API VPN pentru iOS: NEVPNManager, furnizor de tunel sau profil?
Alegeți API-ul după transportul cu care trebuie să vorbiți, apoi dovediți că tunelul duce trafic: ordinea save-load-start, entitlement-urile provider-ului și regulile on-demand.
Trei produse diferite răspund la numele iOS VPN și nu împart un API. Personal VPN folosește transporturile IPsec și IKEv2 integrate în sistem. Custom tunnel rulează propriul protocol într-o network extension. Configuration profile configurează oricare dintre ele și poate adăuga comportament on-demand. Alegerea după transportul cu care trebuie să vorbești este mai rapidă decât alegerea după tutorialul care s-a compilat primul.
Rulați verificările de mai jos în ordine, pentru că fiecare pas presupune că precedentul a produs o configurație validă.
Pasul 1: alegeți după transport
Dacă serverul este IKEv2 sau IPsec în stil Cisco, NEVPNManager este suficient și transporturile sistemului vin gratis. Dacă serverul vorbește OpenVPN, WireGuard sau orice altceva, NEVPNManager nu poate ajuta: nu are cârlig pentru un protocol terț. Acel caz cere NETunnelProviderManager cu un packet tunnel provider care implementează protocolul. Un profil doar distribuie configurație și nu poate adăuga un transport pe care sistemul de operare nu îl are.
PPTP nu este o țintă pe sistemele actuale. IPsec cu secret partajat încă așteaptă numele grupului în remoteIdentifier, un element keychain care ține secretul și autentificare extinsă când serverul cere un nume de utilizator. Fiecare piesă lipsă apare ca aceeași eroare generică de configurație, așa că adaugă-le pe toate înainte de a depana orice altceva.
Pasul 2: respectați ordinea salvare, încărcare, pornire
NEVPNManager scrie în preferences, le citește înapoi și abia apoi pornește. Completați obiectele de protocol și manager, apelați saveToPreferences, apelați loadFromPreferences și apelați startVPNTunnel din load completion handler. Pornirea înainte ca încărcarea să revină produce o eroare configuration-invalid, NEVPNErrorDomain code 1, pe o configurație altfel corectă.
Forma este destul de scurtă pentru a fi ținută într-un singur loc:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }startVPNTunnel revine când cererea este acceptată, nu când tunelul este sus. Observați NEVPNStatusDidChange și citiți connection.status pentru starea reală. O aplicație care presupune succes la locul apelului raportează un VPN conectat în timp ce extension-ul încă negociază. Starea connecting este normală pentru o clipă; o stare care nu iese niciodată din ea este eșecul care merită înregistrat.
Pasul 3: dați procesului provider ce are nevoie
Custom transport rulează într-un proces separat cu propriul bundle identifier și propriul entitlement. Atât aplicația container, cât și provider-ul au nevoie de entitlement-ul network-extension la semnare, iar un build Developer ID în afara App Store tot trebuie să îl poarte în provisioning profile. Un entitlement lipsă arată ca un bug de protocol pentru că extension-ul pur și simplu nu pornește.
Nu există niciun socket descriptor public de împrumutat. NEPacketTunnelProvider vă dă NEPacketTunnelFlow cu read, write și cancel, iar codul care ajunge la căi de chei private se strică între versiuni. Provider-ul continuă să ruleze cât timp aplicația este în fundal, așa că aplicația container nu are nevoie de mod fundal pentru asta.
Pasul 4: on-demand este un set de reguli, nu un comutator
isOnDemandEnabled doar înarmează regulile; NEOnDemandRuleConnect și frații lui decid când se ridică tunelul. O regulă evaluate-connection cu probe URL valorează exact cât acel URL. Dacă probe răspunde fără tunel, regula concluzionează că rețeaua privată este deja accesibilă și nu se conectează niciodată, așa că îndreptați-o spre ceva care răspunde doar din interior.
Always-on este o promisiune separată. Are nevoie de un dispozitiv supravegheat și de un profil administrat, iar un utilizator nesupravegheat poate elimina un profil oricând. Nu livrați un design care depinde de always-on decât dacă flota este supravegheată.
Pasul 5: dovediți calea, nu eticheta
Scanarea interfețelor tun, tap, ppp sau ipsec dovedește că un VPN este configurat, nu că cererea voastră l-a folosit. NWPathMonitor cu usesInterfaceType(.other) spune că o interfață virtuală este disponibilă, iar un viability handler poate testa un singur host. Niciuna nu dovedește calea de ieșire, așa că combinați-le cu o cerere către o resursă la care doar tunelul ajunge. Numele interfețelor sunt un ajutor de diagnostic, niciodată o poartă pe care logica aplicației să se ramifice.
Pentru o verificare pe teren, comparați adresa publică cu și fără tunel și aduceți o pagină doar internă. Un apel de status poate raporta conectat în timp ce provider-ul negociază, așa că lăsați rezultatul resursei să decidă și tratați statusul ca dovadă de sprijin.