Førti .ovpn-filer for ett land kommer fra en leverandør, og planen ser åpenbar ut: kopier en tilfeldig på plass, og start deretter tunnelen. Skrevet som en pipeline inne i ExecStart dør den planen ved oppstart med en statuskode som ikke forklarer noe. Unit-filen er ikke et skript, og rettelsen er enten å hente inn et skall eksplisitt eller å slutte helt å velge filer.

Symptomet: en unit som starter og dør umiddelbart

Statusen viser at tjenesten feilet i løpet av en brøkdel av et sekund, og journal-linjen navngir en kommando som ingen skall noen gang ville ha mottatt. Ingenting om tunnelen vises, fordi tunnelen aldri begynte.

Å lese den nøyaktige kommandolinjen fra journalen er den raskeste måten å bekrefte dette på. systemd gjengir det den kjørte, og strengen vil vise pipeline-tegnene som bokstavelige argumenter i stedet for som operatorer.

Hvorfor ExecStart ikke kan kjøre en pipeline

systemd deler opp kommandolinjen selv, bruker sin egen sitat- og variabelsubstitusjon, og kjører deretter resultatet direkte. Pipes, omdirigering, glob-utvidelse fra et skall og kommandosubstitusjon er rett og slett ikke en del av denne grammatikken. Det er et designvalg og ikke en utelatelse: en unit sier deklarativt hva som skal kjøres, og skall-logikk hører hjemme i et skript som uniten kaller. Begge rettelsene følger av dette, og ingen av dem krever at uniten får flere rettigheter.

Det forklarer også den misvisende utgangskoden. Det første argumentet behandles som binæren, så en feilformet linje feiler før noe av logikken din kjører.

Gjør valget i ExecStartPre

Den direkte rettelsen er et forberedelsestrinn som kaller et skall eksplisitt, og holder valget og starten i samme unit slik at en feil i den ene ikke kan la den andre kjøre alene.

[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

Tre detaljer avgjør om dette overlever møtet med en ekte maskin. Navngivning er den første fellen: systemd erstatter %i allerede ved parsing av uniten, lenge før bash kjører, så spesifikatoren må stå utenfor enkle anførselstegn. xargs -r hindrer cp i å kjøre uten argument når globen ikke treffer noe. Og et mislykket forberedelsestrinn stopper uniten, og det er det riktige utfallet: å starte med gårsdagens konfigurasjon er verre enn å ikke starte. Et tilfeldig valg som alltid tar samme fil er vanligvis ikke uflaks. Sjekk om den kopierte filen overskrives av en pakkeoppdatering, eller om globen bare treffer én foreldet oppføring.

Eller la OpenVPN velge endepunktet

OpenVPN kan allerede holde flere endepunkter i én profil og velge tilfeldig blant dem, noe som fjerner skallet, kopien og skrivetilgangen helt fra oppstartsbanen.

client
remote-random
<connection>
remote au1.example.net 1194 udp
</connection>
<connection>
remote au2.example.net 1194 udp
</connection>

Denne formen holder servervalget inne i filen leverandøren skrev, så en rotasjon som gir filer nye navn ikke ødelegger uniten. Den gjør også kandidatlisten reviderbar, noe en glob over en katalog aldri er. Blandingen har fortsatt sin plass når profiler skiller seg i mer enn et endepunkt: forskjellige sertifikater, forskjellige rutingdirektiver, forskjellig chifferpolitikk. I så fall er valget mellom hele konfigurasjoner, og et skalltrinn er den ærlige måten å uttrykke det på.

Les tilbake instansen og filen den brukte

Bekreft hvilken unit som faktisk kjører før du feilsøker innholdet. Den pakkede metatjenesten og malen er infrastruktur; unitene som svarer til filene dine, er instansene som er oppkalt etter dem.

systemctl list-units 'openvpn*'
systemctl cat [email protected]
journalctl -u openvpn@au -n 30 --no-pager

En instans som ingen husker å ha aktivert, fører vanligvis tilbake til en villfaren konfigurasjonsfil i pakkekatalogen. Slå av den navngitte instansen i stedet for malen, ellers bringer neste pakkeoppgradering den tilbake. Etter endringen starter du uniten og leser kommandolinjen journalen rapporterer, og bekrefter deretter konfigurasjonsbanen den faktisk åpnet. Den ene kontrollen skiller et fungerende tilfeldig valg fra en tjeneste som stille gjenbruker en fil fra forrige måned.

Relaterte artikler