API VPN per iOS: NEVPNManager, provider di tunnel o profilo?
Scegli l’API in base al trasporto con cui devi parlare, poi dimostra che il tunnel porta traffico: ordine save-load-start, entitlement del provider e regole on-demand.
Tre prodotti diversi rispondono al nome iOS VPN e non condividono un’API. Personal VPN usa i trasporti IPsec e IKEv2 integrati nel sistema. Custom tunnel esegue il tuo protocollo all’interno di una network extension. Configuration profile configura l’uno o l’altro e può aggiungere un comportamento on-demand. Scegliere in base al trasporto con cui devi parlare è più rapido che scegliere in base al tutorial che è stato compilato per primo.
Esegui i controlli qui sotto in ordine, perché ogni passaggio presuppone che il precedente abbia prodotto una configurazione valida.
Passaggio 1: scegli in base al trasporto
Se il server è IKEv2 o IPsec in stile Cisco, NEVPNManager basta e i trasporti di sistema arrivano gratis. Se il server parla OpenVPN, WireGuard o qualsiasi altra cosa, NEVPNManager non può aiutare: non ha un aggancio per un protocollo di terze parti. Quel caso richiede NETunnelProviderManager con un packet tunnel provider che implementi il protocollo. Un profilo distribuisce solo la configurazione e non può aggiungere un trasporto che il sistema operativo non ha.
PPTP non è un obiettivo sui sistemi attuali. IPsec con segreto condiviso si aspetta ancora il nome del gruppo in remoteIdentifier, un elemento keychain che custodisce il segreto e l’autenticazione estesa quando il server chiede un nome utente. Ogni pezzo mancante emerge come lo stesso errore di configurazione generico, quindi aggiungili tutti prima di fare debug di qualsiasi altra cosa.
Passaggio 2: rispetta l’ordine salvataggio, caricamento, avvio
NEVPNManager scrive nelle preferences, le rilegge e solo allora avvia. Compila gli oggetti protocollo e manager, chiama saveToPreferences, chiama loadFromPreferences e chiama startVPNTunnel dal load completion handler. Avviare prima che il caricamento ritorni produce un errore configuration-invalid, NEVPNErrorDomain code 1, su una configurazione che per il resto è corretta.
La forma è abbastanza breve da tenere in un solo posto:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }startVPNTunnel ritorna quando la richiesta è accettata, non quando il tunnel è attivo. Osserva NEVPNStatusDidChange e leggi connection.status per lo stato reale. Un’app che presume il successo nel punto di chiamata riporta un VPN connesso mentre l’extension sta ancora negoziando. Uno stato connecting è normale per un momento; uno stato che non ne esce mai è il guasto che vale la pena registrare.
Passaggio 3: dai al processo provider ciò che gli serve
Un Custom transport gira in un processo separato con il proprio bundle identifier e il proprio entitlement. Sia l’app container sia il provider hanno bisogno dell’entitlement network-extension al momento della firma, e una build Developer ID fuori dall’App Store deve comunque portarlo nel provisioning profile. Un entitlement mancante sembra un bug di protocollo perché l’extension semplicemente non si avvia.
Non c’è nessun socket descriptor pubblico da prendere in prestito. NEPacketTunnelProvider ti consegna NEPacketTunnelFlow con read, write e cancel, e il codice che raggiunge percorsi di chiavi private si rompe tra una release e l’altra. Il provider continua a girare mentre l’app è in background, quindi l’app container non ha bisogno di una modalità background per questo.
Passaggio 4: on-demand è un insieme di regole, non un interruttore
isOnDemandEnabled arma solo le regole; NEOnDemandRuleConnect e i suoi fratelli decidono quando il tunnel si alza. Una regola evaluate-connection con un probe URL vale quanto quell’URL. Se il probe risponde senza il tunnel, la regola conclude che la rete privata è già raggiungibile e non si connette mai, quindi puntala a qualcosa che risponda solo dall’interno.
Always-on è una promessa separata. Richiede un dispositivo supervisionato e un profilo gestito, e un utente non supervisionato può rimuovere un profilo quando vuole. Non rilasciare un design che dipende da always-on a meno che la flotta non sia supervisionata.
Passaggio 5: dimostra il percorso, non l’etichetta
Scansionare interfacce tun, tap, ppp o ipsec dimostra che un VPN è configurato, non che la tua richiesta lo abbia usato. NWPathMonitor con usesInterfaceType(.other) dice che un’interfaccia virtuale è disponibile, e un viability handler può testare un host. Nessuno dei due dimostra il percorso di uscita, quindi combinali con una richiesta a una risorsa che solo il tunnel può raggiungere. I nomi delle interfacce sono un aiuto diagnostico, mai un cancello su cui la logica dell’app debba diramarsi.
Per una verifica sul campo, confronta l’indirizzo pubblico con e senza il tunnel e recupera una pagina solo interna. Una chiamata di stato può riportare connesso mentre il provider negozia, quindi lascia decidere il risultato della risorsa e tratta lo stato come prova di supporto.