Một daemon VPN cần các thao tác mạng đặc quyền dù các ứng dụng thông thường mở ổ cắm ra ngoài mà không cần bất kỳ đặc quyền nào. Chính trong khoảng trống đó, phần lớn lỗi về khả năng bắt đầu: ai đó thấy lỗi quyền, cấp toàn bộ tập hợp, và dịch vụ chạy vì những lý do mà sau này không ai giải thích được. Phần hướng dẫn dưới đây bắt đầu từ thao tác đã thất bại, gán nó cho một quyền duy nhất, rồi kiểm tra bối cảnh mà tiến trình thực sự chạy trong đó. Chạy như root không giới hạn là câu trả lời hợp lệ cho một số triển khai, nhưng đó nên là quyết định chứ không phải mặc định.

Bắt đầu từ thao tác đã thất bại

Hãy đọc lỗi trước khi đọc hướng dẫn. «Thao tác không được phép» khi thay đổi giao diện, việc từ chối mở nút thiết bị và lỗi bind trên cổng thấp là ba vấn đề khác nhau với ba quyền khác nhau. Nếu tiến trình khởi động và chỉ thất bại ở lần đổi tuyến đầu tiên, điều đó cũng cho biết việc tạo giao diện đã thành công, giúp thu hẹp câu trả lời đáng kể.

Tái hiện lỗi khi dịch vụ đã dừng, rồi khởi động nó ở tiền cảnh dưới cùng người dùng nếu bản triển khai cho phép. Một lỗi bạn nhìn thấy tốt hơn một dòng nhật ký phải đoán, và nó làm rõ sự khác biệt giữa vấn đề khả năng và sự từ chối của SELinux hay AppArmor.

Gán mỗi thao tác cho một quyền

Bảng này là bản đồ khởi đầu, không thay thế tài liệu của bản triển khai:

OperationUsual authorityWatch for
Create or configure tun/tapCAP_NET_ADMIN in the relevant namespaceCreating the device and opening it are separate steps
Add routes, rules, firewall entriesCAP_NET_ADMINSame capability, different namespace than you think
Open /dev/net/tunDevice permissions, not a capabilityGroup membership or a udev rule may be enough
Raw socketsCAP_NET_RAWNeeded by some user-space tunnel implementations
Bind a port below 1024CAP_NET_BIND_SERVICEIrrelevant for most modern tunnel ports

Hai hàng trong bảng đó là những hàng người ta hay nhầm lẫn. Mở /dev/net/tun là câu hỏi về quyền tệp; yêu cầu hạt nhân cấu hình thứ bạn đã mở là câu hỏi về khả năng. Cấp CAP_NET_ADMIN không sửa được nút thiết bị mà người dùng dịch vụ của bạn không đọc được, và sửa nút đó không cho bạn quyền về tuyến đường. Hãy kiểm tra cả hai trước khi thay đổi bất kỳ điều nào.

WireGuard trong hạt nhân và các chương trình đường hầm trong không gian người dùng cũng không có yêu cầu giống nhau. Đường đi của mô-đun hạt nhân cấu hình giao diện sẵn có qua netlink, trong khi bản triển khai trong không gian người dùng cũng có thể cần thiết bị và, với một số phương thức truyền, cần ổ cắm thô.

Đọc bối cảnh: dịch vụ, vùng chứa hay shell

Một khả năng trong không gian tên mạng của máy chủ có thể ảnh hưởng nhiều hơn hẳn so với cùng thao tác bên trong một ngăn xếp được cô lập có chủ đích. Môi trường chạy vùng chứa thường bắt đầu với tập giới hạn đã thu gọn; thêm NET_ADMIN vào một vùng chứa chia sẻ mạng của máy chủ là quyền lớn hơn nhiều so với thêm vào vùng chứa có không gian tên mạng riêng và không có mount từ máy chủ.

Với các unit systemd, hãy đọc thứ thực sự được áp dụng chứ không phải thứ tệp unit có vẻ nói: systemctl show -p CapabilityBoundingSet -p AmbientCapabilities báo cáo các giá trị hiệu lực, có thể do một drop-in bạn đã quên đặt. Hãy hỏi giá trị hiệu lực, không bao giờ hỏi giá trị dự định. Khả năng ambient quan trọng vì một dịch vụ không phải root mất khả năng qua exec mà không có chúng.

Lấy cấu hình được hỗ trợ của gói hoặc ảnh làm cơ sở. Đừng thêm quyền ổ cắm thô hay chế độ đặc quyền chỉ vì một hướng dẫn khác đã liệt kê chúng cho một công cụ khác; lập luận đó không chuyển giao gì và khiến bạn mất đi sự cô lập mà bạn đã trả tiền. Khi nghi ngờ, đừng cấp gì và hãy đọc ghi chú của bản triển khai cho thao tác chính xác bạn cần.

Quan sát điều gì xảy ra sau khi đặc quyền giảm

Nhiều daemon khởi động với đặc quyền, cấu hình giao diện, rồi chuyển sang người dùng không đặc quyền và giữ đường hầm. Từ thời điểm đó tiến trình không còn thêm được tuyến đường, viết lại quy tắc tường lửa hay mở thiết bị đặc quyền mới, điều này ổn cho tới khi một lần kết nối lại cần đúng thứ đó. Các lần đọc tệp và chạy hook về sau có thể thất bại vì cùng lý do.

Hãy kiểm tra toàn bộ vòng đời chứ không chỉ giây đầu tiên: khởi động, gia hạn hoặc kết nối lại, và dọn dẹp khi dừng. Việc tạo giao diện thành công lần đầu không chứng minh mọi thao tác đặc quyền về sau vẫn hoạt động, và lỗi thường xuất hiện hàng giờ sau đó trên môi trường thật.

Các bản triển khai giữ đường hầm mở qua lần đổi người dùng thường kết hợp điều đó với tùy chọn duy trì đường hầm và khóa. Về phía systemd, câu hỏi tương đương là tập khả năng của unit có sống sót qua lần đổi người dùng bạn đã cấu hình hay không.

Ghi lại quyền đã cấp và lý do của nó

Ghi lại quyền chính xác, thao tác mà nó cho phép và lỗi mà nó đã sửa. Một dòng trong ghi chú triển khai — «CAP_NET_ADMIN trong không gian tên mạng của unit, cần cho các thay đổi tuyến đường sau khi kết nối lại» — là đủ để ngăn người tiếp theo mở rộng quyền lần nữa.

Sau đó hãy đọc lại tập hiệu lực sau mỗi lần nâng cấp. Nhà cung cấp thêm tính năng, ảnh thay đổi giá trị mặc định, và một khả năng không cần thiết năm ngoái có thể trở thành trụ cột mà không ai nhận ra.

Bài viết liên quan