Drie verschillende producten luisteren naar de naam iOS VPN en ze delen geen API. Personal VPN rijdt op de ingebouwde IPsec- en IKEv2-transporten van het systeem. Custom tunnel draait je eigen protocol binnen een network extension. Configuration profile configureert een van beide en kan on-demand-gedrag toevoegen. Kiezen op basis van het transport waarmee je moet praten is sneller dan kiezen op basis van welke tutorial het eerst compileerde.

Voer de onderstaande controles in volgorde uit, want elke stap veronderstelt dat de vorige een geldige configuratie opleverde.

Stap 1: kies op basis van transport

Als de server IKEv2 of IPsec in Cisco-stijl is, volstaat NEVPNManager en krijg je de systeemtransporten gratis. Als de server OpenVPN, WireGuard of iets anders spreekt, kan NEVPNManager niet helpen: het heeft geen haak voor een protocol van derden. Dat geval vereist NETunnelProviderManager met een packet tunnel provider die het protocol implementeert. Een profiel verdeelt alleen configuratie en kan geen transport toevoegen dat het besturingssysteem mist.

PPTP is geen doelwit op huidige systemen. Shared-secret IPsec verwacht nog steeds de groepsnaam in remoteIdentifier, een keychain-item dat het geheim bevat, en uitgebreide authenticatie wanneer de server om een gebruikersnaam vraagt. Elk ontbrekend stuk komt naar voren als dezelfde algemene configuratiefout, dus voeg ze allemaal toe voordat je iets anders debugt.

Stap 2: respecteer de volgorde opslaan, laden, starten

NEVPNManager schrijft naar preferences, leest ze terug en start pas dan. Vul de protocol- en manager-objecten in, roep saveToPreferences aan, roep loadFromPreferences aan en roep startVPNTunnel aan vanuit de load completion handler. Starten voordat het laden terugkeert levert een configuration-invalid-fout op, NEVPNErrorDomain code 1, bij een configuratie die verder correct is.

De vorm is kort genoeg om op één plek te bewaren:

manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }

startVPNTunnel keert terug wanneer het verzoek is geaccepteerd, niet wanneer de tunnel omhoog is. Observeer NEVPNStatusDidChange en lees connection.status voor de echte status. Een app die succes veronderstelt op de aanroepplek meldt een verbonden VPN terwijl de extension nog onderhandelt. Een connecting-status is even normaal; een status die daar nooit uit komt is de fout die het loggen waard is.

Stap 3: geef het provider-proces wat het nodig heeft

Custom transport draait in een apart proces met zijn eigen bundle identifier en zijn eigen entitlement. Zowel de container-app als de provider hebben bij het ondertekenen de network-extension-entitlement nodig, en een Developer ID-build buiten de App Store moet die nog steeds in het provisioning profile dragen. Een ontbrekende entitlement lijkt op een protocolbug omdat de extension simpelweg niet start.

Er is geen openbare socket descriptor om te lenen. NEPacketTunnelProvider geeft je NEPacketTunnelFlow met read, write en cancel, en code die naar paden van privésleutels grijpt, breekt tussen releases. De provider blijft draaien terwijl de app op de achtergrond is, dus de container-app heeft daarvoor geen achtergrondmodus nodig.

Stap 4: on-demand is een regelset, geen schakelaar

isOnDemandEnabled bewapent alleen de regels; NEOnDemandRuleConnect en zijn broers en zussen beslissen wanneer de tunnel omhoog komt. Een evaluate-connection-regel met een probe-URL is slechts zo goed als die URL. Als de probe antwoordt zonder de tunnel, concludeert de regel dat het privénetwerk al bereikbaar is en verbindt nooit, dus richt hem op iets dat alleen van binnenuit antwoordt.

Always-on is een aparte belofte. Het vereist een apparaat onder toezicht en een beheerd profiel, en een gebruiker zonder toezicht kan een profiel verwijderen wanneer hij wil. Lever geen ontwerp dat van always-on afhangt, tenzij de vloot onder toezicht staat.

Stap 5: bewijs het pad, niet het label

Scannen naar tun-, tap-, ppp- of ipsec-interfaces bewijst dat een VPN is geconfigureerd, niet dat je verzoek ervan gebruikmaakte. NWPathMonitor met usesInterfaceType(.other) zegt dat een virtuele interface beschikbaar is, en een viability handler kan één host testen. Geen van beide bewijst het uitgangspad, dus combineer ze met een verzoek aan een resource die alleen de tunnel kan bereiken. Interfacenamen zijn een diagnostisch hulpmiddel, nooit een poort waar applicatielogica op zou moeten vertakken.

Voor een veldcontrole vergelijk je het openbare adres met en zonder de tunnel en haal je een alleen-interne pagina op. Een statusaanroep kan verbonden melden terwijl de provider onderhandelt, dus laat het resultaat van de resource beslissen en behandel de status als ondersteunend bewijs.

Gerelateerde artikelen