Cando constrúes unha pantalla VPN dentro dunha app iOS, a primeira sorpresa é que a lista de protocolos da app Axustes non é a lista da API. O framework Network Extension permite á túa app crear unha configuración VPN persoal, propiedade desa app, e só acepta uns poucos obxectos de protocolo. Todo o demais que a xente espera, desde L2TP ata un perfil descargado, queda fóra desa superficie ou é privado de Apple. Os fallos que seguen normalmente non son erros, son a API rexeitando un traballo que nunca lle deron.

O mito: a API é un editor de Axustes

Crése que, como iOS pode configurar perfís IKEv1, IKEv2, L2TP e IPsec, unha app pode crear calquera deles de forma programática. Non pode. O framework expón exactamente unha ranura de configuración á app que chama, e esa ranura só acepta un pequeno conxunto de clases de protocolo públicas. Todo o demais que a xente espera, desde L2TP ata un perfil descargado, queda fóra desa superficie ou é privado de Apple.

Os fallos que seguen normalmente non son erros. Son a API rexeitando un traballo que nunca lle deron, e a solución é deseñar a pantalla arredor do que a API posúe.

Tres obxectos de protocolo e os que non existen

As túas opcións son IKEv1 mediante NEVPNProtocolIPSec, IKEv2 mediante NEVPNProtocolIKEv2, e NETunnelProviderProtocol se distribúes a túa propia extensión de túnel de paquetes. A referencia de NEVPNManager lista os obxectos de protocolo aceptados. L2TP e PPTP nunca aparecen nesa lista porque Apple non publicou clases para eles. Tentar calquera dos dous remata ao gardar cun erro, ou peor, cunha configuración que o sistema rexeita silenciosamente usar.

O código de escritorio segue outras regras. En macOS, SCNetworkInterfaceCreateWithInterface apila un tipo de interface como L2TP sobre IPv4 e xúntao a un servizo de rede, e networksetup -connectpppoeservice inicia o resultado. Cómprens dereitos de administrador e unha ferramenta de axuda, xa que o segredo compartido e o contrasinal van ao chaveiro do sistema. Copia ese deseño a iOS e nada compila.

Pasa unha referencia do chaveiro, non o contrasinal

Ningunha das dúas clases IKE acepta un contrasinal como texto. As dúas propiedades passwordReference e sharedSecretReference queren unha referencia persistente do chaveiro, que obtés de SecItemCopyMatching pedindo kSecReturnPersistentRef. Pasar os datos do elemento, ou introducir unha cadea no campo, produce un fallo ao gardar ou unha conexión con credenciais baleiras. A referencia só é tan duradeira como o elemento do chaveiro que hai detrás, por iso o elemento ten que existir antes de montar a configuración. Créao na mesma transacción que o gardado e eliminas toda unha clase de erros de orde.

A autenticación con certificado toma outra ruta: identityData máis identityDataPassword para un blob PKCS#12. Distribuír ese blob dentro do paquete da app é un hábito herdado do código de exemplo, non unha decisión de produción, porque o contrasinal viaxa con el e cada copia da app leva a mesma identidade.

O permiso e a dispoñibilidade condicionan todo

Pode que o xestor non exista en absoluto, e a razón é o aprovisionamento. O identificador da túa app necesita a capacidade Network Extension xunto co permiso de VPN persoal, e o perfil que asina a compilación ten que levar ambos.

Omíteo e a instancia compartida devolve nil, ou o gardado falla cun erro que nunca menciona o permiso. A dispoñibilidade é a outra porta. Se apuntas a algo máis antigo que iOS 8, o símbolo falta en tempo de execución, así que o fallo é un fallo da aplicación ou un xestor nil, non un xestor sen configuración. Comproba o tempo de execución e o permiso antes de depurar o teu grafo de obxectos.

Carga, modifica, garda e despois vixía a orde a demanda

Trata o ciclo de vida como cargar, modificar, gardar, e nunca saltes a carga. Ata que loadFromPreferences remate, o xestor non ten nada e o obxecto de protocolo non se pode ler nin cambiar.

Un segundo gardado substitúe a configuración en lugar de engadir outra, así que un gardado a medias pode danar un perfil que funcionaba. As regras a demanda forman unha matriz ordenada, e esa orde é a política. Pon unha regra de conexión desde calquera lugar diante da regra de desconexión e a unha desconexión manual séguella unha reconexión inmediata, o que parece un defecto pero segue a avaliación documentada.

Move a regra de desconexión á fronte cando a acción do usuario ten que gañar. O que queda fóra do control da app importa igual. As rutas veñen do túnel ou da política do servidor en lugar dunha preferencia que ti estableces, cun provedor de túnel de paquetes informándoas cando arrinca. A app non pode listar nin editar perfís instalados por outras apps ou perfís de configuración, así que non prometas unha pantalla que amose todas as VPN do dispositivo.

Artigos relacionados