Satunnainen OpenVPN-valinta systemd:ssä: miksi ExecStart epäonnistuu
systemd ei ole kuori, joten sekoitettu kopio ExecStartin sisällä kuolee. Siirrä valinta ExecStartPre:hen tai anna OpenVPN:n valita palvelin itse.
Neljäkymmentä .ovpn-tiedostoa yhtä maata varten saapuu palveluntarjoajalta, ja suunnitelma näyttää ilmeiseltä: kopioi satunnainen paikalleen ja käynnistä sitten tunneli. Putkeksi ExecStart:n sisälle kirjoitettuna suunnitelma kuolee käynnistyksessä tilakoodiin, joka ei selitä mitään. Unit-tiedosto ei ole skripti, ja korjaus on joko tuoda kuori eksplisiittisesti mukaan tai lopettaa tiedostojen valinta kokonaan.
Oire: unit, joka käynnistyy ja kuolee heti
Tila näyttää, että palvelu epäonnistui sekunnin murto-osassa, ja journal-rivi nimeää komennon, jota mikään kuori ei olisi koskaan saanut. Tunnelista ei näy mitään, koska tunneli ei koskaan alkanut.
Tarkan komentorivin lukeminen journalista on nopein tapa vahvistaa tämä. systemd toistaa sen, mitä se suoritti, ja merkkijono näyttää putken merkit kirjaimellisina argumentteina eikä operaattoreina.
Miksi ExecStart ei voi suorittaa putkea
systemd jakaa komentorivin itse, soveltaa omaa lainaus- ja muuttujakorvaustaan ja suorittaa tuloksen sitten suoraan. Putket, uudelleenohjaus, kuoren glob-laajennus ja komentokorvaus eivät yksinkertaisesti kuulu tähän kielioppiin. Se on suunnitteluvalinta eikä puute: unit kertoo deklaratiivisesti, mitä suoritetaan, ja kuoren logiikka kuuluu skriptiin, jonka unit kutsuu. Molemmat korjaukset seuraavat tästä, eikä kumpikaan vaadi unitille enempää oikeuksia.
Se selittää myös harhaanjohtavan poistumiskoodin. Ensimmäistä argumenttia kohdellaan binäärinä, joten virheellinen rivi epäonnistuu ennen kuin mitään logiikkaasi ajetaan.
Tee valinta ExecStartPre:ssä
Suora korjaus on valmisteluvaihe, joka kutsuu kuorta eksplisiittisesti ja pitää valinnan ja käynnistyksen samassa unitissa, jotta toisen epäonnistuminen ei jätä toista yksin käyntiin.
[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
Kolme yksityiskohtaa ratkaisee, kestääkö tämä kohtaamisen oikean koneen kanssa. Nimeäminen on ensimmäinen ansa: systemd korvaa %i:n jo unitia jäsentäessään, kauan ennen kuin bash käynnistyy, joten määritteen on oltava yksinkertaisten lainausmerkkien ulkopuolella. xargs -r estää cp:n käynnistymisen ilman argumenttia, kun glob ei vastaa mitään. Ja epäonnistunut valmisteluvaihe pysäyttää unitin, mikä on oikea lopputulos: eilisellä kokoonpanolla käynnistäminen on huonompi kuin olla käynnistämättä. Satunnainen valinta, joka ottaa aina saman tiedoston, ei yleensä ole huonoa onnea. Tarkista, kirjoittaako pakettipäivitys kopioidun tiedoston yli, vai vastaako glob vain yhtä vanhentunutta merkintää.
Tai anna OpenVPN:n valita päätepiste
OpenVPN voi jo pitää useita päätepisteitä yhdessä profiilissa ja valita niiden joukosta satunnaisesti, mikä poistaa kuoren, kopioinnin ja kirjoitusoikeuden kokonaan käynnistyspolulta.
client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>
Tämä muoto pitää palvelinvalinnan palveluntarjoajan laatimassa tiedostossa, joten tiedostoja uudelleennimeävä rotaatio ei riko unitia. Se tekee myös ehdokasluettelosta auditoitavan, mitä hakemiston yli tehty glob ei koskaan ole. Sekoittaminen ansaitsee silti paikkansa, kun profiilit eroavat enemmästä kuin päätepisteestä: eri varmenteet, eri reititysdirektiivit, eri salauskäytäntö. Siinä tapauksessa valinta on kokonaisten kokoonpanojen välillä, ja kuorivaihe on rehellinen tapa ilmaista se.
Lue takaisin instanssi ja tiedosto, jota se käytti
Vahvista, mikä unit todella on käynnissä, ennen kuin debuggaat sen sisältöä. Paketoitu meta-palvelu ja mallipohja ovat infrastruktuuria; tiedostojasi vastaavat unitit ovat niiden mukaan nimetyt instanssit.
systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager
Instanssi, jonka käyttöönottoa kukaan ei muista, johtaa yleensä pakettihakemistossa harhailevaan kokoonpanotiedostoon. Sammuta juuri se nimetty instanssi mallipohjan sijaan, muuten seuraava pakettipäivitys tuo sen takaisin. Käynnistä muutoksen jälkeen unit ja lue komentorivi, jonka journal raportoi, ja vahvista sitten kokoonpanopolku, jonka se todella avasi. Se yksi tarkistus erottaa toimivan satunnaisvalinnan palvelusta, joka hiljaa käyttää uudelleen viime kuun tiedostoa.