openconnect bị giết: các tuyến và DNS vẫn trỏ vào đường hầm
Một tiến trình openconnect đã chết có thể để lại tuyến và mục resolver đã cài. Đi theo đường tắt, gửi tín hiệu mà bản dựng của bạn ghi lại, và dọn dẹp.
Đường hầm đã tắt, nhưng máy vẫn hành xử như thể nó đang bật: một truy vấn treo cho đến khi hết thời gian chờ, và một tuyến trỏ vào giao diện không còn tồn tại. Đó là dấu hiệu của một tiến trình openconnect chết mà không chạy trình trợ giúp ngắt kết nối của nó. Trạng thái mạng mà nó tạo ra vẫn được cài đặt, và không gì khác trên hệ thống biết cách xóa nó.
Đi qua máy theo thứ tự trạng thái được tạo: tiến trình, liên kết, tuyến, resolver. Mỗi bước cho bạn biết máy khách đã thực sự biến mất hay chỉ tách khỏi thiết bị đầu cuối của bạn, và sự khác biệt đó quyết định có cần sửa gì không.
Bắt đầu từ tiến trình, không phải cấu hình
Mở thiết bị đầu cuối và hỏi còn gì đang chạy trước khi chạm vào một tuyến. pgrep -a openconnect liệt kê từng phiên bản với các đối số của nó, cho thấy tệp pid và tập lệnh đã được cấp. Một tiến trình bạn không ngờ tới giải thích đường hầm ma nhanh hơn bất kỳ nhật ký nào.
Nếu không có gì chạy, hãy xem liên kết. ip link show tun0 cho biết giao diện có sống sót không, và ip route show dev tun0 liệt kê các tuyến vẫn gắn với nó. Sau đó kiểm tra resolver bằng resolvectl status. Ghi lại cả ba đầu ra trước khi thay đổi, vì chính bản ghi đó là cách sau này bạn phân biệt một mục cũ với một mục mới.
Một giao diện biến mất thường mang theo các tuyến của nó. Các tuyến sống sót sau liên kết thường có nghĩa là tiến trình vẫn còn sống hoặc một máy khách thứ hai sở hữu thiết bị.
Chính tập lệnh trợ giúp mới hoàn tác các thay đổi
openconnect không tự xóa giao diện, các tuyến hay mục resolver. Nó gọi một trình trợ giúp bên ngoài, /etc/vpnc/vpnc-script trong một bản dựng upstream và /usr/share/vpnc-scripts/vpnc-script trong các gói Debian và Ubuntu, được chọn bằng -s. Cùng một tập lệnh dựng đường hầm cũng là tập lệnh tháo nó.
Nếu tiến trình thoát mà không gọi trình trợ giúp đó, trạng thái vẫn còn. hướng dẫn OpenConnect nói rõ rằng định tuyến và dịch vụ tên sẽ không hoạt động đúng nếu không có tập lệnh, và mô tả trình trợ giúp là thành phần tháo trạng thái giao diện khi thoát. Đó là lý do đường dẫn quan trọng khi bạn khởi chạy máy khách bằng -s.
Tín hiệu nào đến đường dẫn đó đã thay đổi giữa các phiên bản. Hướng dẫn 7.06 coi SIGTERM là thoát ngay lập tức, bỏ qua tập lệnh. Các bản dựng hiện tại ghi lại INT và TERM là dừng sạch, khi phiên được đăng xuất và trình trợ giúp chạy. Hãy đọc phần SIGNALS của tệp nhị phân bạn thực sự có thay vì giả định một trong hai hành vi.
man openconnect | sed -n '/^SIGNALS/,/^LIMITATIONS/p'
Gửi tín hiệu mà bản dựng của bạn ghi lại
Khi biết tín hiệu, hãy dừng tiến trình theo pid chứ không theo mẫu.
pgrep -a openconnect
sudo kill -INT "$(cat /var/run/openconnect.pid)"
Sau đó lặp lại ba kiểm tra từ phần đầu thay vì tin vào trạng thái thoát. ip link show tun0 nên thất bại, ip route show dev tun0 không nên in gì, và resolvectl status không nên liệt kê liên kết VPN nữa.
SIGHUP không phải nút dừng: nó ngắt kết nối, chạy tập lệnh và để phiên có thể tiếp tục bằng --cookie. SIGUSR2 buộc kết nối lại ngay lập tức. SIGKILL bỏ qua hoàn toàn việc dọn dẹp, và đó chính là trạng thái mà bài viết này nói tới.
Sửa resolver mà không thay thế resolv.conf
Trên hầu hết các hệ thống Ubuntu /etc/resolv.conf là một liên kết tượng trưng vào systemd-resolved, không phải tệp bạn nên chỉnh sửa. Việc thay thế nó phá vỡ phân giải tên cho mọi mạng, không chỉ VPN. Thay vào đó, hãy xóa đăng ký của đường hầm:
resolvectl revert tun0
resolvectl query example.com
Nếu hệ thống dùng resolvconf thay vì systemd-resolved, bản ghi theo từng giao diện vẫn tồn tại cho đến khi nó được bảo buông liên kết, và resolvconf -d tun0 là hành động tương đương. Kiểm tra resolver nào đang được dùng trước khi chọn lệnh.
Một truy vấn vẫn nhắm tới máy chủ sau liên kết đã chết sẽ treo cho đến khi hết thời gian chờ, và độ trễ đó trông giống máy chủ DNS hỏng hơn là một tuyến còn sót.
Hãy làm lần ngắt kết nối tiếp theo trở nên nhàm chán
Giữ nguyên đường dẫn tệp pid khi khởi động và tắt bằng cách truyền --pid-file mỗi lần, hoặc chạy openconnect dưới một unit mà KillSignal khớp với tín hiệu mà phiên bản của bạn ghi lại. Thử trước ở tiền cảnh cho bạn thấy các thông báo tắt mà trình trợ giúp in ra.
Kết nối, ngắt kết nối và chạy ba kiểm tra một lần. Một lần thoát sạch không để lại liên kết VPN, tuyến VPN hay mục resolver VPN. Nếu một trong ba còn sống, giờ bạn biết thành phần nào đã không dọn dẹp. Cuộc điều tra tiếp theo sẽ bắt đầu từ câu trả lời đó chứ không phải từ một truy vấn treo.