Как да проверим състоянието на VPN без ping в Android, iOS и Windows
Ping доказва само, че един хост е отговорил, а не че тунелът работи. Питайте API за състояние в Android, iOS и Windows и после проверете маршрута, който приложението ви наистина използва.
Пингването на 192.0.2.10 ви казва, че един адрес е отговорил на ICMP ехо, и това е всичко. В мрежа без тунел то може да успее, защото адресът може да е в локалната подмрежа; при здрав тунел може да се провали, защото сървърът изхвърля ICMP, докато обслужва HTTPS. Проверката, която скриптът ви наистина иска, е заявка за състоянието на платформата плюс тест на маршрута до дестинацията, която приложението използва. Третирайте ги като две отделни полета, никога като един boolean.
Какво всъщност доказва ехо отговорът
ICMP е протокол за достижимост, който не познава интерфейси или тунели. Когато пристигне отговор, ядрото съобщава, че хост е отговорил; то не съобщава кой маршрут е пренесъл заявката или отговора. Филтрирането прави сигнала още по-шумен, защото защитна стена, която блокира ехо заявки, не казва нищо за портовете зад нея. А профил с разделен тунел може умишлено да изключи тествания адрес, докато всяка друга дестинация работи.
Това, което наистина искате да знаете, е дали конкретна услуга е използваема по пътя, който приложението поема. Изберете хоста и порта, които приложението вика, и после изисквайте отговор на приложния слой.
Достижимостта и състоянието на тунела са различни факти и всеки от тях може да е верен, докато другият е неверен. Когато ги държите разделени, знаете кой притежава отказа. Когато ги слеете в една проверка, получавате тикет, който никой не може да насочи.
Питайте Android за транспорта, не за ping
Android отговаря директно на въпроса за състоянието чрез ConnectivityManager. Възможностите на активната мрежа носят флаг за VPN транспорт, който се задава, когато трафикът минава през VPN интерфейс. Извикването е локално, евтино и независимо от това дали някой отдалечен хост отговаря.
Тази Java версия връща false, вместо да хвърли изключение, когато няма активна мрежа. Понеже чете активната мрежа, тя отразява профила, който потребителят е избрал в Настройки.
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActiveNetwork());
boolean tunnel = caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_VPN);
За известия при промяна регистрирайте NetworkCallback, вместо да правите периодични заявки по таймер. Не бъркайте това с VpnService.prepare, който само съобщава дали потребителят е дал разрешение за VPN, а не дали пакетите текат. Отнемането идва през VpnService.onRevoke, но забравянето на профил в Настройки не води до никакво излъчване.
iOS: имената на интерфейсите са евристика, не договор
Много iOS откъси преглеждат настройките за прокси, намират речника __SCOPED__ и търсят ключове на интерфейси като tap, tun, utun2, ppp или ipsec. Този подход е конвенция за именуване, а не документирана гаранция, затова актуализация на системата, която преименува интерфейс, може да го счупи. Освен това той често връща вярно за остарели записи, които надживяват тунела.
Когато конфигурацията е собственост на приложението ви, NEVPNManager ви дава истинско състояние. Той описва тунела, който приложението ви е стартирало; при VPN за отделни приложения други приложения може да останат изцяло извън този тунел.
Презаредете предпочитанията, преди да четете състоянието, защото стойността се променя, когато тунелът се вдига и пада:
let manager = NEVPNManager.shared()
manager.loadFromPreferences { error in
let up = manager.connection.status == .connected
print(up)
}
Флагът за състояние на платформата все още не доказва, че трафикът достига до партньора. Точно тази празнина покрива тестът на маршрута и затова един boolean не е достатъчен за поддръжката.
Профилите в Windows показват истинско поле за състояние
Windows следи VPN профилите отделно от адаптерите, а Get-VpnConnection показва ConnectionStatus за всеки профил, който познава. Тук се появяват профили, създадени през клиента на Windows или пакет за провизиране. Командата не е универсален детектор за тунели.
Прочетете полето за именуван профил, като добавите -AllUserConnection, когато профилът принадлежи на всички потребители:
Get-VpnConnection -Name "Fabrikam" | Select-Object Name, ConnectionStatus, ServerAddress
Клиентите от трети страни често остават невидими за тази команда дори когато тунелът им работи, така че празен резултат означава неизвестно, не изключено. Списъците с адаптери подвеждат също толкова: адаптер на производител може да се задържи, докато бездейства, а някои адаптери съществуват само по време на сесия. За профил, който Windows притежава, rasdial съобщава код за изход, по който можете да разклоните. Всичко това описва локално убеждение, а не достижимост на партньора.
Състояние плюс маршрут: проверка в две части
Свързан профил не казва нищо за това накъде отиват пакетите. Разделеният тунел може да държи тунела вдигнат, като изключва дестинацията, която ви интересува. Профилите Always-on остават свързани към мъртъв сървър, а kill switch умишлено блокира трафика, когато тунелът падне.
Тествайте и двата слоя: потвърдете, че VPN транспорт или профил е активен, после че дестинацията се резолвира и отговаря по този път. В Linux питайте ядрото кой интерфейс би използвало:
ip route get 192.0.2.10
resolvectl query intranet.example.test
Когато клиентът е извън вашия контрол, записвайте и двата резултата и оставете образецът да сочи слоя. Свързано плюс неуспешен тест на маршрута подсказва разделен тунел, DNS или политика. Изключено плюс работещ тест на маршрута означава, че друг път носи трафика.
Тест, който можете да изпълните по ред
Запишете първо състоянието на платформата, преди да промените каквото и да е състояние на мрежата. Резолвирайте името на хоста и отбележете семейството на адреса, защото AAAA запис може да поеме различен път от A запис. Отворете порта на услугата и изисквайте отговор на приложението, а не голо ръкостискане. Пазете всяко наблюдение в собствено поле на журнала.
На Linux машина с dig и curl три команди покриват резолвиране, маршрут и самата услуга. Изпълнете ги с вдигнат тунел и отново с паднал:
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
Четири отделни полета бият един boolean, защото състоянието, DNS, маршрутът и политиката се провалят независимо и попадат при различни екипи. Ping в терминал остава добра ръчна проверка за здраве. Той е лошо определение за свързаност при автоматизация, където API на платформата и тестът на маршрута отговарят на истинския въпрос.