Náhodný výber OpenVPN v systemd: prečo ExecStart zlyháva
systemd nie je shell, takže premiešaná kópia vnútri ExecStart zomiera. Presuňte výber do ExecStartPre alebo nechajte OpenVPN vybrať server samo.
Štyridsať súborov .ovpn pre jednu krajinu prichádza od poskytovateľa a plán vyzerá zjavne: skopírovať náhodný na jeho miesto a potom spustiť tunel. Napísaný ako potrubie vnútri ExecStart, ten plán zomiera pri štarte so stavovým kódom, ktorý nič nevysvetľuje. Súbor jednotky nie je skript a oprava spočíva buď v tom, že výslovne privediete shell, alebo v tom, že prestanete súbory vyberať úplne.
Príznak: jednotka, ktorá naštartuje a hneď zomrie
Stav ukazuje, že služba zlyhala v zlomku sekundy, a riadok v žurnáli uvádza príkaz, ktorý by žiadny shell nikdy nedostal. O tuneli sa nič neobjaví, pretože tunel nikdy nezačal.
Prečítať presný príkazový riadok zo žurnálu je najrýchlejší spôsob, ako to potvrdiť. systemd vypisuje, čo spustil, a reťazec ukáže znaky potrubia ako doslovné argumenty, nie ako operátory.
Prečo ExecStart nemôže spustiť potrubie
systemd sám rozdeľuje príkazový riadok, uplatní vlastné úvodzovky a substitúciu premenných a výsledok potom spustí priamo. Potrubia, presmerovanie, globovanie shellom a substitúcia príkazov jednoducho nie sú súčasťou tejto gramatiky. Je to dizajnová voľba, nie opomenutie: jednotka deklaruje, čo spustiť, a logika shellu patrí do skriptu, ktorý jednotka volá. Z toho vyplývajú obe opravy a ani jedna nevyžaduje dať jednotke viac oprávnení.
Vysvetľuje to aj zavádzajúci návratový kód. Prvý argument sa považuje za binárku, takže chybný riadok zlyhá skôr, než sa spustí čokoľvek z vašej logiky.
Výber urobte v ExecStartPre
Priamou opravou je prípravný krok, ktorý výslovne volá shell a drží výber aj štart v tej istej jednotke, aby zlyhanie jedného nemohlo nechať druhé bežať osamote.
[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
O tom, či toto prežije stretnutie so skutočným strojom, rozhodujú tri detaily. Pomenovanie je prvá pasca: systemd nahrádza %i už pri parsovaní jednotky, dávno predtým, než sa spustí bash, takže špecifikátor musí stáť mimo jednoduchých úvodzoviek. xargs -r bráni tomu, aby sa cp spustil bez argumentu, keď glob nič nenájde. A neúspešný prípravný krok jednotku zastaví, čo je správny výsledok: štartovať s včerajšou konfiguráciou je horšie ako neštartovať. Náhodný výber, ktorý vždy vezme ten istý súbor, zvyčajne nie je smola. Skontrolujte, či kopírovaný súbor neprepisuje aktualizácia balíka, alebo či glob nezodpovedá jedinej zastaranej položke.
Alebo nechajte OpenVPN vybrať koncový bod
OpenVPN už dokáže držať niekoľko koncových bodov v jednom profile a náhodne medzi nimi vyberať, čo úplne odstraňuje shell, kopírovanie aj právo zápisu z cesty štartu.
client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>
Táto forma drží výber servera v súbore, ktorý vytvoril poskytovateľ, takže rotácia, ktorá premenúva súbory, jednotku nerozbije. Tiež robí zoznam kandidátov auditovateľným, čím glob nad adresárom nikdy nie je. Miešanie si stále zaslúži svoje miesto, keď sa profily líšia viac než koncovým bodom: iné certifikáty, iné smerovacie direktívy, iná šifrová politika. V takom prípade je výber medzi celými konfiguráciami a krok so shellom je poctivý spôsob, ako to vyjadriť.
Prečítajte si inštanciu a súbor, ktorý použila
Pred ladením obsahu potvrďte, ktorá jednotka skutočne beží. Zabalená meta služba a šablóna sú infraštruktúra; jednotky, ktoré zodpovedajú vašim súborom, sú inštancie pomenované po nich.
systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager
Inštancia, o ktorej si nikto nepamätá, že ju zapol, zvyčajne vedie k zatúlanému konfiguračnému súboru v adresári balíka. Vypnite práve túto pomenovanú inštanciu, nie šablónu, inak ju budúca aktualizácia balíka vráti. Po zmene jednotku spustite a prečítajte príkazový riadok, ktorý hlási žurnál, a potom potvrďte cestu ku konfigurácii, ktorú skutočne otvorila. Táto jediná kontrola oddeľuje fungujúci náhodný výber od služby, ktorá potichu znovu používa súbor z minulého mesiaca.