Un script que inicia OpenVPN e nunca conecta non adoita ser un problema de rede: o cliente está ante unha solicitude sen un terminal onde debuxala. OpenVPN ten exactamente dúas formas admitidas de responder esa solicitude sen unha persoa, un ficheiro de credenciais detrás de auth-user-pass e o socket de xestión, e non son intercambiables. O ficheiro custa unha directiva e responde unha solicitude; o socket responde todas as solicitudes e entrega a calquera cousa que poida abrir un porto loopback unha canle de control non autenticada. Cal dos dous pertence ao teu despregamento depende de que solicitude está realmente bloqueando e de que segredo podes permitirte deixar en repouso.

Nomea a solicitude antes de escoller un mecanismo

Catro solicitudes parecen idénticas nun terminal. O par de conta vén da configuración PAM ou auth-user-pass-verify do servidor e respóndea auth-user-pass. A frase de contrasinal dunha clave privada pertence ao ficheiro de clave e lese con --askpass ou escríbese a man. Un paquete PKCS#12 pide un contrasinal propio. A autenticación de proxy usa o ficheiro auth que toma --http-proxy, non as credenciais da conta.

Cando OpenVPN se executa como fillo de systemd, PHP ou Node non hai terminal, así que calquera destas bloquea en silencio. O proceso queda alí, o rexistro detense tras a liña de cifrado e a unidade acaba esgotando o tempo; ese silencio é a razón pola que a xente engade un bucle de reintento ou un sleep en vez de mirar que solicitude está pendente. Só o socket de xestión pode responder as catro. O ficheiro de credenciais responde a primeira e nada máis.

auth-user-pass: un ficheiro, unha solicitude

O ficheiro garda o nome de usuario na liña un e o contrasinal na liña dous, e nada máis: sen comiñas, sen nomes de clave, sen comentario. Pon o modo 600 e fai propietario á conta que executa openvpn, que para un servizo adoita ser un usuario dedicado e non o teu inicio de sesión. Un ficheiro propiedade de root baixo /root é a diferenza entre un comando que funciona na túa shell e unha unidade que falla ao arrincar.

Dous detalles converten un ficheiro correcto nunha solicitude. Un editor que garda CRLF deixa un retorno de carro pegado ao contrasinal, así que o servidor rexeita un contrasinal que no ficheiro parece correcto; compróbao con cat -A ou od -c en vez de a ollo. E un auth-user-pass sen argumento dentro do perfil significa «pregunta ao usuario» por deseño, algo que unha segunda directiva na liña de ordes pode que non anule, porque o perfil analízase onde está.

A orde das opcións é a terceira trampa, e depende da versión. Algunhas compilacións de OpenVPN 2.4 ignoran --auth-user-pass cando aparece antes de --config, así que as mesmas dúas opcións na outra orde conectan. Pon a directiva dentro do perfil, ou despois de --config na liña de ordes, e busca no perfil cada aparición antes de cambiar calquera outra cousa.

auth-nocache pertence a este mecanismo pero non achega nada. Limita canto tempo garda o cliente a credencial en memoria, o que axuda tras un fallo e nada en absoluto cando falta o ficheiro. Unha reconexión tras un tempo de espera de sesión no servidor volve ler o ficheiro, así que unha credencial que funcionou ao arrincar aínda pode caducar a metade do día.

O socket de xestión: todas as solicitudes, máis superficie

Inicia o cliente cun escoitador e declara explicitamente que as solicitudes se informarán nel, coas directivas documentadas no manual de OpenVPN 2.6:

management 127.0.0.1 3030
management-query-passwords

Desde bash, mantén a conexión nun descriptor de ficheiro libre e responde por nome de solicitude en vez de por posición, porque unha reconexión pode preguntar noutra orde:

exec 3<>/dev/tcp/127.0.0.1/3030
while read -r -u 3 line; do
  case "$line" in
    *"Need 'Auth' username/password"*)
      echo 'username "Auth" alice' >&3
      echo 'password "Auth" secret' >&3 ;;
    *"Need 'Private Key' password"*)
      echo 'password "Private Key" secret' >&3 ;;
  esac
done

A fronteira é o transporte. O protocolo de xestión é texto plano sobre TCP en loopback, así que o escoitador non debe publicarse nun enderezo de LAN ou de túnel para que un controlador remoto o alcance; un controlador remoto significa un reenvío SSH, non unha vinculación máis ampla. O daemon da comunidade tamén acepta un só cliente de xestión á vez, así que unha GUI ou un monitor non poden compartir o socket co teu script. A segunda conexión rexéitase, non se encola, e o fallo parece un script que quedou xordo.

Ese socket tamén é unha canle de control. Sen contrasinal de xestión, calquera cousa que poida conectarse a 127.0.0.1:3030 pode ler o estado, matar o túnel ou responder unha solicitude por si mesma. O contrasinal de xestión e o ficheiro de credenciais son segredos da mesma clase, e ambos merecen o mesmo coidado.

Cal encaixa co despregamento

Escolle o ficheiro de credenciais cando a única solicitude é o par de conta, o cliente se executa como servizo cun propietario estable e podes manter un ficheiro 600 fóra de copias de seguridade que non controlas. Escolle o socket de xestión cando hai unha frase de contrasinal de clave ou un contrasinal PKCS#12, cando o envoltorio xa supervisa o proceso ou cando necesitas vixiar estado e solicitudes mentres depuras unha reconexión.

Dúas condicións moven a decisión. Se o envoltorio é /bin/sh, unha unidade de systemd que chama o binario directamente ou un contedor mínimo, o pegamento de socket só para bash non está dispoñible e o ficheiro é a resposta máis barata. Se o segredo rota a miúdo, ningún ficheiro é un bo fogar para el: consulta un anel de chaves desde un envoltorio pequeno e deixa que a unidade chame o envoltorio, o que mantén a rotación nun só lugar e o contrasinal fóra do historial da shell.

A substitución de procesos está entre os dous e non pertence a ningún. A orde dunha liña de abaixo funciona porque bash a expande antes de que openvpn arrinque, non porque o cliente entenda a sintaxe:

openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")

Rómpese baixo /bin/sh, nunha unidade que evita a shell e en imaxes sen bash nin /dev/fd. Gárdao para probas interactivas, nunca como o contrato do que depende un servizo.

Protexe o segredo e despois verifica desde o rexistro

Ambos mecanismos deixan un segredo lexible polo proceso OpenVPN. Nunca poñas o contrasinal na liña de ordes nin no ficheiro da unidade, onde ps e systemctl o mostran a cada usuario local; pasa a ruta ao ficheiro, non o valor que contén. Onde os certificados poden substituír o par de conta, iso elimina a categoría de solicitude en vez de agochala.

Unha execución correcta mostra a secuencia de solicitudes completándose e a sesión alcanzando «Initialization Sequence Completed». Se o cliente se detén na mesma solicitude, a coincidencia fallou: imprime as liñas exactas que enviou o socket, comproba as comiñas e o nome da solicitude, e corrixe o patrón en vez de engadir un sleep. Un túnel que informa éxito e non transporta nada é un problema de encamiñamento ou de push, non de credenciais.

Despois proba a reconexión, non só o primeiro arrinque. Corta a sesión do servidor ou espera o seu tempo de espera; o cliente volve preguntar, e é aí onde un ficheiro que parecía correcto ao arrincar mostra se aínda é lexible pola conta que se reconecta.

Artigos relacionados