Fyrre .ovpn-filer til ét land kommer fra en udbyder, og planen ser indlysende ud: kopiér en tilfældig på plads, og start så tunnelen. Skrevet som en pipeline inde i ExecStart dør den plan ved opstart med en statuskode, der ikke forklarer noget. Unit-filen er ikke et script, og rettelsen er enten at hente en skal ind eksplicit eller at holde helt op med at vælge filer.

Symptomet: en unit, der starter og straks dør

Statusen viser, at tjenesten fejlede på en brøkdel af et sekund, og journal-linjen nævner en kommando, som ingen skal nogensinde ville have modtaget. Der vises intet om tunnelen, fordi tunnelen aldrig begyndte.

At læse den præcise kommandolinje fra journalen er den hurtigste måde at bekræfte dette. systemd gengiver det, den eksekverede, og strengen vil vise pipeline-tegnene som bogstavelige argumenter i stedet for som operatorer.

Hvorfor ExecStart ikke kan køre en pipeline

systemd opdeler selv kommandolinjen, anvender sin egen citering og variabelsubstitution og eksekverer derefter resultatet direkte. Pipes, omdirigering, glob-udvidelse fra en skal og kommandosubstitution er simpelthen ikke en del af den grammatik. Det er et designvalg og ikke en udeladelse: en unit er deklarativ om, hvad der skal køres, og skal-logik hører til i et script, som uniten kalder. Begge rettelser følger af det, og ingen af dem kræver, at uniten får flere rettigheder.

Det forklarer også den misvisende exitkode. Det første argument behandles som binæren, så en forkert linje fejler, før noget af din logik kører.

Foretag valget i ExecStartPre

Den direkte rettelse er et forberedelsestrin, der kalder en skal eksplicit og holder valget og starten i samme unit, så en fejl i den ene ikke kan efterlade den anden kørende 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 afgør, om dette overlever mødet med en rigtig maskine. Navngivning er den første fælde: systemd erstatter %i under parsing af uniten, længe før bash kører, så specifieren skal stå uden for enkelte anførselstegn. xargs -r forhindrer, at cp kører uden argument, når globbet ikke matcher noget. Og et mislykket forberedelsestrin stopper uniten, og det er det rigtige resultat: at starte med gårsdagens konfiguration er værre end ikke at starte. Et tilfældigt valg, der altid tager den samme fil, er normalt ikke uheld. Tjek, om den kopierede fil overskrives af en pakkeopdatering, eller om globbet kun matcher én forældet post.

Eller lad OpenVPN vælge endepunktet

OpenVPN kan allerede holde flere endepunkter i én profil og vælge tilfældigt blandt dem, hvilket helt fjerner skallen, kopien og skriveadgangen fra opstartsstien.

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

Denne form holder servervalget inde i den fil, udbyderen har skrevet, så en rotation, der omdøber filer, ikke ødelægger uniten. Den gør også kandidatlisten reviderbar, hvilket et glob over en mappe aldrig er. Blandingen har stadig sin plads, når profiler adskiller sig i mere end et endepunkt: forskellige certifikater, forskellige routing-direktiver, forskellig krypteringspolitik. I så fald er valget mellem hele konfigurationer, og et skal-trin er den ærlige måde at udtrykke det på.

Læs instansen og den fil, den brugte, tilbage

Bekræft, hvilken unit der faktisk kører, før du fejlfinder dens indhold. Den pakkede meta-tjeneste og skabelonen er infrastruktur; de units, der svarer til dine filer, er de instanser, der er opkaldt efter dem.

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

En instans, som ingen husker at have aktiveret, fører normalt tilbage til en vildfaren konfigurationsfil i pakkemappen. Slå den navngivne instans fra i stedet for skabelonen, ellers bringer den næste pakkeopgradering den tilbage. Start uniten efter ændringen, og læs den kommandolinje, journalen rapporterer, og bekræft derefter den konfigurationssti, den faktisk åbnede. Den ene kontrol adskiller et fungerende tilfældigt valg fra en tjeneste, der stille genbruger en fil fra sidste måned.

Relaterede artikler