iOS VPN API: NEVPNManager, tunelio teikėjas ar profilis?
Pasirinkite API pagal transportą, kuriuo turite kalbėti, tada įrodykite, kad tunelis perduoda srautą: save-load-start tvarka, provider entitlement ir on-demand taisyklės.
Trys skirtingi produktai atsako į iOS VPN vardą ir jie nesidalina vienu API. Personal VPN naudoja sistemos įmontuotus IPsec ir IKEv2 transportus. Custom tunnel vykdo jūsų pačių protokolą network extension viduje. Configuration profile sukonfigūruoja bet kurį iš jų ir gali pridėti on-demand elgseną. Rinktis pagal transportą, kuriuo turite kalbėti, greičiau nei rinktis pagal tą pamoką, kuri buvo sukompiliuota pirmoji.
Atlikite toliau pateiktus patikrinimus iš eilės, nes kiekvienas žingsnis daro prielaidą, kad ankstesnis sukūrė galiojančią konfigūraciją.
1 veiksmas: rinkitės pagal transportą
Jei serveris yra IKEv2 arba Cisco stiliaus IPsec, NEVPNManager pakanka ir sistemos transportai ateina nemokamai. Jei serveris kalba OpenVPN, WireGuard arba kuo nors kitu, NEVPNManager negali padėti: jis neturi kablio trečiosios šalies protokolui. Tam atvejui reikia NETunnelProviderManager su packet tunnel provider, kuris įgyvendina protokolą. Profilis tik paskirsto konfigūraciją ir negali pridėti transporto, kurio operacinė sistema neturi.
PPTP nėra tikslas dabartinėse sistemose. Shared-secret IPsec vis dar tikisi grupės pavadinimo remoteIdentifier, keychain elemento, saugančio paslaptį, ir išplėstinės autentifikacijos, kai serveris prašo vartotojo vardo. Kiekviena trūkstama dalis pasirodo kaip ta pati bendra konfigūracijos klaida, todėl pridėkite jas visas prieš derindami ką nors kita.
2 veiksmas: gerbkite išsaugojimo, įkėlimo, paleidimo tvarką
NEVPNManager rašo į preferences, perskaito juos atgal ir tik tada paleidžia. Užpildykite protokolo ir manager objektus, iškvieskite saveToPreferences, iškvieskite loadFromPreferences ir iškvieskite startVPNTunnel iš load completion handler. Paleidimas prieš grįžtant įkėlimui sukelia configuration-invalid klaidą, NEVPNErrorDomain code 1, konfigūracijoje, kuri kitu atveju yra teisinga.
Forma pakankamai trumpa, kad tilptų vienoje vietoje:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }startVPNTunnel grįžta, kai užklausa priimama, o ne kai tunelis pakeltas. Stebėkite NEVPNStatusDidChange ir skaitykite connection.status tikrajai būsenai. Programėlė, kuri daro prielaidą apie sėkmę iškvietimo vietoje, praneša apie prisijungusį VPN, kol extension dar derasi. Connecting būsena trumpam yra normalu; būsena, kuri niekada iš jos neišeina, yra gedimas, kurį verta registruoti.
3 veiksmas: duokite provider procesui tai, ko jam reikia
Custom transport veikia atskirame procese su savo bundle identifier ir savo entitlement. Tiek container programėlei, tiek provider pasirašymo metu reikia network-extension entitlement, o Developer ID build už App Store ribų vis tiek turi jį nešti provisioning profile. Trūkstamas entitlement atrodo kaip protokolo klaida, nes extension tiesiog nepaleidžiamas.
Nėra viešo socket descriptor, kurį būtų galima pasiskolinti. NEPacketTunnelProvider duoda jums NEPacketTunnelFlow su read, write ir cancel, o kodas, kuris siekia privačių raktų kelių, lūžta tarp leidimų. Provider toliau veikia, kol programėlė yra fone, todėl container programėlei tam nereikia fono režimo.
4 veiksmas: on-demand yra taisyklių rinkinys, ne jungiklis
isOnDemandEnabled tik užtaiso taisykles; NEOnDemandRuleConnect ir jo broliai nusprendžia, kada tunelis pakyla. evaluate-connection taisyklė su probe URL yra tik tokia gera, kokia yra ta URL. Jei probe atsako be tunelio, taisyklė daro išvadą, kad privatus tinklas jau pasiekiamas, ir niekada neprisijungia, todėl nukreipkite ją į kažką, kas atsako tik iš vidaus.
Always-on yra atskiras pažadas. Jam reikia prižiūrimo įrenginio ir valdomo profilio, o neprižiūrimas naudotojas gali pašalinti profilį kada nori. Nesiųskite dizaino, kuris priklauso nuo always-on, nebent flotilė yra prižiūrima.
5 veiksmas: įrodykite kelią, ne etiketę
tun, tap, ppp arba ipsec sąsajų skenavimas įrodo, kad VPN sukonfigūruotas, o ne kad jūsų užklausa jį naudojo. NWPathMonitor su usesInterfaceType(.other) sako, kad virtuali sąsaja yra prieinama, o viability handler gali patikrinti vieną hostą. Nė vienas neįrodo išėjimo kelio, todėl sujunkite juos su užklausa į išteklių, kurį pasiekti gali tik tunelis. Sąsajų pavadinimai yra diagnostinė pagalba, niekada vartai, nuo kurių programos logika neturėtų šakotis.
Lauko patikrinimui palyginkite viešąjį adresą su tuneliu ir be jo bei gaukite tik vidinį puslapį. Statuso iškvietimas gali pranešti apie prisijungimą, kol provider derasi, todėl leiskite ištekliaus rezultatui nuspręsti, o statusą laikykite papildomu įrodymu.