Đừng chồng gia cố systemd lên bước chuyển user của OpenVPN
Hai công thức đặc quyền tối thiểu ghép lại không thành một công thức chặt hơn. Chọn ai thực hiện việc chuyển danh tính, rồi ánh xạ quyền hạn trên toàn bộ vòng đời.
Hai công thức đặc quyền tối thiểu dán chồng lên nhau không tạo ra một triển khai chặt chẽ hơn. Một mô hình cho phép daemon khởi động với đặc quyền rồi hạ xuống tài khoản không đặc quyền sau khi khởi tạo; mô hình kia để trình quản lý dịch vụ chạy nó dưới một danh tính bị hạn chế ngay từ chỉ thị đầu tiên. Mỗi mô hình tự nó hoạt động, và sự kết hợp thường tạo ra một dịch vụ không làm sạch được cả hai việc. Phần còn lại đi qua quyết định theo thứ tự.
Hai mô hình, một chủ sở hữu của việc chuyển
Mô hình thứ nhất thuộc về daemon. Các tùy chọn OpenVPN của bản cộng đồng user và group đổi danh tính sau khi đường hầm và khóa được thiết lập, còn persist-key cùng với persist-tun giữ những tài nguyên đó dùng được về sau.
Mô hình thứ hai thuộc về trình quản lý dịch vụ. Một thiết lập systemd User= hoặc Group= quyết định danh tính mà tiến trình khởi động dưới đó, và các chỉ thị năng lực quyết định thứ nó được giữ. Chọn giữa hai mô hình là câu hỏi đóng gói trước khi là câu hỏi bảo mật, và người bảo trì gói đã trả lời câu đó rồi. Việc của bạn là tìm ra câu trả lời ấy chứ không phải phát minh ra lựa chọn thứ ba.
Cả hai đều chính đáng. Sai lầm là coi chúng như các lớp của một thiết kế, vì mô hình thứ hai có thể biến việc chuyển danh tính của mô hình thứ nhất thành một thao tác mà tiến trình không còn được phép làm.
Quyết định nơi danh tính thay đổi
Nếu unit đã khởi động dưới một tài khoản chuyên dụng, việc thêm chỉ thị cho daemon chuyển sang tài khoản khác đòi hỏi một bước chuyển setuid mà một dịch vụ đã được gia cố không bao giờ nên làm. Lỗi hiện ra như lỗi quyền khi khởi động chứ không phải như một thông điệp chính sách rõ ràng. Điều này được đọc như một năng lực bị thiếu, khiến người ta lao về phía một tập giới hạn rộng hơn thay vì về phía câu hỏi danh tính.
Hãy đọc xem gói đã cài thực sự cung cấp gì trước khi sửa bất cứ thứ gì, kể cả thư mục drop-in của nó. Một số unit cố ý bỏ qua bước hạ cấp của chính daemon vì trình quản lý đã xử lý việc đó, và một số khác dựa vào các tùy chọn ấy cho việc chuyển sau khởi tạo. Gỡ bỏ một trong hai mà không biết mình thừa hưởng mô hình nào chính là cách một dịch vụ đang chạy thôi khởi động.
Viết mô hình đã chọn trong một dòng: thuộc trình quản lý hay thuộc daemon. Mọi chỉ thị về sau phải nhất quán với câu đó, và một unit hỗn hợp nên bị coi là lỗi chứ không phải thỏa hiệp.
Năng lực là giới hạn, không phải ban phát
Một tập giới hạn năng lực nói tiến trình được giữ tối đa những gì. Đó là một mức trần, và việc liệt kê một năng lực ở đó tự nó chẳng cho gì, vì thế một unit có tập giới hạn rộng rãi vẫn có thể không tạo được đường hầm.
Thứ thực sự đưa một năng lực vào tập môi trường của dịch vụ là AmbientCapabilities=. tài liệu tham chiếu thực thi của systemd ghi lại hai chỉ thị riêng rẽ, và chính khác biệt đó giải thích phần lớn những lời khuyên mơ hồ về năng lực trên mạng.
Chỉ thêm năng lực sau khi thao tác đang hỏng đã xác định được nó. Một tập giới hạn rộng hơn che giấu nguyên nhân thật và để dịch vụ có nhiều quyền hơn thiết kế dự tính. Nó cũng khiến unit khó xem xét hơn, vì mức trần không còn mô tả công việc nữa. Hãy gỡ năng lực thừa sau khi lỗi thật đã được sửa.
Ánh xạ quyền hạn trên vòng đời
Liệt kê những gì tiến trình phải làm ở từng giai đoạn: khởi động, trạng thái ổn định, xác thực lại và tháo dỡ. Việc tạo giao diện, thay đổi tuyến, đọc khóa được bảo vệ và gọi tiến trình trợ giúp không phải tất cả đều xảy ra cùng lúc hay dưới cùng yêu cầu. Sắp xếp danh sách theo giai đoạn trước khi sắp xếp theo năng lực.
Các tùy chọn duy trì giữ tài nguyên qua các lần đàm phán lại, và chúng không cấp những quyền chưa từng có. Một khóa mà tiến trình không đọc được khi khởi động sẽ vẫn không đọc được về sau, bất kể cờ duy trì nói gì. Các cờ giữ lại thứ đã hoạt động.
Dùng tài khoản chuyên dụng thay vì tài khoản dùng chung. Các nhà phát triển OpenVPN cảnh báo về thói quen dùng nobody làm ví dụ chung, vì các dịch vụ khác trên máy chủ có thể đã chạy dưới tài khoản đó và sự cô lập bạn tưởng có không hề ở đó.
Các tính năng làm thay đổi tải cục bộ, như giảm tải kênh dữ liệu hay một bản dựng liên kết khác đi, có thể làm dịch chuyển những thao tác cần thiết. Hãy xem lại bản đồ khi gói thay đổi, không chỉ khi có thứ gì hỏng.
Viết kế hoạch ra và giữ quyền truy cập khôi phục
Bản ghi triển khai nên nêu tên trình quản lý, danh tính khởi động, danh tính ổn định dự kiến và từng khoản cấp cùng thao tác cần đến nó. Chính bản ghi đó khiến thay đổi tiếp theo có thể xem xét thay vì thử nghiệm.
Giữ quyền truy cập bảng điều khiển trong lúc sửa, vì một unit hỏng khi khởi động rất khó sửa từ xa. Hãy thử khởi động lại và khởi động lại hoàn toàn trước khi tuyên bố thay đổi hoàn tất. Một unit sống sót qua lần khởi động lại vẫn có thể hỏng trước khi mạng lên.
Thành công là một vòng đời quyền hạn tối thiểu được hiểu rõ, không phải một tiến trình tình cờ chạy dưới một cái tên không phải root.