Skripta koja pokrene OpenVPN i nikad se ne poveže obično nije mrežni problem: klijent sjedi na upitu bez terminala na kojem bi ga prikazao. OpenVPN ima točno dva podržana načina da odgovori na taj upit bez čovjeka, datoteku vjerodajnica iza auth-user-pass i upravljački socket, i oni nisu zamjenjivi. Datoteka košta jednu direktivu i odgovara na jedan upit; socket odgovara na svaki upit i daje svemu što može otvoriti loopback port neautentificirani kontrolni kanal. Koji od njih pripada vašem postavljanju zavisi od toga koji upit zapravo blokira i kojoj tajni možete priuštiti da ostane u mirovanju.

Imenujte upit prije nego odaberete mehanizam

Četiri upita izgledaju jednako na terminalu. Par za račun dolazi iz poslužiteljeve postavke PAM ili auth-user-pass-verify i odgovara mu auth-user-pass. Lozinka privatnog ključa pripada datoteci ključa i čita se kroz --askpass ili upisuje ručno. Paket PKCS#12 traži vlastitu lozinku. Proxy autentifikacija koristi auth datoteku koju uzima --http-proxy, ne vjerodajnice računa.

Kad OpenVPN radi kao dijete systemd, PHP ili Node, terminala nema, pa bilo koji od njih tiho blokira. Proces sjedi, zapisnik staje nakon retka šifre i jedinica na kraju istekne; ta tišina je razlog zašto ljudi dodaju petlju ponovnog pokušaja ili sleep umjesto da pogledaju koji upit čeka. Samo upravljački socket može odgovoriti na sva četiri. Datoteka vjerodajnica odgovara na prvi i ni na što drugo.

auth-user-pass: jedna datoteka, jedan upit

Datoteka drži korisničko ime u prvom retku i lozinku u drugom, i ništa drugo: bez navodnika, bez imena ključeva, bez komentara. Postavite način 600 i učinite vlasnikom račun koji pokreće openvpn, što je za uslugu često namjenski korisnik, a ne vaša prijava. Datoteka u vlasništvu roota pod /root razlika je između naredbe koja radi u vašoj ljusci i jedinice koja padne pri podizanju.

Dva detalja pretvaraju ispravnu datoteku u upit. Uređivač koji sprema CRLF ostavlja vraćanje kolica zalijepljeno za lozinku, pa poslužitelj odbija lozinku koja u datoteci izgleda ispravno; provjerite s cat -A ili od -c, a ne okom. A auth-user-pass bez argumenta unutar profila znači «pitaj korisnika» po dizajnu, što druga direktiva u naredbenom retku možda neće nadjačati, jer se profil parsira tamo gdje stoji.

Redoslijed opcija treća je zamka i ovisi o verziji. Neke gradnje OpenVPN 2.4 ignoriraju --auth-user-pass kad se pojavi prije --config, pa se iste dvije opcije u drugom redoslijedu povezuju. Stavite direktivu u profil ili nakon --config u naredbenom retku i prije bilo čega drugog pretražite profil za svaku pojavu.

auth-nocache pripada ovom mehanizmu ali ništa ne daje. Ograničava koliko dugo klijent drži vjerodajnice u memoriji, što pomaže nakon pada i nimalo kad datoteka nedostaje. Ponovno povezivanje nakon isteka sesije na strani poslužitelja ponovno čita datoteku, pa vjerodajnice koje su radile pri podizanju mogu isteći sredinom dana.

Upravljački socket: svaki upit, više površine

Pokrenite klijent s osluškivačem i izričito navedite da će se upiti izvještavati na njemu, koristeći direktive dokumentirane u priručniku OpenVPN 2.6:

management 127.0.0.1 3030
management-query-passwords

Iz basha držite vezu na rezervnom opisniku datoteke i odgovarajte po imenu upita, a ne po položaju, jer ponovno povezivanje može pitati drugim redoslijedom:

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

Granica je prijevoz. Protokol upravljanja je čisti tekst preko TCP-a na loopbacku, pa se osluškivač ne smije objaviti na LAN ili adresi tunela da bi ga udaljeni kontroler dosegnuo; udaljeni kontroler znači SSH prosljeđivanje, ne šire vezivanje. Zajednički daemon također prihvaća jedan upravljački klijent odjednom, pa GUI ili monitor ne mogu dijeliti socket s vašom skriptom. Druga veza se odbija, ne stavlja u red, i kvar izgleda kao skripta koja je oglušila.

Taj socket je i kontrolni kanal. Bez upravljačke lozinke sve što se može spojiti na 127.0.0.1:3030 može čitati stanje, ubiti tunel ili samo odgovoriti na upit. Upravljačka lozinka i datoteka vjerodajnica ista su klasa tajne i obje zaslužuju istu pažnju.

Koji odgovara postavljanju

Odaberite datoteku vjerodajnica kad je jedini upit par za račun, klijent radi kao usluga sa stabilnim vlasnikom i možete držati datoteku 600 izvan sigurnosnih kopija koje ne kontrolirate. Odaberite upravljački socket kad je u igri lozinka ključa ili lozinka PKCS#12, kad omotač već nadzire proces ili kad trebate promatrati stanje i upite dok otklanjate greške u ponovnom povezivanju.

Dva uvjeta pomiču odluku. Ako je omotač /bin/sh, systemd jedinica koja izravno poziva binarnu datoteku ili minimalni kontejner, ljepilo za socket samo za bash nije dostupno i datoteka je jeftiniji odgovor. Ako se tajna često izmjenjuje, nijedna datoteka nije dobar dom za nju: zatražite privjesak ključeva iz malog omotača i pustite jedinicu da pozove omotač, što drži izmjenu na jednom mjestu, a lozinku izvan povijesti ljuske.

Zamjena procesa stoji između dvaju i ne pripada nijednom. Jednolinijski primjer dolje radi jer ga bash proširuje prije nego openvpn krene, a ne zato što klijent razumije sintaksu:

openvpn --config client.ovpn --auth-user-pass <(printf "%s
%s
" "$USER" "$PASS")

Lomi se pod /bin/sh, u jedinici koja zaobilazi ljusku i u slikama bez basha ili /dev/fd. Držite ga za interaktivno testiranje, nikad kao ugovor o kojem usluga ovisi.

Zaštitite tajnu, pa provjerite iz zapisnika

Oba mehanizma ostavljaju tajnu čitljivu OpenVPN procesu. Nikad ne stavljajte lozinku u naredbeni redak ili u datoteku jedinice, gdje je ps i systemctl pokazuju svakom lokalnom korisniku; predajte putanju do datoteke, ne vrijednost u njoj. Gdje certifikati mogu zamijeniti par za račun, to uklanja kategoriju upita umjesto da je skriva.

Ispravan rad pokazuje dovršetak slijeda upita i sesiju koja doseže «Initialization Sequence Completed». Ako se klijent zaustavi na istom upitu, podudaranje nije uspjelo: ispišite točne retke koje je socket poslao, provjerite navodnike i ime upita i popravite uzorak umjesto dodavanja sleepa. Tunel koji izvještava uspjeh i ne nosi ništa problem je usmjeravanja ili pusha, ne vjerodajnica.

Zatim testirajte ponovno povezivanje, ne samo prvo pokretanje. Prekinite sesiju na strani poslužitelja ili dočekajte njezin istek; klijent pita ponovno i upravo tu datoteka koja je izgledala ispravno pri podizanju pokazuje je li još čitljiva računu koji se ponovno povezuje.

Povezani članci