Tres coses decideixen quina font de credencials heu d’utilitzar: si hi ha una persona asseguda a la consola, si el secret pot viure al disc i si un altre procés ha de respondre la sol·licitud. Si trieu malament, el client informa d’un problema amb stdin mentre la contrasenya és perfectament vàlida, cosa que envia la majoria de la gent al servidor sense cap motiu. Trieu primer el camí; els missatges d’error només tenen sentit quan sabeu quin camí els ha produït.

Les tres condicions que ho decideixen

La sol·licitud a la consola és l’únic camí que necessita una persona, així que és l’únic que falla en silenci dins d’una unitat systemd o un contenidor. Si una persona inicia el client i escriu la contrasenya, no hi intervé cap fitxer i res sensible no acaba al disc. Si el client s’inicia a l’arrencada, aquesta mateixa sol·licitud es converteix en una penjada, i el temps d’espera sol aparèixer com una fallada de connexió genèrica en lloc d’un error de credencials.

Un fitxer de credencials és la resposta correcta quan el procés s’inicia sense supervisió i el secret pot sobreviure al disc sota un conjunt de permisos controlat. Quan el secret no s’ha d’escriure de cap manera - una política només de magatzem, un testimoni de curta durada - necessiteu un flux que el client pugui obrir, cosa que a la pràctica vol dir substitució de procés o un ajudant que escriu en un descriptor de fitxer. La interfície de gestió cobreix el quart cas: un controlador que ja gestiona el cicle de vida del túnel i pot respondre preguntes per un sòcol.

  • Persona a la consola, sense automatització: sol·licitud interactiva.
  • Inici sense supervisió, el secret es pot emmagatzemar: fitxer de credencials amb mode 0600.
  • Inici sense supervisió, el secret no es pot emmagatzemar: substitució de procés o un fd escrit per un agent de secrets.
  • Un altre procés és propietari del client: interfície de gestió.

Quan dues respostes encaixen, preferiu la que manté el secret fora d’argv i fora de l’historial del shell. Una contrasenya passada com a argument de programa és llegible per qualsevol usuari local a través de la llista de processos, i aquesta exposició és difícil de desfer.

Què fa realment cada camí d’entrada

--auth-user-pass tot sol demana un nom d’usuari i una contrasenya a la consola. Si li doneu un nom de fitxer, el client pren la primera línia com a nom d’usuari i la segona com a contrasenya; res no admet cometes, comentaris ni sintaxi clau-valor. Aquest és tot el format, així que qui l’edita esperant un fitxer INI el trenca. Un bloc <auth-user-pass> en línia conté les mateixes dues línies dins del perfil, cosa que converteix el perfil mateix en un secret i el posa a la mateixa classe de tractament que una clau privada.

Els altres dos camins són un flux i un sòcol. OpenVPN només necessita un descriptor de fitxer llegible, així que acceptarà una substitució de procés, una entrada /dev/fd amb canonada al darrere o un nom de fitxer que en realitat és un FIFO. La interfície de gestió és diferent de naturalesa: el client demana els valors a un procés supervisor en lloc de llegir-los ell mateix. Aquesta diferència importa en reconnectar: un fitxer de credencials, un FIFO que un ajudant de secrets pot tornar a escriure i la interfície de gestió poden tornar a subministrar sense cap persona; la substitució de procés no, perquè el descriptor es consumeix a la primera lectura.

El fitxer ha de ser exactament de dues línies

Dos modes de fallada cobreixen la majoria de fitxers de credencials trencats. Un editor de Windows deixa finals CRLF, el retorn de carro passa a formar part de la contrasenya, i el servidor rebutja un valor que a la pantalla sembla correcte. Una segona línia en blanc - una línia buida on hauria de ser la contrasenya - deixa el client amb una contrasenya buida, que el servidor rebutja encara que el valor a la pantalla sembli correcte. Un salt de línia final després de la contrasenya no fa mal. Escriviu el fitxer des del shell, no des d’un editor, i comproveu els 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

El camí importa tant com el contingut. Un camí relatiu es resol contra el directori de treball del procés, que per a un servei poques vegades és el directori on vau provar. Feu servir un camí absolut, feu que el fitxer sigui propietat del compte que executa el client i manteniu el mode 0600 perquè el grup i els altres no el puguin llegir. El manual d’OpenVPN 2.6 llista les formes acceptades de la directiva; consulteu-lo abans d’inventar-ne una tercera.

Proveu el fitxer abans de culpar el servidor. Executar openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 imprimeix si el fitxer s’ha obert i, després, si les credencials s’han acceptat, cosa que us diu quina capa cal canviar a continuació.

Fluxos, stdin i els errors que produeixen

Passar la contrasenya per una canonada és el primer que prova la majoria de la gent i el camí amb més sorpreses. La substitució de procés funciona perquè el client només necessita un descriptor llegible: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). Passar /dev/stdin només funciona quan stdin encara és obert i llegible en el moment que el client pregunta, cosa que no és certa en una canonada que ja l’ha consumit.

ERROR: could not read Auth username from stdin té dues causes diferents. En alguns clients 2.3.x el missatge venia d’un defecte de gestió de stdin que les versions 2.3 posteriors van corregir, així que un client tan antic només millora actualitzant. En un client actual la mateixa redacció vol dir que el client ha demanat entrada de consola i que stdin no era un terminal - exactament la situació en una unitat systemd, una tasca cron o un contenidor iniciat sense -t.

auth-nocache afegeix un tercer bucle que sembla una contrasenya trencada. Descarta les credencials de la memòria després de l’ús, així que una reconnexió provocada per un canvi de xarxa no té res per tornar a reproduir i la sol·licitud torna. Aquesta és la directiva funcionant tal com està dissenyada. auth-nocache canvia el que el client guarda en memòria, no el que el servidor o el proveïdor d’identitat pensa del compte, així que tota la solució és tornar a subministrar el mateix fitxer, rellegit en reiniciar - i per a una connexió gestionada aquest subministrament hauria de venir del magatzem de secrets aprovat, no d’una contrasenya en un script.

La interfície de gestió quan un altre procés és amo de la sol·licitud

Un controlador que ja supervisa el túnel també pot respondre les seves preguntes. Inicieu el client amb --management 127.0.0.1 7505, llegiu les línies d’estat i vigileu >PASSWORD:Need 'Auth' username/password. El controlador respon amb username "Auth" alice seguit de password "Auth" ... en línies d’ordre separades. El testimoni 'Auth' fa eco de l’identificador de la petició i ha de coincidir, o la resposta s’ignora i el client espera.

El cost és una màquina d’estats que ara teniu: ordre de connexions, reinicis del client i un sòcol local que altres usuaris de l’amfitrió no han d’abastar. El que compreu és una credencial subministrada en temps d’execució, sense fitxer al disc i sense cap sol·licitud que es pugui penjar. Si res més de la vostra pila ja no parla el protocol, aquest camí afegeix un component a mantenir.

Fallades que semblen problemes de credencials

Un intercanvi TLS que mai no acaba, o un VERIFY ERROR: depth=0, error=certificate signature failure, és un problema de confiança i passa abans que es llegeixi cap nom d’usuari. Un client proto tcp apuntat a un oient UDP falla al mateix lloc: els paquets no arriben mai a l’etapa d’autenticació, així que tota contrasenya sembla incorrecta per associació. Manteniu la verificació de certificats activada abans que s’enviï la credencial; una sol·licitud familiar no diu res sobre qui rep la contrasenya. Comproveu la cadena de certificats, el nom comú i el transport abans de tocar la credencial.

Els errors de shell al script que munta el perfil són l’altre rastre fals. Un espai que falta dins de [ ! -f "$file" ] produeix command not found, el script s’atura aviat, el perfil no es torna a construir i el client s’inicia amb l’anterior. Aquest error pertany al shell, no a l’autenticació, i no hi ha manera de reescriure la contrasenya que l’esborri.

No tota sol·licitud en aquest flux és aquesta credencial. Una frase de pas de clau privada, un inici de sessió de proxy HTTP i la contrasenya del servei són tres secrets diferents demanats en fases diferents, i una frase de pas de clau normalment la gestiona el client o un agent en lloc d’auth-user-pass. Si la sol·licitud apareix abans que la sessió TLS estigui en marxa, esteu responent la pregunta equivocada i cap restabliment de compte no ajudarà. Un cop exclosa la sol·licitud equivocada, les comprovacions restants comencen per la capa més primerenca:

  • Llegiu el primer error de protocol, no l’última línia de credencials: TLS, després autenticació, després push.
  • Confirmeu que el fitxer és de dues línies, no té retorns de carro i es referencia amb un camí absolut.
  • Confirmeu que el perfil i la línia d’ordres no es contradiuen sobre la directiva.
  • Separeu "credencials acceptades" de "el trànsit flueix" - l’encaminament i el DNS són una capa posterior.

Quan el client arriba a la fase push, deixeu de mirar les credencials i comenceu a llegir les rutes i els servidors DNS que ha enviat el servidor. Aquest és el problema següent, i no té res a veure amb la contrasenya que acabeu de corregir.

Articles relacionats