Czy iPhone jest w VPN? Co aplikacja iOS naprawdę może zobaczyć
W iOS SDK nie ma jednej flagi VPN. Aplikacja może obserwować tylko własną konfigurację, powiadomienie o stanie i ograniczony zrzut proxy, nic więcej.
Zapytaj aplikację iOS, czy telefon jest w VPN, a uczciwa odpowiedź brzmi: nie może tego wiedzieć w sensie, o którym myślisz. SDK nie udostępnia flagi «urządzenie jest w tunelu», a prywatne interfejsy, które mogłyby się do tego zbliżyć, są zamknięte dla publikowanych aplikacji. Możesz obserwować własną konfigurację aplikacji, stan z nią związany oraz jedną lub dwie pośrednie wskazówki ze stosu sieciowego. Każda odpowiada na inne pytanie, a większość zepsutych sprawdzeń bierze się z potraktowania jednej z nich jako całej odpowiedzi.
Mit jednej flagi VPN
Panuje przekonanie, że gdzieś w SDK istnieje właściwość, która informuje, czy urządzenie jest w tunelu, tak jak flaga osiągalności informuje, czy host odpowiada. Taka publiczna właściwość nie istnieje. A nawet gdyby istniała, «tunel istnieje» i «mój ruch z niego korzysta» to różne twierdzenia, i dla większości aplikacji liczy się tylko drugie.
Właśnie ta luka sprawia, że biblioteki reklamujące jednolinijkowy detektor VPN zwykle czytają coś kruchego, na przykład nazwę interfejsu albo klucz proxy, i przedstawiają to jako wyrok.
Wczytaj preferencje, zanim zaufasz nil
Współdzielona instancja menedżera istnieje od chwili, gdy o nią poprosisz, ale jej właściwość protokołu pozostaje nil, dopóki nie zakończy się wywołanie ładowania. Zatem nil protokołu oznacza «jeszcze nie wczytano» co najmniej tak często, jak «nie zainstalowano». Czytaj wewnątrz bloku ukończenia i dopiero potem decyduj: istniejący obiekt protokołu z włączoną flagą aktywacji to wygląd «zainstalowano».
Drugi sygnał jest na obiekcie połączenia: stan nieprawidłowy, który system zgłasza, gdy ta aplikacja nie ma zainstalowanej konfiguracji. Nieprawidłowy stan razem z nil protokołu po zakończonym ładowaniu to prawdziwy brak, a nie wyścig czasu.
Zmiany połączenia przychodzą jako powiadomienia
Procedury obsługi przekazane do load i save informują, co stało się z konfiguracją, a nie co robi tunel. Czekanie, aż jedna z nich zadziała przy łączeniu, to wyścig, który nigdy się nie rozstrzyga. Zamiast tego obserwuj powiadomienie o zmianie stanu i odczytaj bieżącą wartość obiektu połączenia, gdy nadejdzie.
Gdy konfiguracja jest zainstalowana, stan połączenia przechodzi krótką sekwencję: rozłączono, łączenie, połączono, ponowne potwierdzanie, rozłączanie. «Połączono» opisuje tunel, a nie serwer za nim, więc nie jest dowodem, że ruch płynie. On-demand może też podnieść tunel, gdy aplikacja jest wstrzymana, a wtedy powiadomienie przychodzi, zanim masz co aktualizować.
Ograniczony zrzut proxy to wskazówka, nie wyrok
CFNetwork może przekazać aplikacji bieżące ustawienia proxy systemu, a w tym wyniku znajduje się ograniczony słownik z kluczem według nazwy interfejsu. Nazwa zaczynająca się od tun, utun, ppp, ipsec lub tap to wskazówka, że tunel istnieje. To nadal zrzut tego, co ta aplikacja może zobaczyć, a nie stwierdzenie, dokąd podróżują pakiety.
Dostawcy nie zgadzają się co do nazewnictwa, więc brakujący prefiks niczego nie dowodzi, a istniejący interfejs może istnieć, nie przenosząc ruchu. Osiągalność jest jeszcze słabsza: udane żądanie do prywatnego adresu pokazuje, że ścieżka działała dla tego żądania w tej chwili, a nie że zainstalowano VPN.
Symulator pożycza Maca, a inne aplikacje pozostają niewidoczne
Symulator nie ma własnego stosu sieciowego; każde połączenie, które nawiązuje, jest połączeniem Maca. VPN działający na Macu hosta obowiązuje więc już dla symulowanej aplikacji, a ustawienia samego symulatora nic nie pokazują. Jeśli tunel podniósł się po uruchomieniu symulatora, ponowne uruchomienie go jest zwykle szybsze niż debugowanie aplikacji. Host na niestandardowym porcie potrzebuje tego portu w adresie URL albo lokalnego przekierowania, takiego jak socat TCP-LISTEN:12345,fork TCP:host:12345.
Publiczne interfejsy API nie będą wyliczać profili VPN należących do innych aplikacji ani profili konfiguracji. Dla jednej znanej aplikacji przenośnym trikiem jest sondowanie schematu URL przez canOpenURL, a od iOS 9 odpytywany schemat musi być zadeklarowany w twoim Info.plist; jeśli go pominiesz, wywołanie zwróci false. OpenVPN Connect odpowiada na openvpn://, co czyni go dobrym przykładem i złym ogólnym detektorem.
Połącz trzy obserwacje i powiedz, co znaczą
W praktyce zestaw trzy wyniki: konfigurację, która się wczytała i jest włączona, stan połączenia, który nie jest nieprawidłowy, oraz żądanie do adresu osiągalnego tylko przez tunel. Każdy z osobna wprowadza w błąd; razem mówią, co aplikacja może wiedzieć, a nie co zakłada użytkownik.
Zapisz wynik jako trzy wiersze w swojej diagnostyce, a nie jako jeden boolean. Kiedy użytkownik mówi, że VPN jest wyłączony, a twoja aplikacja się nie zgadza, trzy wiersze pokazują, która obserwacja odbiegła, i to jest różnica między zgłoszeniem do wsparcia, na które możesz zareagować, a takim, które kończy się słowami «u mnie działa».