Tres cousas deciden que fonte de credenciais debe usar: se hai unha persoa sentada na consola, se o segredo pode vivir no disco e se outro proceso debe responder á solicitude. Se escolle mal, o cliente informa dun problema con stdin mentres o contrasinal é perfectamente válido, o que envía a maioría da xente ao servidor sen motivo. Escolla primeiro a ruta; as mensaxes de erro só teñen sentido cando sabe que ruta as produciu.

As tres condicións que o deciden

A solicitude da consola é a única ruta que necesita unha persoa, así que é a única que falla en silencio dentro dunha unidade systemd ou un contedor. Se unha persoa inicia o cliente e escribe o contrasinal, non intervén ningún ficheiro e nada sensíbel acaba no disco. Se o cliente arrinca no inicio, esa mesma solicitude convértese nun bloqueo, e o tempo de espera adoita aparecer como un fallo de conexión xenérico en lugar dun erro de credenciais.

Un ficheiro de credenciais é a resposta correcta cando o proceso arrinca sen supervisión e o segredo pode sobrevivir no disco baixo un conxunto de permisos controlado. Cando o segredo non debe escribirse en absoluto - unha política só de almacén, un token de curta duración - necesita un fluxo que o cliente poida abrir, o que na práctica significa substitución de proceso ou un axudante que escribe nun descritor de ficheiro. A interface de xestión cobre o cuarto caso: un controlador que xa xestiona o ciclo de vida do túnel e pode responder preguntas por un socket.

  • Persoa na consola, sen automatización: solicitude interactiva.
  • Inicio sen supervisión, o segredo pode almacenarse: ficheiro de credenciais con modo 0600.
  • Inicio sen supervisión, o segredo non pode almacenarse: substitución de proceso ou un fd escrito por un axente de segredos.
  • Outro proceso é dono do cliente: interface de xestión.

Cando encaixan dúas respostas, prefira a que mantén o segredo fóra de argv e fóra do historial do shell. Un contrasinal pasado como argumento de programa é lexíbel por calquera usuario local a través da lista de procesos, e esa exposición é difícil de desfacer.

Que fai realmente cada ruta de entrada

--auth-user-pass por si só pide un nome de usuario e un contrasinal na consola. Cun nome de ficheiro, o cliente toma a primeira liña como nome de usuario e a segunda como contrasinal; nada admite comiñas, comentarios nin sintaxe clave-valor. Ese é todo o formato, así que quen o edite esperando un ficheiro INI rompeo. Un bloque <auth-user-pass> en liña contén esas mesmas dúas liñas dentro do perfil, o que converte o perfil nun segredo e o sitúa na mesma clase de manexo que unha chave privada.

As outras dúas rutas son un fluxo e un socket. OpenVPN só necesita un descritor de ficheiro lexíbel, así que aceptará unha substitución de proceso, unha entrada /dev/fd apoiada por unha tubaxe ou un nome de ficheiro que en realidade é un FIFO. A interface de xestión é distinta por natureza: o cliente pide os valores a un proceso supervisor en lugar de lelos el mesmo. Esa diferenza importa ao reconectar: un ficheiro de credenciais, un FIFO no que un axudante de segredos pode volver escribir e a interface de xestión poden volver fornecer sen unha persoa; a substitución de proceso non, porque o descritor consómese na primeira lectura.

O ficheiro ten que ser exactamente de dúas liñas

Dous modos de fallo cobren a maioría dos ficheiros de credenciais rotos. Un editor de Windows deixa finais CRLF, o retorno de carro pasa a formar parte do contrasinal e o servidor rexeita un valor que parece correcto na pantalla. Unha segunda liña en branco - unha liña baleira onde debería estar o contrasinal - deixa o cliente cun contrasinal baleiro, que o servidor rexeita aínda que o valor na pantalla pareza correcto. Un salto de liña final despois do contrasinal é inofensivo. Escriba o ficheiro desde o shell, non desde un editor, e comprobe os bytes:

install -m 600 /dev/null /etc/openvpn/client.creds
printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS" > /etc/openvpn/client.creds
od -c /etc/openvpn/client.creds | head -3

A ruta importa tanto como o contido. Unha ruta relativa resólvese contra o directorio de traballo do proceso, que para un servizo raramente é o directorio onde probou. Use unha ruta absoluta, faga que o ficheiro sexa propiedade da conta que executa o cliente e manteña o modo 0600 para que o grupo e os demais non poidan lelo. O manual de OpenVPN 2.6 enumera as formas aceptadas da directiva; consúlteo antes de inventar unha terceira.

Probe o ficheiro antes de culpar o servidor. Executar openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 imprime se se abriu o ficheiro e, despois, se se aceptaron as credenciais, o que lle di que capa cambiar a continuación.

Fluxos, stdin e os erros que producen

Pasar o contrasinal por unha tubaxe é o primeiro que proba a maioría e a ruta con máis sorpresas. A substitución de proceso funciona porque o cliente só necesita un descritor lexíbel: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). Pasar /dev/stdin só funciona cando stdin segue aberto e lexíbel no momento en que o cliente pregunta, o que non se cumpre nunha tubaxe que xa o consumiu.

ERROR: could not read Auth username from stdin ten dúas causas distintas. Nalgúns clientes 2.3.x a mensaxe viña dun defecto de manexo de stdin que as versións 2.3 posteriores corrixiron, así que un cliente tan antigo só mellora actualizando. Nun cliente actual a mesma redacción significa que o cliente pediu entrada de consola e que stdin non era un terminal - exactamente a situación nunha unidade systemd, unha tarefa cron ou un contedor iniciado sen -t.

auth-nocache engade un terceiro bucle que parece un contrasinal roto. Descarta as credenciais da memoria tras o seu uso, así que unha reconexión provocada por un cambio de rede non ten nada que reproducir e a solicitude volve. Eso é a directiva funcionando como se deseñou. auth-nocache cambia o que o cliente garda en memoria, non o que o servidor ou o provedor de identidade pensa da conta, así que toda a solución é volver fornecer o mesmo ficheiro, relido ao reiniciar - e para unha conexión xestionada ese fornecemento debería vir do almacén de segredos aprobado, non dun contrasinal nun script.

A interface de xestión cando outro proceso é dono da solicitude

Un controlador que xa supervisa o túnel tamén pode responder ás súas preguntas. Inicie o cliente con --management 127.0.0.1 7505, lea as liñas de estado e vixie >PASSWORD:Need 'Auth' username/password. O controlador responde con username "Auth" alice seguido de password "Auth" ... en liñas de orde separadas. O token 'Auth' fai eco do identificador da petición e ten que coincidir, ou a resposta ignórase e o cliente espera.

O custo é unha máquina de estados que agora posúe: orde de conexións, reinicios do cliente e un socket local que outros usuarios do host non deben alcanzar. O que compra é unha credencial fornecida en tempo de execución, sen ficheiro no disco e sen unha solicitude que se poida bloquear. Se nada máis da súa pila xa fala o protocolo, esta ruta engade un compoñente que manter.

Fallos que parecen problemas de credenciais

Unha aperta de mans TLS que nunca se completa, ou un VERIFY ERROR: depth=0, error=certificate signature failure, é un problema de confianza e ocorre antes de que se lea ningún nome de usuario. Un cliente proto tcp apuntado a un escoitador UDP falla no mesmo punto: os paquetes nunca chegan á fase de autenticación, así que todo contrasinal parece incorrecto por asociación. Manteña a verificación de certificados activada antes de enviar a credencial; unha solicitude familiar non di nada sobre quen recibe o contrasinal. Comprobe a cadea de certificados, o nome común e o transporte antes de tocar a credencial.

Os erros de shell no script que ensambla o perfil son o outro rastro falso. Un espazo que falta dentro de [ ! -f "$file" ] produce command not found, o script detense antes, o perfil nunca se reconstrúe e o cliente arrinca co anterior. Ese erro pertence ao shell, non á autenticación, e por moito que reescriba o contrasinal non o vai borrar.

Non toda solicitude neste fluxo é esta credencial. Unha frase de paso de chave privada, un inicio de sesión de proxy HTTP e o contrasinal do servizo son tres segredos distintos pedidos en fases diferentes, e unha frase de paso de chave adoita xestionala o cliente ou un axente en lugar de auth-user-pass. Se a solicitude aparece antes de que a sesión TLS estea en marcha, está a responder a pregunta equivocada e ningún restablecemento de conta axudará. Unha vez excluída a solicitude equivocada, as comprobacións restantes comezan pola capa máis temperá:

  • Lea o primeiro erro de protocolo, non a última liña de credenciais: TLS, despois autenticación, despois push.
  • Confirme que o ficheiro ten dúas liñas, non contén retornos de carro e se referencia cunha ruta absoluta.
  • Confirme que o perfil e a liña de ordes non discrepan sobre a directiva.
  • Separe "credenciais aceptadas" de "o tráfico flúe" - o encamiñamento e o DNS son unha capa posterior.

Cando o cliente chegue á fase push, deixe de mirar as credenciais e comece a ler as rutas e os servidores DNS que enviou o servidor. Ese é o seguinte problema, e non ten nada que ver co contrasinal que acaba de corrixir.

Artigos relacionados