OpenVPN citește parola din terminal, nu din stdin
Unde citește OpenVPN de fapt o parolă, de ce eșuează un fișier pe stdin și cele trei căi acceptate pentru autentificare din script pe Linux și macOS.
OpenVPN cere un nume de utilizator și o parolă pe terminalul de control, iar un fișier redirecționat către intrarea standard nu este acel terminal. Acest singur detaliu explică scriptul care se blochează deși parola stă chiar acolo în conductă. Promptul este desenat de client, iar citirea se face din dispozitivul de terminal, așa că redirecționarea stdin nu schimbă nimic. Alimentează clientul printr-una dintre căile de intrare documentate și același script se conectează din prima încercare.
Trei căi acoperă aproape toate cazurile, și fiecare eșuează în felul ei. Alege după promptul pe care clientul îl arată de fapt, nu după opțiunea cea mai ușor de pus într-un script.
Promptul nu vine din stdin
Când OpenVPN are nevoie de credențiale, deschide terminalul de control și citește acolo. De aceea un test interactiv arată bine, în timp ce aceeași comandă sub cron sau într-un fișier unit stă nemișcată cu promptul scris într-un jurnal pe care nimeni nu îl privește. Unele compilări revin la intrarea standard când nu există terminal, iar această inconsecvență e mai rea decât un eșec dur, pentru că ascunde problema până la implementare.
Verifică mediul înainte de a scrie orice cod: rulează clientul sub același utilizator, cu același stdin, cum va face planificatorul sau managerul de servicii. Dacă promptul nu apare niciodată în jurnal și procesul nu înaintează, ceva așteaptă un terminal care nu există.
Prima cale: un fișier de credențiale cu două linii
Opțiunea de autentificare ia o cale, iar fișierul conține exact două linii, întâi numele de utilizator, apoi parola, și nimic altceva. Dă calea explicit în loc să te bazezi pe un nume de fișier implicit, pentru că un fișier de credențiale rătăcit în directorul de lucru este felul în care ajunge în uz contul greșit. Setează modul la 0600 și dă proprietatea contului care rulează clientul.
Clientul citește fișierul o dată la pornire, deci rotirea parolei înseamnă repornirea procesului. De obicei acesta este comportamentul dorit, și îi este locul în runbook lângă procedura de rotire.
A doua cale: askpass pentru fraza cheii
O cheie privată protejată cu frază ridică un al doilea prompt, diferit, iar acesta are răspunsul lui dintr-un fișier: opțiunea askpass citește fraza din prima linie a unui fișier. Pentru tunelurile bazate pe SSH echivalentul este un program askpass pe care clientul îl execută, iar ieșirea lui standard devine secretul.
Niciuna dintre forme nu pune secretul în lista de argumente, iar ambele îl lasă să existe ca fișier sau ca executabil care îl tipărește. Protecția o constituie permisiunile fișierului și proprietatea procesului, nu obscuritatea. Un ajutor care repetă un șir scris în cod este un secret cu pași în plus.
A treia cale: CLI-ul propriu al clientului de portal
Clienții de întreprindere livrează de obicei un punct de intrare în linia de comandă care se conectează la un portal numit fără nicio fereastră, și aceasta este calea acceptată. Pe Linux clientul GlobalProtect expune operațiuni de conectare și de import de certificat prin CLI-ul său, iar portalurile care folosesc autentificare prin certificat au nevoie de pasul de import înainte ca o conectare automată să funcționeze. Preferă-l apăsărilor sintetice de taste: obții un cod de ieșire real, nicio dependență de focalizarea ferestrei, și supraviețuiește unui ecran blocat.
Dacă prima conectare mai are nevoie de un om care să accepte un certificat, automatizarea nu e terminată. Fă importul în timpul configurării și notează-l ca precondiție.
Când fluxul are nevoie de un pseudo-terminal
O secvență care cere o parolă și apoi un cod de unică folosință nu are un singur fișier de citit. Un driver de terminal ca Expect este instrumentul potrivit pentru că așteaptă pe rând fiecare model, și are nevoie de procesul pornit înainte de a putea potrivi ceva.
Două eșecuri domină. Un script care așteaptă un prompt fără să pornească clientul așteaptă la nesfârșit, iar Tcl nu este un shell, deci aritmetica de shell scrisă într-un bloc expect nu este evaluată așa cum se citește. Ține steagul de depanare aprins cât construiești modelele, apoi stinge-l.
Secrete care se scurg, și unde se ascund
Orice este transmis ca argument se vede în lista de procese, deci credențialele aparțin unui fișier sau unui ajutor, niciodată liniei de comandă. Codurile de unică folosință se consumă prin proiectare și trebuie produse pentru fiecare încercare. Jurnalele de eșec poartă adesea numele de utilizator și uneori mai mult, așa că cenzurează-le înainte de a le trimite oriunde, și ține secretul în afara profilului însuși, pentru că un fișier de configurare cu parolă încorporată ajunge lipit în tichete și în depozite. Rotirea contului înseamnă atunci vânarea fiecărei copii, și exact acesta este costul pe care îl evită această așezare.
Auditează căile alese, apoi leagă-le în fișierul unit sau în planificatorul care va rula efectiv clientul. Tunelul trăiește exact cât trăiește acel proces.