Ping ка 192.0.2.10 каже само да је једна адреса одговорила на ICMP ехо, и ништа више. На мрежи без тунела може ипак успети, јер адреса може бити на локалној подмрежи; са здравим тунелом може и пасти, јер сервер одбацује ICMP док служи HTTPS. Провера која је вашој скрипти потребна јесте упит о статусу платформе плус тест руте ка дестинацији коју апликација користи. Третирајте их као два одвојена поља, никада као један булов израз.

Шта одговор на ехо заиста доказује

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. Тај приступ је конвенција именовања, не документована гаранција, па га ажурирање OS-а које преименује интерфејс може покварити. Такође радо пријављује true за застареле записе који надживљавају тунел.

Када ваша апликација поседује конфигурацију, NEVPNManager даје прави статус. Он описује тунел који је ваша апликација покренула; уз VPN по апликацији, друге апликације могу стајати потпуно изван тог тунела.

Поново учитајте подешавања пре читања статуса, јер се вредност мења док се тунел диже и пада:

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

Заставица статуса платформе ипак не доказује да саобраћај стиже до партнера. Управо ту празнину покрива тест руте, и зато један булов израз није довољан за подршку.

Windows профили откривају право поље статуса

Windows прати VPN профиле одвојено од адаптера, а Get-VpnConnection открива ConnectionStatus за сваки профил који познаје. Овде се појављују профили направљени преко Windows клијента или пакета за обезбеђивање. Ова cmdlet није општи детектор тунела.

Прочитајте поље за именовани профил, додајући -AllUserConnection када профил припада свим корисницима:

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

Клијенти трећих страна често остају невидљиви за ову cmdlet чак и када им је тунел активан, па празан резултат значи непознато, а не искључено. И листе адаптера подједнако обмањују: адаптер произвођача може остати док је неактиван, а неки адаптери постоје само током сесије. За профил који 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

Четири одвојена поља побеђују један булов израз, јер статус, DNS, рута и политика не успевају независно и завршавају код различитих тимова. Ping у терминалу остаје добра ручна провера. То је лоша дефиниција повезаности за аутоматизацију, где API платформе и тест руте одговарају на право питање.

Повезани чланци