Súbor prihlasovacích údajov alebo riadiaci socket OpenVPN: čo skriptovať
auth-user-pass pokrýva výzvu účtu; riadiaci socket pokrýva všetky štyri. Porovnajte expozíciu, cenu skriptovania a ako každý zlyháva v službe.
Skript, ktorý spustí OpenVPN a nikdy sa nepripojí, zvyčajne nie je problém siete: klient sedí pri výzve bez terminálu, na ktorom by ju vykreslil. OpenVPN má presne dva podporované spôsoby, ako na túto výzvu odpovedať bez človeka, súbor prihlasovacích údajov za auth-user-pass a riadiaci socket, a nie sú zameniteľné. Súbor stojí jednu direktívu a odpovedá na jednu výzvu; socket odpovedá na každú výzvu a dá čomukoľvek, čo vie otvoriť loopback port, neautentizovaný riadiaci kanál. Ktorý patrí do vášho nasadenia, závisí od toho, ktorá výzva skutočne blokuje, a od toho, ktoré tajomstvo si môžete dovoliť nechať v pokoji.
Pomenujte výzvu, skôr než zvolíte mechanizmus
Štyri výzvy vyzerajú na termináli rovnako. Dvojica pre účet prichádza z nastavenia PAM alebo auth-user-pass-verify na serveri a odpovedá na ňu auth-user-pass. Heslová fráza súkromného kľúča patrí k súboru kľúča a číta sa cez --askpass alebo sa píše ručne. Balík PKCS#12 si pýta vlastné heslo. Proxy autentifikácia používa súbor auth, ktorý berie --http-proxy, nie prihlasovacie údaje účtu.
Keď OpenVPN beží ako potomok systemd, PHP alebo Node, nie je tam terminál, takže ktorákoľvek z nich ticho blokuje. Proces tam sedí, log sa zastaví po riadku šifry a jednotka nakoniec vyprší; to ticho je dôvod, prečo ľudia pridávajú slučku opakovania alebo sleep namiesto toho, aby sa pozreli, ktorá výzva čaká. Len riadiaci socket vie odpovedať na všetky štyri. Súbor prihlasovacích údajov odpovedá na prvú a na nič iné.
auth-user-pass: jeden súbor, jedna výzva
Súbor obsahuje používateľské meno na prvom riadku a heslo na druhom, a nič iné: žiadne úvodzovky, žiadne názvy kľúčov, žiadny komentár. Nastavte režim 600 a vlastníkom urobte účet, ktorý spúšťa openvpn, čo je pri službe často vyhradený používateľ, nie vaše prihlásenie. Súbor vlastnený rootom pod /root je rozdiel medzi príkazom, ktorý funguje vo vašom shelli, a jednotkou, ktorá pri štarte zlyhá.
Dva detaily premenia správny súbor na výzvu. Editor, ktorý ukladá CRLF, nechá návrat vozíka prilepený k heslu, takže server odmietne heslo, ktoré v súbore vyzerá správne; kontrolujte pomocou cat -A alebo od -c, nie okom. A auth-user-pass bez argumentu v profile znamená podľa návrhu «spýtaj sa používateľa», čo druhá direktíva na príkazovom riadku nemusí prepísať, pretože profil sa parsuje tam, kde leží.
Poradie volieb je tretia pasca a závisí od verzie. Niektoré zostavenia OpenVPN 2.4 ignorujú --auth-user-pass, keď sa objaví pred --config, takže tie isté dve voľby v opačnom poradí sa pripoja. Umiestnite direktívu do profilu alebo za --config na príkazovom riadku a pred akoukoľvek ďalšou zmenou prehľadajte profil na každý výskyt.
auth-nocache patrí k tomuto mechanizmu, ale nič neposkytuje. Obmedzuje, ako dlho klient drží prihlasovacie údaje v pamäti, čo pomôže po páde a vôbec nie vtedy, keď súbor chýba. Opätovné pripojenie po vypršaní relácie na strane servera súbor znova načíta, takže prihlasovacie údaje, ktoré fungovali pri štarte, môžu predsa vypršať uprostred dňa.
Riadiaci socket: každá výzva, väčší povrch
Spustite klienta s poslucháčom a výslovne uveďte, že výzvy sa budú hlásiť na ňom, pomocou direktív dokumentovaných v manuáli OpenVPN 2.6:
management 127.0.0.1 3030
management-query-passwords
V bashi držte spojenie na voľnom deskriptore súboru a odpovedajte podľa názvu výzvy, nie podľa pozície, pretože opätovné pripojenie sa môže spýtať v inom poradí:
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
Hranicou je prenos. Riadiaci protokol je čistý text cez TCP na loopbacku, takže poslucháč nesmie byť publikovaný na adrese LAN alebo tunela, aby sa k nemu dostal vzdialený správca; vzdialený správca znamená SSH presmerovanie, nie širšie naviazanie. Komunitný démon tiež prijíma len jedného riadiaceho klienta naraz, takže GUI alebo monitor nemôžu zdieľať socket s vaším skriptom. Druhé spojenie je odmietnuté, nie zaradené do fronty, a zlyhanie vyzerá ako skript, ktorý ohluchol.
Tento socket je aj riadiaci kanál. Bez riadiaceho hesla môže čokoľvek, čo sa vie pripojiť k 127.0.0.1:3030, čítať stav, zabiť tunel alebo samo odpovedať na výzvu. Riadiace heslo a súbor prihlasovacích údajov sú tajomstvá rovnakej triedy a obe si zaslúžia rovnakú starostlivosť.
Ktorý sa hodí k nasadeniu
Zvoľte súbor prihlasovacích údajov, keď je jedinou výzvou dvojica pre účet, klient beží ako služba so stabilným vlastníkom a môžete držať súbor 600 mimo záloh, ktoré nekontrolujete. Zvoľte riadiaci socket, keď je v hre heslová fráza kľúča alebo heslo PKCS#12, keď obal už proces dohliada, alebo keď potrebujete sledovať stav a výzvy pri ladení opätovného pripojenia.
Dve podmienky hýbu rozhodnutím. Ak je obalom /bin/sh, jednotka systemd, ktorá volá binárku priamo, alebo minimálny kontajner, lepidlo socketu len pre bash nie je k dispozícii a súbor je lacnejšia odpoveď. Ak sa tajomstvo často mení, ani jeden súbor preň nie je dobrým domovom: vyžiadajte kľúčenku z malého obalu a nechajte jednotku volať obal, čo drží rotáciu na jednom mieste a heslo mimo histórie shellu.
Nahradenie procesu stojí medzi oboma a nepatrí ani jednému. Jednoriadkový príkaz nižšie funguje, pretože ho bash rozvinie pred spustením openvpn, nie preto, že by klient rozumel syntaxi:
openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")
Zlyháva pod /bin/sh, v jednotke, ktorá obchádza shell, a v obrazoch bez bashe alebo /dev/fd. Ponechajte ho na interaktívne testovanie, nikdy ako zmluvu, na ktorej služba závisí.
Chráňte tajomstvo, potom overte z logu
Oba mechanizmy zanechávajú tajomstvo čitateľné pre proces OpenVPN. Nikdy nedávajte heslo na príkazový riadok ani do súboru jednotky, kde ho ps a systemctl ukážu každému miestnemu používateľovi; odovzdajte cestu k súboru, nie hodnotu v ňom. Tam, kde certifikáty môžu nahradiť dvojicu pre účet, to odstraňuje kategóriu výzvy namiesto jej skrývania.
Správny beh ukazuje dokončenie sledu výziev a reláciu dosahujúcu «Initialization Sequence Completed». Ak sa klient zastaví na tej istej výzve, porovnanie zlyhalo: vytlačte presné riadky, ktoré socket poslal, skontrolujte úvodzovky a názov výzvy a opravte vzor namiesto pridania sleepu. Tunel, ktorý hlási úspech a nič neprenáša, je problém smerovania alebo push, nie prihlasovacích údajov.
Potom otestujte opätovné pripojenie, nielen prvý štart. Zrušte reláciu na strane servera alebo počkajte na jej vypršanie; klient sa spýta znova, a práve tam súbor, ktorý pri štarte vyzeral správne, ukáže, či je pre účet, ktorý sa znova pripája, stále čitateľný.