Lệnh trả về, dịch vụ hiện là thất bại, và không có gì giống một lời giải thích đến được terminal. Sự im lặng đó là triệu chứng mà người ta mô tả là «OpenVPN không khởi động», và nó gần như không bao giờ có nghĩa là chương trình chết mà không nói gì. Nó có nghĩa là thông báo đã đi vào một kênh bạn không đọc, hoặc thứ bạn khởi động không phải thứ bạn đã cấu hình. Cả hai trường hợp đều có thể chẩn đoán trong chưa đầy một phút khi bạn ngừng coi tệp cấu hình là nghi phạm.

Bốn nơi hấp thụ đầu ra: journal của unit, plugin sở hữu kết nối, đầu bên kia của đường hầm, và một tệp nhị phân khác với tệp bạn nghĩ đang chạy. Mỗi nơi có cách kiểm tra riêng.

Im lặng nghĩa là bạn không nhìn đúng kênh

Lệnh gọi ở tiền cảnh in ra terminal của bạn. Unit in vào journal, và một unit thất bại có thể thoát trước khi viết bất cứ thứ gì nếu lỗi nằm ở cách nó được khởi động chứ không phải ở điều được nói với nó. Sự khác biệt này quan trọng: không có mục nào trong journal nghĩa là tiến trình chưa bao giờ thực sự chạy, còn một mục rồi sau đó thoát nghĩa là nó đã chạy và từ chối điều gì đó.

systemctl status openvpn-client@office
journalctl -u openvpn-client@office -b --no-pager

Thêm systemctl show -p Result -p ExecMainStatus openvpn-client@office để tách một lần thoát sạch khỏi tín hiệu. Trạng thái 1 với Result=exit-code là quyết định của chương trình; Result=signal hoặc timeout lại chỉ vào môi trường, và không lượng chỉnh sửa cấu hình nào thay đổi được điều đó. Ghi lại cả hai giá trị trước khi khởi động lại bất cứ thứ gì, vì khởi động lại xóa trạng thái tạm thời đã sinh ra chúng.

Tên instance là một phần của đường dẫn

Unit mẫu được đóng gói không nhận đường dẫn tệp. Nó nhận một tên instance, và tên đó được ghép vào một thư mục để tìm tệp cấu hình: office được phân giải thành /etc/openvpn/client/office.conf trong gói Debian và Ubuntu. Một tệp tên là office-v2.conf, được khởi động như @office sẽ không bao giờ được đọc, và unit thoát lặng lẽ vì theo quan điểm của nó không có gì để làm. Thư mục tra cứu khác nhau giữa chế độ client và server, nên cùng một lỗi chỉ sang nơi hoàn toàn khác khi bạn đổi mẫu.

Sự không khớp đó là nguyên nhân phổ biến nhất của thất bại im lặng, và nó vô hình trong tệp cấu hình vì tệp cấu hình vẫn ổn. Liệt kê những gì thực sự tồn tại và so sánh hai tên theo từng ký tự, kể cả bất kỳ phần mở rộng nào mà gói mong đợi.

ls -l /etc/openvpn/client/
systemctl list-units 'openvpn*' --all

Nếu unit đã được bật nhưng không có instance nào được liệt kê, chính việc bật có thể tham chiếu tới một tên đã được đổi sau đó. Bật lại đúng instance thường là đủ, và tệp unit cũ còn sót lại đáng để xóa để nó không làm người tiếp theo bối rối. Một tệp unit bị bỏ quên là chuyện nhỏ nhưng khiến ai đó mất một giờ sau này.

Khi plugin sở hữu đường hầm, terminal không thấy gì

Một kết nối khởi động từ applet màn hình thuộc về NetworkManager, và đầu ra OpenVPN của nó đi vào journal của dịch vụ đó chứ không vào shell nào bạn đang mở. Chạy client bằng tay mà không thấy gì là điều bình thường trong cách sắp xếp đó, vì tiến trình chạy bằng tay không phải là tiến trình mang kết nối.

Tìm trong journal dịch vụ sở hữu nó, sau đó tái tạo việc phân tích với mức độ chi tiết bạn có thể đọc. Hai lệnh dưới đây nhìn vào những chủ sở hữu khác nhau của cùng một thất bại.

journalctl -b -u NetworkManager --no-pager | grep -i -A3 openvpn
openvpn --config /etc/openvpn/client/office.conf --verb 4 --log /tmp/ovpn.log

Lần chạy độc lập là để đọc thông báo, không phải để thay thế kết nối được quản lý, và hai thứ khác nhau sau đó: tích hợp DNS, tuyến đường và thời gian sống thuộc về plugin. Sửa lỗi phân tích trong lần chạy độc lập không tự động sửa phân giải tên khi applet tiếp quản, nên hãy tách hai quan sát ra.

Hai tệp nhị phân, một PATH

Một bản dựng cài thủ công dưới /usr/local thắng khi gọi từ shell, vì /usr/local/sbin đứng trước /usr/sbin trong PATH mặc định của Ubuntu. Unit không dùng PATH của bạn; nó chạy đường dẫn tuyệt đối được ghi trong ExecStart. Vì vậy phiên bản chạy được trong terminal và phiên bản thất bại khi chạy như dịch vụ có thể thực sự là những chương trình khác nhau.

So sánh cả hai trước khi dựng lại bất cứ thứ gì. Lệnh thứ ba là lệnh quyết định.

command -v openvpn
whereis openvpn
systemctl cat openvpn-client@office | grep ExecStart

Một khác biệt môi trường nữa ẩn ở cùng một chỗ. Một unit đóng gói dựa vào thư mục thời gian chạy dưới /run, do systemd tạo cho nó; một unit thay thế viết tay bỏ qua thiết lập đó có thể thất bại trước khi mở một tệp nào, và thất bại trông như một lần từ chối chung mà không có thông báo OpenVPN nào.

Những thất bại client không thể báo cáo

Một số kết quả được quyết định ở đầu xa. Một gateway trả lời bằng trạng thái HTTP và đóng kết nối đã cho bạn biết về trạng thái của chính nó, và bước tiếp theo hữu ích là log của nó hoặc tài khoản đằng sau thông tin xác thực chứ không phải các tệp cục bộ của bạn. Trong tình huống đó không có gì cục bộ bị hỏng, và sửa tệp cấu hình để bù đắp chỉ làm lần chẩn đoán sau khó hơn. Hãy đọc log đó trước khi chạm vào cấu hình client.

Một trường hợp im lặng khác là client hoạt động đúng. Đường hầm ở chế độ client không bao giờ lắng nghe trên một cổng, nên một kiểm tra mong đợi trình lắng nghe mở sẽ không báo gì và trông như thất bại. Xác nhận bạn đã khởi động chế độ nào trước khi kết luận từ danh sách cổng trống.

Xử lý từng lớp theo thứ tự: unit có tồn tại và tên instance có đúng không, có gì đến được journal hay tệp --log, tệp nhị phân và tệp cấu hình nào thực sự đã chạy, và thất bại là cục bộ hay từ xa. Mỗi câu trả lời bỏ đi một lớp. Bắt đầu từ tệp cấu hình nghĩa là viết lại một tệp có thể chưa bao giờ được mở.

Bài viết liên quan