Dịch vụ thất bại, nhật ký nhắc đến một spawn và một thư mục, và phản xạ đầu tiên là kiểm tra cấu hình VPN. Chưa có gì trong tệp đó được đọc. systemd thất bại khi chuẩn bị tiến trình, trước khi tệp thực thi chạy, nên không có trình phân tích nào, không có chứng chỉ nào và không có máy chủ từ xa nào được hỏi tới. Đọc mã trạng thái như một phát biểu về systemd thay vì về OpenVPN là điều biến việc này thành một cuộc điều tra ngắn.

Đọc mã trạng thái trước ứng dụng

Mã số sau tên dịch vụ gọi tên giai đoạn đã thất bại. Lỗi thư mục được báo cáo dưới dạng trạng thái CHDIR, trong khi một tệp thực thi không chạy được là một mã hoàn toàn khác. Hai thứ trông giống nhau trong một dòng tóm tắt và không có điểm chung nào về nguyên nhân.

Sự phân biệt đó quan trọng vì các cách sửa nằm ở các tệp khác nhau. Lỗi CHDIR liên quan đến một đường dẫn và cách dịch vụ nhìn nó. Lỗi exec liên quan đến tệp nhị phân, trình thông dịch của nó hoặc một mount không liên quan. Thay đổi remote VPN, danh sách mật mã hoặc đường dẫn chứng chỉ không thể giải quyết cả hai.

Xác nhận rằng lỗi xảy ra lúc khởi động chứ không phải sau một lần chạy thành công. Nếu dịch vụ hoạt động hôm qua và giờ thất bại ở cùng giai đoạn, thì có gì đó đã thay đổi ở thư mục, quyền của nó hoặc chính unit, và thay đổi đó là bằng chứng cần tìm.

Hỏi unit xem nó muốn ở đâu

Đọc unit hiệu lực thay vì tệp mà bạn cho là đã cài đặt, vì các drop-in có thể ghi đè thư mục làm việc mà bạn chưa bao giờ sửa unit chính. Kết quả của show trả lời câu hỏi trực tiếp:

systemctl cat [email protected]
systemctl show [email protected] -p WorkingDirectory -p RootDirectory -p User -p ProtectHome
journalctl -u [email protected] -b --no-pager | tail -30

Với mẫu máy chủ upstream, thư mục làm việc là thư mục cấu hình máy chủ và tên phiên bản chọn hồ sơ bên trong nó. Một phiên bản tên branch do đó chờ tệp riêng của nó trong cùng thư mục, và một hồ sơ đặt ở nơi khác hoàn toàn không thỏa mãn yêu cầu về thư mục làm việc.

So sánh điều unit yêu cầu với điều đang tồn tại. Một đường dẫn từng tồn tại, một liên kết tượng trưng giờ trỏ nơi khác hoặc một tên phiên bản không còn khớp với thư mục đều là những thay đổi bình thường tạo ra đúng lỗi này.

Kiểm tra đường dẫn như dịch vụ nhìn thấy

Shell của bạn và dịch vụ không chia sẻ cùng một góc nhìn hệ thống tệp. Một thư mục gốc hoặc ảnh gốc được cấu hình thay đổi ý nghĩa của đường dẫn tuyệt đối bên trong unit, và một đường dẫn rõ ràng có trên máy chủ có thể vắng mặt trong không gian tên đó. Đọc cài đặt của unit trước khi tin vào một thử nghiệm thủ công.

Quyền làm vấn đề nặng thêm. Dịch vụ chạy dưới một người dùng cụ thể, và người dùng đó phải đi qua được mọi thư mục cha để tới đích, không chỉ đọc bản thân đích. Một thư mục đọc được bởi root nhưng không đi qua được bởi người dùng dịch vụ tạo ra lỗi trông như đường dẫn bị thiếu.

namei -l /etc/openvpn/server
systemctl show [email protected] -p ProtectSystem -p ReadOnlyPaths

Các cài đặt tăng cứng cũng là một phần của bức tranh này. Một unit ẩn các thư mục nhà hoặc biến một phần hệ thống tệp thành chỉ đọc đang làm đúng điều nó được cấu hình để làm, và thư mục làm việc phải nằm ở nơi sandbox vẫn để lộ nó.

Sửa chủ sở hữu, rồi chờ một lỗi khác

Sửa bố cục hoặc unit thông qua người sở hữu cấu hình đó. Di chuyển một hồ sơ vào thư mục mong đợi là một cách sửa chính đáng khi bố cục sai, nhưng nó không giải thích một thư mục không thể vào được, nên đừng coi đó là câu trả lời chung.

Đừng chọn lối tắt nới rộng quyền trên cây cấu hình hoặc gỡ bỏ sandbox. Cả hai làm triệu chứng biến mất trong khi gỡ bỏ những lớp bảo vệ được đặt ở đó có chủ đích, và lần hỏng tiếp theo sẽ khó diễn giải hơn.

Khởi động lại phiên bản và đọc sự kiện tiếp theo thay vì cho rằng đã thành công. Lỗi tiếp theo có khả năng là OpenVPN không mở được tệp cấu hình của nó, đó là tiến bộ: đã vào được thư mục làm việc và trình phân tích đang chạy. Từ đó hãy theo ánh xạ tệp thực tế của unit thay vì quay lại xử lý sự cố mạng.

Tài liệu tham chiếu thực thi của systemd định nghĩa cách thư mục làm việc được diễn giải cùng với các thư mục gốc và sandbox. Mẫu cần nhớ rất đơn giản: mỗi mã trạng thái gọi tên một giai đoạn khác nhau, và chỉ lỗi của chính ứng dụng mới mô tả ứng dụng.

Bài viết liên quan