Trei lucruri decid ce sursă de acreditări să folosiți: dacă o persoană stă la consolă, dacă secretul poate trăi pe disc și dacă un alt proces trebuie să răspundă solicitării. Dacă alegeți greșit, clientul raportează o problemă cu stdin în timp ce parola este perfect valabilă, iar asta trimite majoritatea oamenilor la server fără motiv. Alegeți mai întâi calea; mesajele de eroare au sens doar după ce știți ce cale le-a produs.

Cele trei condiții care decid

Solicitarea din consolă este singura cale care are nevoie de o persoană, deci singura care eșuează în tăcere într-o unitate systemd sau într-un container. Dacă o persoană pornește clientul și tastează parola, nu este implicat niciun fișier și nimic sensibil nu ajunge pe disc. Dacă clientul pornește la boot, aceeași solicitare devine o blocare, iar timeout-ul apare de obicei ca o eroare generală de conexiune, nu ca o eroare de acreditări.

Un fișier de acreditări este răspunsul corect când procesul pornește fără supraveghere și secretul poate supraviețui pe disc sub un set controlat de permisiuni. Când secretul nu trebuie scris deloc - o politică doar cu seif, un token de scurtă durată - aveți nevoie de un flux pe care clientul îl poate deschide, ceea ce în practică înseamnă substituție de proces sau un ajutor care scrie într-un descriptor de fișier. Interfața de administrare acoperă al patrulea caz: un controler care deja gestionează ciclul de viață al tunelului și poate răspunde la întrebări printr-un socket.

  • Persoană la consolă, fără automatizare: solicitare interactivă.
  • Pornire fără supraveghere, secretul poate fi stocat: fișier de acreditări cu mod 0600.
  • Pornire fără supraveghere, secretul nu poate fi stocat: substituție de proces sau un fd în care scrie un agent de secrete.
  • Un alt proces deține clientul: interfața de administrare.

Când se potrivesc două răspunsuri, alegeți-l pe cel care ține secretul în afara argv și a istoricului shell-ului. O parolă transmisă ca argument de program este citibilă de orice utilizator local prin lista de procese, iar această expunere este greu de anulat.

Ce face de fapt fiecare cale de intrare

--auth-user-pass singur cere un nume de utilizator și o parolă la consolă. Cu un nume de fișier, clientul ia prima linie ca nume de utilizator și a doua ca parolă; nimic nu acceptă ghilimele, comentarii sau sintaxă cheie-valoare. Acesta este tot formatul, așa că cine îl editează așteptând un fișier INI îl strică. Un bloc <auth-user-pass> inline conține aceleași două linii în profil, ceea ce face profilul însuși un secret și îl pune în aceeași clasă de manipulare ca o cheie privată.

Celelalte două căi sunt un flux și un socket. OpenVPN are nevoie doar de un descriptor de fișier citibil, așa că va accepta o substituție de proces, o intrare /dev/fd susținută de un pipe sau un nume de fișier care este de fapt un FIFO. Interfața de administrare este diferită prin natură: clientul cere valorile unui proces supraveghetor în loc să le citească singur. Această diferență contează la reconectare: un fișier de acreditări, un FIFO în care un ajutor de secrete poate scrie din nou și interfața de administrare pot furniza din nou fără o persoană; substituția de proces nu poate, pentru că descriptorul este consumat la prima citire.

Fișierul trebuie să aibă exact două linii

Două moduri de eșec acoperă majoritatea fișierelor de acreditări stricate. Un editor Windows lasă terminații CRLF, returul de car este devine parte a parolei, iar serverul respinge o valoare care pare corectă pe ecran. O a doua linie goală - o linie goală acolo unde ar trebui să fie parola - lasă clientul cu o parolă goală, pe care serverul o respinge chiar dacă valoarea de pe ecran pare corectă. O linie nouă suplimentară după parolă este inofensivă. Scrieți fișierul din shell, nu dintr-un editor, și verificați octeții:

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

Calea contează la fel de mult ca conținutul. O cale relativă este rezolvată față de directorul de lucru al procesului, care pentru un serviciu este rar directorul în care ați testat. Folosiți o cale absolută, faceți fișierul proprietatea contului care rulează clientul și păstrați modul 0600 ca grupul și ceilalți să nu îl poată citi. Manualul OpenVPN 2.6 enumeră formele acceptate ale directivei; verificați-l înainte de a inventa una a treia.

Testați fișierul înainte de a da vina pe server. Rularea openvpn --config client.ovpn --auth-user-pass /etc/openvpn/client.creds --verb 4 afișează dacă fișierul a fost deschis și, mai târziu, dacă acreditările au fost acceptate, ceea ce vă spune ce strat să schimbați în continuare.

Fluxuri, stdin și erorile pe care le produc

Trimiterea parolei printr-un pipe este primul lucru pe care majoritatea o încearcă și calea cu cele mai multe surprize. Substituția de proces funcționează pentru că clientul are nevoie doar de un descriptor citibil: openvpn --config client.ovpn --verb 3 --auth-user-pass <(printf '%s\n%s\n' "$VPN_USER" "$VPN_PASS"). Transmiterea /dev/stdin funcționează doar când stdin este încă deschis și citibil în momentul în care clientul întreabă, ceea ce nu este adevărat într-un pipeline care l-a consumat deja.

ERROR: could not read Auth username from stdin are două cauze diferite. La unii clienți 2.3.x mesajul venea dintr-un defect de tratare a stdin pe care versiunile 2.3 ulterioare l-au corectat, așa că un client atât de vechi se îmbunătățește doar prin actualizare. La un client actual aceeași formulare înseamnă că clientul a cerut intrare de consolă și stdin nu era un terminal - exact situația dintr-o unitate systemd, un job cron sau un container pornit fără -t.

auth-nocache adaugă un al treilea ciclu care arată ca o parolă stricată. Arunca acreditările din memorie după utilizare, așa că o reconectare declanșată de o schimbare de rețea nu are ce să redea și solicitarea revine. Aceasta este directiva care funcționează conform proiectării. auth-nocache schimbă ce păstrează clientul în memorie, nu ce crede serverul sau furnizorul de identitate despre cont, așa că întreaga remediere este să furnizați din nou același fișier, recitit la repornire - iar pentru o conexiune gestionată acea furnizare ar trebui să vină din depozitul de secrete aprobat, nu dintr-o parolă într-un script.

Interfața de administrare când un alt proces deține solicitarea

Un controler care deja supraveghează tunelul poate răspunde și la întrebările lui. Porniți clientul cu --management 127.0.0.1 7505, citiți liniile de stare și urmăriți >PASSWORD:Need 'Auth' username/password. Controlerul răspunde cu username "Auth" alice urmat de password "Auth" ... pe linii de comandă separate. Tokenul 'Auth' repetă identificatorul din cerere și trebuie să corespundă, altfel răspunsul este ignorat și clientul așteaptă.

Costul este o mașină de stări pe care o dețineți acum: ordinea conexiunilor, repornirile clientului și un socket local la care ceilalți utilizatori de pe gazdă nu trebuie să ajungă. Ce cumpărați este o acreditare furnizată la momentul execuției, fără fișier pe disc și fără o solicitare care se poate bloca. Dacă nimic altceva din stiva dumneavoastră nu vorbește deja protocolul, această cale adaugă o componentă de întreținut.

Eșecuri care par probleme de acreditări

Un handshake TLS care nu se termină niciodată, sau un VERIFY ERROR: depth=0, error=certificate signature failure, este o problemă de încredere și apare înainte de a fi citit orice nume de utilizator. Un client proto tcp îndreptat spre un ascultător UDP eșuează în același punct: pachetele nu ajung niciodată la faza de autentificare, așa că fiecare parolă pare greșită prin asociere. Păstrați verificarea certificatelor pornită înainte ca acreditarea să fie trimisă; o solicitare familiară nu spune nimic despre cine primește parola. Verificați lanțul de certificate, numele comun și transportul înainte de a atinge acreditarea.

Erorile de shell din scriptul care asamblează profilul sunt cealaltă pistă falsă. Un spațiu lipsă în [ ! -f "$file" ] produce command not found, scriptul se oprește devreme, profilul nu este niciodată reconstruit, iar clientul pornește cu cel anterior. Acea eroare aparține shell-ului, nu autentificării, și indiferent de câte ori rescrieți parola, nu o va șterge.

Nu fiecare solicitare din acest flux este această acreditare. O frază de acces pentru o cheie privată, o autentificare prin proxy HTTP și parola serviciului sunt trei secrete diferite cerute în faze diferite, iar o frază de acces pentru cheie este de obicei gestionată de client sau de un agent în loc de auth-user-pass. Dacă solicitarea apare înainte ca sesiunea TLS să fie stabilită, răspundeți la întrebarea greșită și nicio resetare a contului nu va ajuta. După ce solicitarea greșită este exclusă, verificările rămase încep de la cel mai timpuriu strat:

  • Citiți prima eroare de protocol, nu ultima linie de acreditări: TLS, apoi autentificare, apoi push.
  • Confirmați că fișierul are două linii, nu conține retururi de car și este referit printr-o cale absolută.
  • Confirmați că profilul și linia de comandă nu sunt în dezacord cu privire la directivă.
  • Separați "acreditări acceptate" de "traficul curge" - rutarea și DNS sunt un strat ulterior.

Când clientul ajunge în faza push, opriți-vă din a privi acreditările și începeți să citiți rutele și serverele DNS pe care le-a trimis serverul. Aceea este următoarea problemă și nu are nimic de-a face cu parola pe care tocmai ați corectat-o.

Articole similare