Co NEVPNManager może utworzyć na iOS (a czego nie)
API VPN systemu iOS buduje jedną konfigurację należącą do aplikacji z trzech klas protokołów. L2TP, PPTP i podpisane profile nie są częścią tej powierzchni.
Gdy budujesz ekran VPN wewnątrz aplikacji iOS, pierwsze zaskoczenie jest takie, że lista protokołów w aplikacji Ustawienia nie jest listą API. Framework Network Extension pozwala aplikacji utworzyć jedną osobistą konfigurację VPN, należącą do tej aplikacji, i przyjmuje tylko kilka obiektów protokołu. Wszystko inne, czego ludzie oczekują, od L2TP po pobrany profil, znajduje się poza tą powierzchnią lub jest prywatne dla Apple. Błędy, które następują, zwykle nie są błędami, to API odmawia pracy, której nigdy nie otrzymało.
Mit: API to edytor Ustawień
Uważa się, że skoro iOS potrafi konfigurować profile IKEv1, IKEv2, L2TP i IPsec, aplikacja może utworzyć każdy z nich programowo. Nie może. Framework udostępnia wywołującej aplikacji dokładnie jedno miejsce konfiguracji, a to miejsce przyjmuje tylko mały zestaw publicznych klas protokołów. Wszystko inne, czego ludzie oczekują, od L2TP po pobrany profil, znajduje się poza tą powierzchnią lub jest prywatne dla Apple.
Błędy, które następują, zwykle nie są błędami. To API odmawia pracy, której nigdy nie otrzymało, a rozwiązaniem jest zaprojektowanie ekranu wokół tego, czym API zarządza.
Trzy obiekty protokołu i te, których nie ma
Twoje opcje to IKEv1 przez NEVPNProtocolIPSec, IKEv2 przez NEVPNProtocolIKEv2 oraz NETunnelProviderProtocol, jeśli dostarczasz własne rozszerzenie tunelu pakietów. Dokumentacja NEVPNManager wymienia akceptowane obiekty protokołu. L2TP i PPTP nigdy nie pojawiają się na tej liście, ponieważ Apple nie opublikowało dla nich klas. Próba któregokolwiek z nich kończy się przy zapisie błędem lub, co gorsza, konfiguracją, której system po cichu odmawia użyć.
Kod desktopowy podlega innym regułom. W systemie macOS SCNetworkInterfaceCreateWithInterface układa typ interfejsu, taki jak L2TP przez IPv4, i przypisuje go do usługi sieciowej, a networksetup -connectpppoeservice uruchamia wynik. Wymagane są uprawnienia administratora i narzędzie pomocnicze, ponieważ wspólny sekret i hasło trafiają do pęku kluczy systemu. Skopiuj ten projekt na iOS, a nic się nie skompiluje.
Przekaż referencję do pęku kluczy, a nie hasło
Żadna z dwóch klas IKE nie przyjmuje hasła jako tekstu. Dwie właściwości passwordReference i sharedSecretReference chcą trwałej referencji do pęku kluczy, którą otrzymujesz z SecItemCopyMatching, prosząc o kSecReturnPersistentRef. Przekazanie danych elementu lub wpisanie ciągu w pole powoduje błąd zapisu albo połączenie z pustymi poświadczeniami. Referencja jest trwała tylko tak długo, jak element pęku kluczy za nią, dlatego element musi istnieć, zanim konfiguracja zostanie złożona. Utwórz go w tej samej transakcji co zapis, a usuniesz całą klasę błędów kolejności.
Uwierzytelnianie certyfikatem idzie inną drogą: identityData plus identityDataPassword dla bloba PKCS#12. Dostarczanie tego bloba w pakiecie aplikacji to nawyk przejęty z kodu przykładowego, a nie decyzja wydawnicza, ponieważ hasło podróżuje razem z nim, a każda kopia aplikacji nosi tę samą tożsamość.
Uprawnienie i dostępność warunkują wszystko
Menedżer może w ogóle nie istnieć, a powodem jest provisionowanie. Identyfikator aplikacji potrzebuje możliwości Network Extension wraz z uprawnieniem do osobistego VPN, a profil podpisujący kompilację musi mieć oba.
Pomiń to, a współdzielona instancja zwróci nil albo zapis nie powiedzie się z błędem, który nigdy nie wspomina uprawnienia. Dostępność to druga brama. Jeśli celujesz w coś starszego niż iOS 8, symbolu brakuje w czasie działania, więc awaria to crash albo menedżer nil, a nie menedżer bez konfiguracji. Sprawdź środowisko uruchomieniowe i uprawnienie, zanim zaczniesz debugować graf obiektów.
Wczytaj, zmień, zapisz, a potem obserwuj kolejność na żądanie
Traktuj cykl życia jako wczytanie, zmianę i zapis i nigdy nie pomijaj wczytania. Dopóki loadFromPreferences się nie zakończy, menedżer nic nie trzyma i obiektu protokołu nie można odczytać ani podmienić.
Drugi zapis zastępuje konfigurację zamiast dodawać kolejną, więc zapis w połowie może uszkodzić profil, który działał. Reguły na żądanie tworzą uporządkowaną tablicę, a ta kolejność jest polityką. Umieść regułę łączenia z dowolnego miejsca przed regułą rozłączenia, a po ręcznym rozłączeniu następuje natychmiastowe ponowne połączenie, co wygląda jak defekt, ale jest zgodne z udokumentowaną oceną.
Przenieś regułę rozłączenia do przodu, gdy działanie użytkownika musi wygrać. To, co pozostaje poza kontrolą aplikacji, liczy się równie mocno. Trasy pochodzą z tunelu lub polityki serwera, a nie z ustawienia, które konfigurujesz, a dostawca tunelu pakietów zgłasza je przy starcie. Aplikacja nie może wyświetlić ani edytować profili zainstalowanych przez inne aplikacje lub profile konfiguracji, więc nie obiecuj ekranu pokazującego każdy VPN na urządzeniu.