Scenarijus, kuris paleidžia OpenVPN ir niekada neprisijungia, paprastai nėra tinklo problema: klientas sėdi prie užklausos be terminalo, kuriame ją nupieštų. OpenVPN turi lygiai du palaikomus būdus atsakyti į tą užklausą be žmogaus: kredencialų failą už auth-user-pass ir valdymo lizdą, ir jie nėra keičiami. Failas kainuoja vieną direktyvą ir atsako į vieną užklausą; lizdas atsako į kiekvieną užklausą ir suteikia bet kam, kas gali atidaryti loopback prievadą, neautentifikuotą valdymo kanalą. Kuris priklauso jūsų diegimui, priklauso nuo to, kuri užklausa iš tikrųjų blokuoja, ir nuo to, kokią paslaptį galite sau leisti palikti ramybėje.

Įvardykite užklausą prieš rinkdamiesi mechanizmą

Keturios užklausos terminale atrodo vienodai. Paskyros pora ateina iš serverio PAM arba auth-user-pass-verify nustatymo ir į ją atsako auth-user-pass. Privataus rakto slaptafrazė priklauso rakto failui ir nuskaitoma per --askpass arba įvedama ranka. PKCS#12 paketas prašo savo slaptažodžio. Tarpinio serverio autentifikacija naudoja auth failą, kurį ima --http-proxy, o ne paskyros kredencialus.

Kai OpenVPN veikia kaip systemd, PHP arba Node vaikas, terminalo nėra, todėl bet kuri iš jų tyliai blokuoja. Procesas sėdi, žurnalas sustoja po šifro eilutės, o vienetas galiausiai viršija laiką; ta tyla yra priežastis, kodėl žmonės prideda kartojimo ciklą arba sleep, o ne žiūri, kuri užklausa laukia. Į visas keturias gali atsakyti tik valdymo lizdas. Kredencialų failas atsako į pirmąją ir į nieką daugiau.

auth-user-pass: vienas failas, viena užklausa

Failas turi vartotojo vardą pirmoje eilutėje ir slaptažodį antroje, ir nieko daugiau: jokių kabučių, jokių raktų vardų, jokio komentaro. Nustatykite 600 režimą ir padarykite savininku paskyrą, kuri paleidžia openvpn, o tai paslaugai dažnai yra atskiras vartotojas, o ne jūsų prisijungimas. Root priklausantis failas po /root yra skirtumas tarp komandos, kuri veikia jūsų apvalkale, ir vieneto, kuris nepavyksta įkrovimo metu.

Dvi smulkmenos paverčia teisingą failą užklausa. Redaktorius, kuris įrašo CRLF, palieka prie slaptažodžio priklijuotą vežimėlio grąžinimą, todėl serveris atmeta slaptažodį, kuris faile atrodo teisingas; tikrinkite su cat -A arba od -c, o ne akimis. O profilio viduje esantis auth-user-pass be argumento pagal dizainą reiškia «paklausk vartotojo», ko antroji direktyva komandų eilutėje gali ir neperrašyti, nes profilis analizuojamas ten, kur jis yra.

Parinkčių tvarka yra trečias spąstas, ir ji priklauso nuo versijos. Kai kurie OpenVPN 2.4 rinkiniai nepaiso --auth-user-pass, kai jis yra prieš --config, todėl tos pačios dvi parinktys kita tvarka prisijungia. Įdėkite direktyvą į profilį arba po --config komandų eilutėje ir prieš ką nors keisdami grep'inkite profilį dėl kiekvieno pasitaikymo.

auth-nocache priklauso šiam mechanizmui, bet nieko nesuteikia. Jis riboja, kiek laiko klientas laiko kredencialus atmintyje, kas padeda po lūžio ir visiškai nepadeda, kai failo nėra. Pakartotinis prisijungimas po serverio sesijos laiko limito vėl nuskaito failą, todėl kredencialai, kurie veikė įkrovimo metu, vis tiek gali pasibaigti dienos viduryje.

Valdymo lizdas: kiekviena užklausa, daugiau paviršiaus

Paleiskite klientą su klausytoju ir aiškiai nurodykite, kad užklausos bus pranešamos per jį, naudodami direktyvas, dokumentuotas OpenVPN 2.6 vadove:

management 127.0.0.1 3030
management-query-passwords

Iš bash laikykite ryšį atsarginiame failo deskriptoriuje ir atsakykite pagal užklausos vardą, o ne pagal poziciją, nes prisijungimas iš naujo gali klausti kita tvarka:

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

Riba yra transportas. Valdymo protokolas yra atviras tekstas per TCP loopback sąsajoje, todėl klausytojo negalima skelbti LAN ar tunelio adresu, kad nuotolinis valdiklis jį pasiektų; nuotolinis valdiklis reiškia SSH perdavimą, o ne platesnį susiejimą. Bendruomenės demonas taip pat priima tik vieną valdymo klientą vienu metu, todėl GUI ar monitorius negali dalytis lizdo su jūsų scenarijumi. Antrasis prisijungimas atmetamas, o ne dedamas į eilę, ir gedimas atrodo kaip apkurtęs scenarijus.

Tas lizdas taip pat yra valdymo kanalas. Be valdymo slaptažodžio bet kas, kas gali prisijungti prie 127.0.0.1:3030, gali skaityti būseną, nužudyti tunelį arba pats atsakyti į užklausą. Valdymo slaptažodis ir kredencialų failas yra tos pačios klasės paslaptis, ir abu verti tokios pačios priežiūros.

Kuris tinka diegimui

Rinkitės kredencialų failą, kai vienintelė užklausa yra paskyros pora, klientas veikia kaip paslauga su stabiliu savininku, ir galite laikyti 600 failą už atsarginių kopijų, kurių nekontroliuojate. Rinkitės valdymo lizdą, kai dalyvauja rakto slaptafrazė arba PKCS#12 slaptažodis, kai apvalkalas jau prižiūri procesą, arba kai reikia stebėti būseną ir užklausas derinant prisijungimą iš naujo.

Dvi sąlygos pastumia sprendimą. Jei apvalkalas yra /bin/sh, systemd vienetas, kuris tiesiogiai kviečia dvejetainį failą, arba minimalus konteineris, tik bash skirtas lizdo klijai nepasiekiami ir failas yra pigesnis atsakymas. Jei paslaptis dažnai sukasi, nė vienas failas nėra geras namas jai: paklauskite raktų saugyklos iš mažo apvalkalo ir leiskite vienetui kviesti apvalkalą, kas laiko rotaciją vienoje vietoje, o slaptažodį už apvalkalo istorijos.

Procesų pakeitimas stovi tarp abiejų ir nepriklauso nė vienam. Vienos eilutės komanda žemiau veikia todėl, kad bash ją išskleidžia prieš startuojant openvpn, o ne todėl, kad klientas supranta sintaksę:

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

Ji lūžta po /bin/sh, vienete, kuris apeina apvalkalą, ir atvaizduose be bash arba /dev/fd. Laikykite ją interaktyviam testavimui, niekada kaip sutartį, nuo kurios priklauso paslauga.

Apsaugokite paslaptį, tada patikrinkite iš žurnalo

Abu mechanizmai palieka paslaptį, kurią gali perskaityti OpenVPN procesas. Niekada nedėkite slaptažodžio į komandų eilutę ar vieneto failą, kur ps ir systemctl rodo jį kiekvienam vietiniam vartotojui; perduokite kelią iki failo, o ne reikšmę jame. Ten, kur sertifikatai gali pakeisti paskyros porą, tai pašalina užklausos kategoriją, o ne ją slepia.

Teisingas paleidimas rodo užklausų sekos užbaigimą ir sesijos pasiekimą «Initialization Sequence Completed». Jei klientas sustoja ties ta pačia užklausa, atitikimas nepavyko: atspausdinkite tikslias eilutes, kurias išsiuntė lizdas, patikrinkite kabutes ir užklausos vardą, ir pataisykite šabloną, o ne pridėkite sleep. Tunelis, kuris praneša apie sėkmę ir nieko neperduoda, yra maršrutizavimo arba push problema, o ne kredencialų.

Tada išbandykite prisijungimą iš naujo, o ne tik pirmą paleidimą. Nutraukite serverio sesiją arba palaukite jos laiko limito; klientas vėl klausia, ir būtent ten failas, kuris įkrovimo metu atrodė teisingas, parodo, ar jis vis dar skaitomas paskyros, kuri jungiasi iš naujo.

Susiję straipsniai