Atsitiktinis OpenVPN pasirinkimas systemd: kodėl ExecStart nepavyksta
systemd nėra apvalkalas, todėl sumaišyta kopija ExecStart viduje miršta. Perkelkite pasirinkimą į ExecStartPre arba leiskite OpenVPN pačiam pasirinkti serverį.
Keturiasdešimt .ovpn failų vienai šaliai atkeliauja iš tiekėjo, ir planas atrodo akivaizdus: nukopijuoti atsitiktinį į jo vietą, tada paleisti tunelį. Užrašytas kaip konvejeris ExecStart viduje, tas planas miršta įkrovimo metu su būsenos kodu, kuris nieko nepaaiškina. Unito failas nėra scenarijus, o pataisymas yra arba aiškiai įtraukti apvalkalą, arba visiškai nustoti rinktis failus.
Simptomas: unitas, kuris paleidžiamas ir iškart miršta
Būsena rodo, kad paslauga nepavyko per sekundės dalį, o žurnalo eilutė įvardija komandą, kurios jokia apvalkalas niekada nebūtų gavęs. Apie tunelį nieko nepasirodo, nes tunelis taip ir neprasidėjo.
Tikslios komandų eilutės nuskaitymas iš žurnalo yra greičiausias būdas tai patvirtinti. systemd atkartoja tai, ką įvykdė, ir eilutė parodys konvejerio simbolius kaip pažodinius argumentus, o ne kaip operatorius.
Kodėl ExecStart negali paleisti konvejerio
systemd pats suskaido komandų eilutę, taiko savo kabutes ir kintamųjų pakeitimą, o tada rezultatą vykdo tiesiogiai. Konvejeriai, peradresavimas, apvalkalo atliekamas glob išplėtimas ir komandų pakeitimas tiesiog nėra šios gramatikos dalis. Tai dizaino pasirinkimas, o ne praleidimas: unitas deklaratyviai nurodo, ką vykdyti, o apvalkalo logika priklauso scenarijui, kurį unitas iškviečia. Abi pataisos iš to išplaukia, ir nė viena nereikalauja suteikti unitui daugiau privilegijų.
Tai taip pat paaiškina klaidinantį išėjimo kodą. Pirmasis argumentas traktuojamas kaip dvejetainis failas, todėl neteisinga eilutė nepavyksta dar prieš paleidžiant bet kurią jūsų logikos dalį.
Pasirinkimą atlikite ExecStartPre
Tiesioginė pataisa yra paruošiamasis žingsnis, kuris aiškiai iškviečia apvalkalą ir laiko pasirinkimą bei paleidimą tame pačiame unite, kad vieno nesėkmė neleistų kitam veikti vienam.
[Service]
Type=notify
ExecStartPre=/bin/bash -c "ls /etc/openvpn/profiles/au* | shuf -n 1 | xargs -r -I{} cp -f {} /etc/openvpn/%i.conf"
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/%i.conf
Trys detalės lemia, ar tai atlaikys susidūrimą su tikra mašina. Pavadinimas yra pirmosios spąstai: systemd pakeičia %i jau analizuodamas unitą, gerokai anksčiau, nei paleidžiamas bash, todėl specifikatorius turi stovėti už vienkartinių kabučių. xargs -r neleidžia cp paleisti be argumento, kai glob nieko neatitinka. O nepavykęs paruošiamasis žingsnis sustabdo unitą, ir tai yra teisingas rezultatas: pradėti su vakarykšte konfigūracija yra blogiau nei nepradėti. Atsitiktinis pasirinkimas, kuris visada ima tą patį failą, paprastai nėra nesėkmė. Patikrinkite, ar kopijuojamą failą perrašo paketo naujinimas, ar glob atitinka tik vieną pasenusį įrašą.
Arba leiskite OpenVPN pasirinkti galinį tašką
OpenVPN jau gali laikyti kelis galinius taškus viename profilyje ir atsitiktinai rinktis iš jų, o tai visiškai pašalina apvalkalą, kopijavimą ir rašymo prieigą iš įkrovimo kelio.
client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>
Ši forma laiko serverio pasirinkimą tiekėjo sukurto failo viduje, todėl rotacija, kuri pervadina failus, nesugadina unito. Ji taip pat padaro kandidatų sąrašą audituojamą, ko glob kataloge niekada nebūna. Maišymas vis dar vertas savo vietos, kai profiliai skiriasi daugiau nei galiniu tašku: skirtingi sertifikatai, skirtingos maršrutizavimo direktyvos, skirtinga šifravimo politika. Tokiu atveju pasirinkimas yra tarp ištisų konfigūracijų, ir apvalkalo žingsnis yra sąžiningas būdas tai išreikšti.
Perskaitykite atgal instanciją ir failą, kurį ji naudojo
Prieš derindami jo turinį patvirtinkite, kuris unitas iš tikrųjų veikia. Supakuota meta paslauga ir šablonas yra infrastruktūra; unitai, atitinkantys jūsų failus, yra instancijos, pavadintos jų vardu.
systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager
Instancija, kurios įjungimo niekas neprisimena, paprastai veda prie paketo kataloge paklydusio konfigūracijos failo. Išjunkite būtent tą pavadintą instanciją, o ne šabloną, kitaip kitas paketo naujinimas ją sugrąžins. Po pakeitimo paleiskite unitą ir perskaitykite komandų eilutę, kurią praneša žurnalas, tada patvirtinkite konfigūracijos kelią, kurį ji iš tikrųjų atidarė. Tas vienas patikrinimas atskiria veikiantį atsitiktinį pasirinkimą nuo paslaugos, kuri tyliai naudoja praėjusio mėnesio failą.