Programar un cliente VPN: elija la capa antes de la contraseña
La CLI del proveedor, rasdial, una intención de aplicación o la automatización de la interfaz fallan cada uno de forma distinta. Elija la capa, mantenga el secreto fuera de argv y espere el estado, no los códigos de salida.
Los scripts arrancan clientes VPN en la capa que eligió el autor, y esa capa rara vez es la que necesitaba el trabajo. La línea de comandos del proveedor, el marcador del sistema operativo y una intención de aplicación móvil vuelven todos en momentos distintos de la vida de la conexión. También tratan el secreto de forma diferente, y esa diferencia decide si la contraseña es visible para cada usuario de la máquina. Elija la capa antes de escribir la primera línea del script.
Capa 1: la línea de comandos del proveedor
La mayoría de los clientes de escritorio incluyen una línea de comandos que acepta un nombre de perfil y, con demasiada frecuencia, una contraseña. El antiguo cliente de Cisco aceptaba un verbo connect con argumentos de usuario y contraseña; macOS expone el servicio integrado mediante networksetup; NetworkManager responde a nmcli. Estas llamadas vuelven cuando termina el comando, que no es el mismo momento en que el túnel pasa a ser utilizable. Lea la documentación del propio proveedor para la versión que despliegue, porque estas interfaces cambian y algunas se eliminan por completo.
nmcli connection up "Work VPN"
networksetup -connectpppoeservice "Work VPN"
La ventaja es que el proveedor conoce su propio almacén de perfiles, así que la llamada usa la misma configuración que usaría la GUI. La desventaja es que cada proveedor inventa sus propios verbos, y un script escrito para un cliente no se traslada a otro. Considere esta capa como el camino más corto cuando el cliente es fijo y la versión está fijada.
Capa 2: el servicio propio del sistema operativo
En Windows el marcador forma parte del sistema operativo y trabaja contra una entrada de la libreta de teléfonos en lugar del almacén de perfiles del proveedor. Eso lo hace más portátil entre clientes y más fácil de automatizar desde una cuenta de servicio. También significa que la conexión puede existir en un sitio y no en el otro, lo que confunde a quien mira en la lista equivocada.
rasdial "Work VPN" user pass
Get-VpnConnection -Name "Work VPN" | Select-Object ConnectionStatus
Use la superficie de PowerShell cuando necesite crear o quitar la entrada en lugar de marcarla. Las capas WMI y cmdlet exponen los mismos objetos con nombres distintos, y la eliminación es una operación separada de la desconexión. Un script que solo marca dejará entradas obsoletas después de una migración. Compruebe en qué almacén escribe su automatización antes de prometer que la limpieza ocurre.
Remove-VpnConnection -Name "Old VPN" -Force
Get-VpnConnection
En macOS el equivalente es la lista de servicios de red, donde un servicio existente se conecta por su nombre en lugar de crearse sobre la marcha.
Las credenciales se filtran en cada capa, así que elija el canal
Todo lo que pasa por la línea de comandos aparece en la tabla de procesos para cada usuario local, y normalmente también sobrevive en el historial del shell. La alternativa compatible de OpenVPN es leer el secreto desde un archivo con --askpass, y el archivo en sí necesita permisos que coincidan con la confianza que deposita en él. Una tubería con nombre evita escribir el secreto en el disco pero permite que cualquier proceso capaz de abrirla escriba allí. En Windows, guarde el secreto en el administrador de credenciales, o en un archivo que solo la cuenta de servicio pueda leer, y nunca como literal en un archivo batch.
openvpn --config /etc/openvpn/work.conf --askpass /etc/openvpn/work.secret --auth-nocache --daemon
ls -l /etc/openvpn/work.secret
La misma regla se aplica a los tokens y a los códigos de un solo uso: si la automatización los necesita, la automatización necesita un canal que no sea un argumento de línea de comandos. Rote el secreto cuando cambie el mecanismo, porque el valor antiguo ha estado en un registro en algún sitio. Un script que funciona y filtra no es un script que funcione.
Espere el estado y luego supervise a un solo propietario
Cada una de estas llamadas vuelve antes de que el túnel esté listo, así que sondee el estado que expone el cliente o pruebe un destino dentro de él con un tiempo de espera. Copiar archivos o abrir una conexión de base de datos justo después de la llamada de conexión es una carrera, y falla de forma intermitente de un modo que parece un fallo de red.
ip link show tun0
nmcli -t -f GENERAL.STATE connection show "Work VPN"
curl -sS --max-time 5 https://app.internal.example/health -o /dev/null
La desconexión tiene el mismo problema al revés: el proceso puede terminar antes de que las rutas hayan desaparecido. Use los hooks del cliente donde existan, como los scripts up y down de OpenVPN o el ExecStartPost de una unidad systemd, porque se ejecutan en el punto que de verdad le importa. Los hooks se ejecutan con los privilegios de quien los invocó, así que un hook que reinicia la red necesita una regla explícita en lugar de una suposición. Mantenga exactamente un propietario durante la vida de la conexión.
Cuando dos supervisores arrancan y paran el mismo perfil, el resultado es un bucle de reconexión que se lee como una caída del proveedor. El runbook termina cuando la capa está documentada, el secreto tiene un canal que no es argv, la condición de espera es una comprobación de estado con tiempo de espera, y un solo proceso posee el ciclo de vida.