Những hook chạy không lỗi mà vẫn báo thiếu tệp thường đang nhìn sai chỗ, chứ không phải thất bại trong nhiệm vụ của mình. Đường dẫn tương đối trong một script được phân giải theo thư mục làm việc của tiến trình, và một dịch vụ khởi động với thư mục làm việc mà bạn không chọn. Tệp cạnh script và tệp mà tiến trình mở chỉ là một khi có thứ gì đó neo chúng lại. Khoảng cách đó giải thích phần lớn các lỗi hook bị đọc nhầm thành vấn đề quyền.

Hãy kiểm tra đường dẫn trước khi kiểm tra quyền, vì lỗi quyền trên tệp sai vẫn là tệp sai.

Đường dẫn tương đối được phân giải theo tiến trình, không theo tệp

Khi một script gọi open("policy.json"), hạt nhân phân giải tên đó theo thư mục làm việc hiện tại của tiến trình. Không có gì từ vị trí của chính script tham gia vào lần tìm kiếm đó. OpenVPN khởi động hook từ một thư mục do nó tự chọn, và tùy chọn cd có thể thay đổi thư mục đó, nên một script được thử bằng tay từ thư mục của chính nó sẽ hành xử khác khi daemon chạy nó. Bài thử thủ công qua, lần chạy dịch vụ hỏng, và dòng nhật ký chỉ nhắc đến cái tên bị thiếu.

Python phơi bày vị trí của script dưới dạng __file__, và chính điều đó khiến việc neo trở nên khả thi. Path(__file__).resolve().parent / "policy.json" dựng đường dẫn từ tệp thay vì từ tiến trình. Một dòng đó loại bỏ sự phụ thuộc vào thư mục làm việc mà không thay đổi gì về đặc quyền.

Hãy neo đường dẫn một cách có chủ đích, rồi kiểm tra resolve làm gì

resolve() đi theo các liên kết tượng trưng, nên một bản cài đặt liên kết hook vào chỗ của nó sẽ neo tại đích của liên kết, không phải tại thư mục chứa liên kết. Đó thường là điều bạn muốn cho một triển khai có phiên bản, và là sai cho một bố cục mong đợi dữ liệu nằm cạnh liên kết tượng trưng. Hãy quyết định triển khai muốn nói gì, và viết mã cho khớp thay vì phát hiện khác biệt trên môi trường thật. Path(__file__).parent mà không có resolve() giữ lại thư mục riêng của liên kết.

Nếu dữ liệu thuộc về phiên bản chạy chứ không thuộc chương trình, hãy lấy đường dẫn tuyệt đối từ cấu hình. Mã hóa cứng một vị trí gắn hook vào một bố cục máy chủ duy nhất.

Đi qua bốn ranh giới theo thứ tự

Bắt đầu từ thư mục làm việc: so sánh WorkingDirectory, tùy chọn cd của OpenVPN và mọi lớp bọc đổi thư mục trước exec. Sau đó xác nhận vị trí đã phân giải, vì một tệp cùng tên gần giống trong triển khai khác có thể trả lời lần tìm kiếm và che mất lỗi. Tiếp theo là góc nhìn hệ thống tệp: chroot hoặc không gian tên gắn kết của dịch vụ có thể làm một đường dẫn tuyệt đối của máy chủ đơn giản là không tồn tại. Cuối cùng là danh tính truy cập, một câu hỏi tách khỏi khả năng nhìn thấy.

ProtectHome và PrivateTmp giấu những vị trí khác nhau, và cả hai đều không xuất hiện trong một danh sách thư mục lấy từ máy chủ. Một đường dẫn tồn tại với root trong một shell có thể vô hình bên trong không gian tên của đơn vị, và đó là lý do việc thử cùng lệnh bên ngoài dịch vụ chứng minh được rất ít.

Sửa lần tìm kiếm mà không mở rộng dịch vụ

Neo đường dẫn chỉ giải quyết ranh giới đầu tiên. Nó không phơi ra một thư mục mà dịch vụ giấu, và nó không cấp cho một tài khoản không đặc quyền quyền truy cập tệp chỉ dành cho root. Nâng script-security thay đổi những script mà OpenVPN sẽ chạy; nó không ảnh hưởng đến nơi một tên tương đối được phân giải. Đổi thư mục làm việc cho toàn bộ dịch vụ rộng hơn vấn đề, vì mọi đường dẫn tương đối khác của chứng chỉ, nhật ký hay trợ giúp đều di chuyển theo.

Ưu tiên cách sửa hẹp: một đường dẫn tất định trong script, một giá trị cấu hình rõ ràng cho dữ liệu của phiên bản chạy, và quyền sở hữu tệp khớp với tài khoản mà hook thực sự chạy dưới đó.

Ghi lại bằng chứng nêu tên ranh giới

Một báo cáo sự cố hữu ích chứa ba thứ: đường dẫn chính xác mà hook đã thử, môi trường đã tạo ra nó, và ranh giới nào đã từ chối. In đường dẫn đã phân giải và ngoại lệ mà không đổ nội dung tệp ra. Bộ ba đó tách một neo sai khỏi một lần gắn kết ẩn và khỏi một lần từ chối quyền, vốn là ba cách sửa khác nhau.

Khẳng định rằng root có thể đọc tệp từ một terminal chỉ trả lời một trong những câu hỏi đó và không trả lời câu nào khác. Thay vào đó hãy thử từ chính bối cảnh của dịch vụ.

Bài viết liên quan