Ping tới 192.0.2.10 chỉ cho bạn biết một địa chỉ đã trả lời một gói ICMP echo, và không hơn thế. Trên mạng không có đường hầm, nó vẫn có thể thành công vì địa chỉ đó có thể nằm trong mạng con cục bộ; với một đường hầm khỏe mạnh, nó có thể thất bại vì máy chủ bỏ ICMP trong khi phục vụ HTTPS. Kiểm tra mà script của bạn cần là một truy vấn trạng thái nền tảng cộng với một bài kiểm tra tuyến đường tới đích mà ứng dụng sử dụng. Hãy coi chúng là hai trường riêng biệt, không bao giờ là một boolean duy nhất.

Một phản hồi echo thực sự chứng minh điều gì

ICMP là một giao thức về khả năng tiếp cận, không có khái niệm giao diện hay đường hầm. Khi một phản hồi đến, nhân hệ điều hành báo rằng một máy chủ đã trả lời; nó không báo tuyến nào đã mang yêu cầu đi hay tuyến nào mang phản hồi về. Lọc gói còn làm tín hiệu nhiễu hơn, vì một tường lửa chặn yêu cầu echo không nói gì về các cổng phía sau nó. Và một hồ sơ đường hầm chia tách có thể cố ý loại trừ địa chỉ được kiểm tra trong khi mọi đích khác vẫn hoạt động.

Điều bạn thực sự muốn biết là liệu một dịch vụ cụ thể có dùng được trên con đường mà ứng dụng đi hay không. Chọn máy chủ và cổng mà ứng dụng gọi, rồi yêu cầu một phản hồi ở tầng ứng dụng.

Khả năng tiếp cận và trạng thái đường hầm là hai sự thật khác nhau, và cái này có thể đúng trong khi cái kia sai. Giữ chúng tách rời cho bạn biết lỗi thuộc về ai. Gộp chúng thành một lần kiểm tra tạo ra một phiếu mà không ai có thể định tuyến.

Hỏi Android về phương thức vận chuyển, không phải về ping

Android trả lời trực tiếp câu hỏi về trạng thái thông qua ConnectivityManager. Khả năng của mạng đang hoạt động mang một cờ vận chuyển VPN, được đặt khi lưu lượng được định tuyến qua một giao diện VPN. Lệnh gọi này là cục bộ, rẻ và độc lập với việc có máy chủ từ xa nào trả lời hay không.

Phiên bản Java này trả về false thay vì ném ngoại lệ khi không có mạng đang hoạt động. Vì nó đọc mạng đang hoạt động, nó phản ánh hồ sơ mà người dùng đã chọn trong Cài đặt.

ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);

Đối với thông báo thay đổi, hãy đăng ký một NetworkCallback thay vì thăm dò bằng bộ hẹn giờ. Đừng nhầm với VpnService.prepare, thứ chỉ báo cáo việc người dùng đã cấp quyền cho VPN hay chưa, không phải các gói có đang chảy hay không. Việc thu hồi đến qua VpnService.onRevoke, nhưng quên một hồ sơ trong Cài đặt không tạo ra bất kỳ quảng bá nào.

iOS: tên giao diện là một suy đoán, không phải hợp đồng

Nhiều đoạn mã iOS kiểm tra cài đặt proxy, tìm từ điển __SCOPED__ và tìm các khóa giao diện như tap, tun, utun2, ppp hoặc ipsec. Cách đó là một quy ước đặt tên, không phải bảo đảm được ghi thành tài liệu, nên một bản cập nhật hệ điều hành đổi tên giao diện có thể làm hỏng nó. Nó cũng có xu hướng báo true cho các mục cũ tồn tại lâu hơn đường hầm.

Khi ứng dụng của bạn sở hữu cấu hình, NEVPNManager cho một trạng thái thật. Nó mô tả đường hầm mà ứng dụng của bạn đã khởi động; với VPN theo từng ứng dụng, các ứng dụng khác có thể nằm hoàn toàn ngoài đường hầm đó.

Tải lại tùy chọn trước khi đọc trạng thái, vì giá trị thay đổi khi đường hầm lên và xuống:

let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
    let up = manager.connection.status == .connected
    print(up)
}

Cờ trạng thái của nền tảng vẫn không chứng minh lưu lượng tới được máy ngang hàng. Chính khoảng trống đó là thứ bài kiểm tra tuyến đường bao phủ, và đó là lý do một boolean không đủ cho việc hỗ trợ.

Hồ sơ Windows phơi bày một trường trạng thái thật

Windows theo dõi hồ sơ VPN tách biệt với bộ điều hợp, và Get-VpnConnection phơi bày ConnectionStatus cho mỗi hồ sơ mà nó biết. Các hồ sơ được tạo qua ứng dụng khách Windows hoặc gói cung cấp xuất hiện ở đây. Lệnh này không phải là một máy dò đường hầm tổng quát.

Đọc trường cho một hồ sơ có tên, thêm -AllUserConnection khi hồ sơ thuộc về tất cả người dùng:

Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress

Các ứng dụng khách bên thứ ba thường vô hình với lệnh này ngay cả khi đường hầm của họ đang hoạt động, nên kết quả rỗng nghĩa là không rõ, không phải đã ngắt. Danh sách bộ điều hợp cũng gây hiểu nhầm tương tự: bộ điều hợp của nhà cung cấp có thể tồn tại trong khi rảnh, và một số bộ điều hợp chỉ tồn tại trong một phiên. Với hồ sơ do Windows sở hữu, rasdial báo một mã thoát mà bạn có thể phân nhánh. Tất cả những điều này mô tả niềm tin cục bộ, không phải khả năng tiếp cận máy ngang hàng.

Trạng thái cộng tuyến đường: kiểm tra hai phần

Một hồ sơ đã kết nối không nói gì về việc các gói đi đâu. Đường hầm chia tách có thể giữ đường hầm hoạt động trong khi loại trừ đích mà bạn quan tâm. Hồ sơ always-on vẫn kết nối với một máy chủ đã chết, và kill switch cố ý chặn lưu lượng khi đường hầm sụp.

Hãy kiểm tra cả hai lớp: xác nhận một phương thức vận chuyển VPN hoặc hồ sơ đang hoạt động, rồi xác nhận đích được phân giải và trả lời theo tuyến đó. Trên Linux, hãy hỏi nhân hệ điều hành nó sẽ dùng giao diện nào:

ip route get 192.0.2.10
resolvectl query intranet.example.test

Khi ứng dụng khách nằm ngoài tầm kiểm soát của bạn, hãy ghi lại cả hai kết quả và để mẫu hình chỉ ra lớp. Đã kết nối cộng một bài kiểm tra tuyến đường thất bại gợi ý đường hầm chia tách, DNS hoặc chính sách. Đã ngắt kết nối cộng một bài kiểm tra tuyến đường thành công nghĩa là một con đường khác đang mang lưu lượng.

Một bài kiểm tra bạn có thể chạy theo thứ tự

Ghi lại trạng thái nền tảng trước, trước khi bạn thay đổi bất kỳ trạng thái mạng nào. Phân giải tên máy chủ và ghi chú họ địa chỉ, vì bản ghi AAAA có thể đi theo tuyến khác với bản ghi A. Mở cổng dịch vụ và yêu cầu một phản hồi ứng dụng thay vì chỉ một cái bắt tay. Giữ mỗi quan sát trong trường nhật ký riêng của nó.

Trên một máy Linux có dig và curl, ba lệnh bao phủ phân giải, tuyến đường và chính dịch vụ. Chạy chúng khi đường hầm lên và lại khi đường hầm xuống:

dig +short intranet.example.test
ip route get 198.51.100.20
curl -sS -o /dev/null -w "%{http_code}" --max-time 8 https://intranet.example.test/health

Bốn trường riêng biệt thắng một boolean, vì trạng thái, DNS, tuyến đường và chính sách hỏng độc lập và rơi vào các nhóm khác nhau. Ping trong terminal vẫn là một kiểm tra thủ công tốt. Nó là một định nghĩa kém về kết nối cho tự động hóa, nơi API của nền tảng và một bài kiểm tra tuyến đường trả lời câu hỏi thực sự.

Bài viết liên quan