Container LXD không mở được /dev/net/tun? Kiểm tra mục unix-char
LXD phải chuyển thiết bị TUN của máy chủ vào container trước khi một ứng dụng khách VPN có thể dùng nó. Xem unix-char thêm gì, không thêm gì, và cách kiểm chứng.
LXD đưa một thiết bị ký tự của máy chủ vào container bằng cách thêm một nút thiết bị, không phải bằng cách dạy khách tự tạo một nút. Nếu container không có /dev/net/tun, máy chủ có thể có thiết bị mà khách vẫn không mở được. Mục unix-char là nửa phía người quản lý của con đường đó, và nó cố ý hẹp hơn một container đặc quyền. Vì thế nút trên máy chủ và nút trong container đáng được kiểm riêng.
Cơ chế đủ ngắn để theo dõi: LXD phân giải một đường dẫn máy chủ, tạo nút tương ứng bên trong phiên bản và thêm thiết bị vào cgroup thiết bị của container. Sau đó tiến trình khách cần quyền và năng lực của chính nó để dùng nút cho bất cứ việc gì.
Mục unix-char thực sự thay đổi điều gì
Một thiết bị unix-char bảo LXD đưa một thiết bị ký tự của máy chủ ra ở một đường dẫn đã chọn bên trong container. Mục này có ba phần quan trọng: nhãn thiết bị mà người quản lý dùng, đường dẫn source trên máy chủ và path mà khách nhìn thấy. Chỉ hai phần sau mô tả chính thiết bị. Một lỗi gõ ở một trong hai sẽ tạo nút ở nơi mà ứng dụng khách không bao giờ mở.
Trên máy chủ, thiết bị thường là /dev/net/tun. Bên trong container bạn có thể giữ nguyên đường dẫn đó hoặc chọn đường dẫn khác, nhưng đường dẫn phải khớp với điều ứng dụng khách VPN mong đợi. Giữ /dev/net/tun tránh được vấn đề cấu hình thứ hai, vì hầu hết ứng dụng khách mở đường dẫn đó mà không hỏi.
Người quản lý áp dụng mục này khi phiên bản khởi động hoặc khi thiết bị được cắm nóng. Nó không sao chép trình điều khiển vào khách và không tạo giao diện đường hầm. Nó làm nút hiển thị và cho phép truy cập qua nhóm kiểm soát thiết bị của container.
Khai báo thiết bị trên phiên bản, không phải bên trong khách
Thêm mục từ bối cảnh quản trị LXD, nêu tên phiên bản và một nhãn bạn sẽ nhận ra sau này. Với container tên vpnbox, lệnh là:
lxc config device add vpnbox tun unix-char source=/dev/net/tun path=/dev/net/tun
lxc config device show vpnbox
Nhãn tun chỉ có giá trị trong cấu hình của phiên bản. Nó không phải tên giao diện và không cần khớp với bất cứ thứ gì trong khách. Nếu một hồ sơ đã cung cấp cùng thiết bị đó, thêm mục thứ hai tạo xung đột chứ không phải dư thừa, nên hãy xem cấu hình hiệu lực trước.
Sửa tệp bên trong container là sai tầng. mknod trong một script khởi động có thể trông như chạy được trên container đặc quyền, rồi biến mất khi tạo lại hoặc thất bại trên container ít đặc quyền hơn. Người quản lý sở hữu bộ thiết bị của phiên bản; hãy để nó sở hữu cả nút.
Khớp quyền sở hữu và chế độ với tiến trình khách
Mục unix-char có thể đặt uid, gid và mode cho nút bên trong container. Dùng chúng để khớp với tài khoản chạy ứng dụng khách VPN, thay vì mở thiết bị cho mọi người dùng hoặc chuyển container sang chế độ đặc quyền.
Hiển thị không giống như được phép. Một nút thuộc root với chế độ 600 thì dịch vụ chạy dưới người dùng không đặc quyền vẫn thấy, nhưng vẫn không mở được. Kiểm tra tài khoản của khách trước, sau đó đặt quyền sở hữu cho tài khoản đó, và giữ chế độ không rộng hơn mức ứng dụng khách cần.
Tiến trình cũng cần khả năng cấu hình giao diện đường hầm, thường là CAP_NET_ADMIN trong không gian tên mạng của container. Chuyển thiết bị không cấp khả năng đó, và cấp khả năng không cung cấp thiết bị; đây là hai yêu cầu độc lập.
Biết mục này không cấp gì
Một nút hiển thị không phải là VPN đang chạy. Gói ứng dụng khách vẫn phải cài, hồ sơ vẫn phải hợp lệ và dịch vụ vẫn phải khởi động. Xác thực, tuyến và DNS vẫn là việc của ứng dụng khách, và lỗi ở đó không phải bằng chứng rằng mục thiết bị sai.
systemd có thể thêm một hạn chế nữa. Một unit có DeviceAllow hoặc chính sách thiết bị được siết chặt có thể từ chối truy cập vào nút do người quản lý container cung cấp. Kiểm tra chính sách thiết bị của unit khi nút tồn tại nhưng dịch vụ báo lỗi quyền, và đổi chính sách đó thay vì mở rộng container.
Cắm nóng là tùy chọn và tường minh. Mục có required=false cần đường dẫn nguồn và có thể xuất hiện hoặc biến mất khi thiết bị máy chủ thay đổi. Vòng đời đó hợp với phần cứng đến rồi đi; với thiết bị TUN mà VPN cần lúc khởi động, một mục tùy chọn có thể khiến dịch vụ khởi động trước khi điều kiện tiên quyết tồn tại.
Kiểm chứng hiển thị, mở và giao diện theo đúng thứ tự đó
Trước hết xác nhận nút bên trong container dự định. Đường dẫn, số chính và số phụ cùng quyền sở hữu phải khớp với thiết bị máy chủ và mục bạn đã thêm. Thiếu nút nghĩa là người quản lý chưa áp dụng mục, hoặc đã áp dụng cho phiên bản khác.
lxc exec vpnbox -- ls -l /dev/net/tun
lxc exec vpnbox -- sh -c 'test -c /dev/net/tun && echo char-device-ok'
Tiếp theo xác nhận tài khoản dịch vụ mở được nó. Một thử nghiệm ngắn dưới tài khoản đó tách vấn đề sở hữu khỏi vấn đề dịch vụ. Cuối cùng, khởi động ứng dụng khách và xác nhận giao diện đường hầm xuất hiện; chỉ bước thứ ba đó chứng minh toàn bộ đường đi, vì hai bước đầu có thể qua trong khi hồ sơ hoặc năng lực của ứng dụng khách vẫn sai.
Ghi lại phiên bản, nhãn thiết bị, nguồn trên máy chủ, đường dẫn trong khách và tài khoản sở hữu khi thay đổi được duyệt. Năm giá trị đó là những gì việc tạo lại, di chuyển hoặc đổi hồ sơ sau này phải giữ, và chúng dễ so sánh hơn nhiều so với một lỗi quyền không có bối cảnh.