API VPN sous iOS : NEVPNManager, fournisseur de tunnel ou profil ?
Choisissez l'API selon le transport auquel vous devez parler, puis prouvez que le tunnel transporte du trafic : ordre enregistrer, charger, démarrer, autorisations du fournisseur et règles à la demande.
Trois produits différents répondent au nom de VPN sous iOS, et ils ne partagent pas la même API. Le VPN personnel repose sur les transports IPsec et IKEv2 intégrés au système. Un tunnel personnalisé exécute votre propre protocole dans une extension réseau. Et un profil de configuration configure l'un ou l'autre et peut ajouter un comportement à la demande. Choisir selon le transport auquel vous devez parler est plus rapide que choisir selon le tutoriel qui a compilé en premier.
Exécutez les contrôles ci-dessous dans l'ordre, car chaque étape suppose que la précédente a produit une configuration valide.
Étape 1 : choisir selon le transport
Si le serveur est IKEv2 ou IPsec à la Cisco, NEVPNManager suffit et les transports du système viennent gratuitement. Si le serveur parle OpenVPN, WireGuard ou autre chose, NEVPNManager ne peut pas aider : il n'a pas de point d'accroche pour un protocole tiers. Ce cas exige NETunnelProviderManager avec un fournisseur de tunnel de paquets qui implémente le protocole. Un profil ne fait que distribuer de la configuration et ne peut pas ajouter un transport que le système d'exploitation n'a pas.
PPTP n'est pas une cible sur les systèmes actuels. L'IPsec à secret partagé attend toujours le nom de groupe dans remoteIdentifier, un élément de trousseau qui porte le secret et une authentification étendue quand le serveur demande un nom d'utilisateur. Chaque pièce manquante se manifeste par la même erreur de configuration générique, alors ajoutez-les toutes avant de déboguer autre chose.
Étape 2 : respecter l'ordre enregistrer, charger, démarrer
NEVPNManager écrit dans les préférences, les relit et ne démarre qu'ensuite. Renseignez les objets de protocole et de gestionnaire, appelez saveToPreferences, appelez loadFromPreferences et appelez startVPNTunnel depuis le gestionnaire de fin du chargement. Démarrer avant le retour du chargement produit une erreur de configuration invalide, code 1 dans NEVPNErrorDomain, sur une configuration par ailleurs correcte.
La forme est assez courte pour tenir en un seul endroit :
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }
startVPNTunnel revient quand la requête est acceptée, pas quand le tunnel est monté. Observez NEVPNStatusDidChange et lisez connection.status pour l'état réel. Une app qui suppose le succès au point d'appel signale un VPN connecté alors que l'extension négocie encore. Un état de connexion est normal un instant ; un état qui n'en sort jamais est la panne qui mérite d'être journalisée.
Étape 3 : donner au processus du fournisseur ce dont il a besoin
Un transport personnalisé s'exécute dans un processus séparé avec son propre identifiant de bundle et sa propre autorisation. L'app conteneur et le fournisseur ont tous deux besoin de l'autorisation d'extension réseau au moment de la signature, et une compilation Developer ID hors de l'App Store doit encore la porter dans le profil de provisionnement. Une autorisation manquante ressemble à un bug de protocole parce que l'extension ne démarre tout simplement pas.
Il n'y a aucun descripteur de socket public à emprunter. NEPacketTunnelProvider vous donne NEPacketTunnelFlow avec read, write et cancel, et le code qui tend vers des chemins de clés privées casse d'une version à l'autre. Le fournisseur continue de tourner pendant que l'app est en arrière-plan, donc le conteneur n'a pas besoin de mode arrière-plan pour cela.
Étape 4 : à la demande est un jeu de règles, pas un interrupteur
isOnDemandEnabled n'arme que les règles ; NEOnDemandRuleConnect et ses semblables décident quand le tunnel monte. Une règle d'évaluation de connexion avec une URL de sonde ne vaut que ce que vaut cette URL. Si la sonde répond sans le tunnel, la règle conclut que le réseau privé est déjà joignable et ne se connecte jamais, alors pointez-la vers quelque chose qui ne répond que de l'intérieur.
Le toujours actif est une promesse distincte. Il exige un appareil supervisé et un profil géré, et un utilisateur non supervisé peut retirer un profil quand il veut. Ne livrez pas une conception qui dépend du toujours actif sauf si le parc est supervisé.
Étape 5 : prouver le chemin, pas l'étiquette
Scanner les interfaces tun, tap, ppp ou ipsec prouve qu'un VPN est configuré, pas que votre requête l'a utilisé. NWPathMonitor avec usesInterfaceType(.other) indique qu'une interface virtuelle est disponible, et un gestionnaire de viabilité peut tester un seul hôte. Ni l'un ni l'autre ne prouve le chemin de sortie, alors combinez-les avec une requête vers une ressource que seul le tunnel peut atteindre. Les noms d'interface sont une aide au diagnostic, jamais une porte sur laquelle la logique applicative devrait se brancher.
Pour un contrôle terrain, comparez l'adresse publique avec et sans le tunnel et récupérez une page uniquement interne. Un appel d'état peut signaler connecté pendant que le fournisseur négocie, alors laissez le résultat de la ressource décider et traitez l'état comme une preuve d'appui.