Quaranta fitxers .ovpn d’un país arriben d’un proveïdor, i el pla sembla obvi: copieu-ne un a l’atzar al seu lloc i després inicieu el túnel. Escrit com una canonada dins d’ExecStart, aquest pla mor a l’arrencada amb un codi d’estat que no explica res. El fitxer d’unitat no és un script, i la reparació és o bé portar un intèrpret d’ordres explícitament o bé deixar de triar fitxers del tot.

El símptoma: una unitat que s’inicia i mor immediatament

L’estat mostra que el servei va fallar en una fracció de segon, i la línia del registre anomena una ordre que cap intèrpret d’ordres hauria rebut mai. No apareix res sobre el túnel, perquè el túnel mai no va començar.

Llegir la línia d’ordre exacta del registre és la manera més ràpida de confirmar-ho. systemd reprodueix el que ha executat, i la cadena mostrarà els caràcters de canonada com a arguments literals en lloc d’operadors.

Per què ExecStart no pot executar una canonada

systemd divideix ell mateix la línia d’ordre, aplica les seves pròpies cometes i substitució de variables, i després executa el resultat directament. Les canonades, la redirecció, l’expansió de patrons de l’intèrpret d’ordres i la substitució d’ordres simplement no formen part d’aquesta gramàtica. És una decisió de disseny i no una omissió: una unitat és declarativa sobre què cal executar, i la lògica d’intèrpret d’ordres pertany a un script que la unitat invoca. Totes dues reparacions se’n deriven, i cap no requereix donar més privilegis a la unitat.

També explica el codi de sortida enganyós. El primer argument es tracta com el binari, així que una línia mal formada falla abans que s’executi res de la vostra lògica.

Feu la tria a ExecStartPre

La reparació directa és un pas de preparació que crida un intèrpret d’ordres explícitament, mantenint la tria i l’inici a la mateixa unitat perquè una fallada en un no pugui deixar l’altre funcionant sol.

[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

Tres detalls decideixen si això sobreviu al contacte amb una màquina real. L’anomenament és el primer parany: systemd substitueix %i mentre analitza la unitat, molt abans que bash s’executi, així que l’especificador ha de quedar fora de les cometes simples. xargs -r evita que cp s’executi sense argument quan el patró no coincideix amb res. I un pas de preparació fallit atura la unitat, que és el resultat correcte: començar amb la configuració d’ahir és pitjor que no començar. Una tria a l’atzar que sempre agafa el mateix fitxer normalment no és mala sort. Comproveu si el fitxer copiat se sobreescriu per una actualització del paquet, o si el patró només coincideix amb una entrada obsoleta.

O deixeu que OpenVPN triï el punt final

OpenVPN ja pot tenir diversos punts finals en un perfil i triar-ne un a l’atzar, cosa que treu l’intèrpret d’ordres, la còpia i el permís d’escriptura del camí d’arrencada del tot.

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

Aquesta forma manté la tria de servidor dins del fitxer que el proveïdor ha escrit, així que una rotació que reanomena fitxers no trenca la unitat. També fa auditable la llista de candidats, cosa que un patró sobre un directori no és mai. La barreja encara es guanya el lloc quan els perfils difereixen en més d’un punt final: certificats diferents, directrius d’encaminament diferents, política de xifratge diferent. En aquest cas la tria és entre configuracions senceres i un pas d’intèrpret d’ordres és la manera honesta d’expressar-ho.

Torneu a llegir la instància i el fitxer que ha utilitzat

Confirmeu quina unitat s’executa realment abans de depurar-ne el contingut. El servei meta empaquetat i la plantilla són infraestructura; les unitats que corresponen als vostres fitxers són les instàncies que porten el seu nom.

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

Una instància que ningú recorda haver activat sol remuntar-se a un fitxer de configuració esgarriat al directori del paquet. Desactiveu aquesta instància anomenada en lloc de la plantilla, altrament la propera actualització del paquet la tornarà a portar. Després del canvi, inicieu la unitat i llegiu la línia d’ordre que el registre informa, i després confirmeu el camí de configuració que ha obert realment. Aquesta única comprovació separa una tria a l’atzar que funciona d’un servei que reutilitza en silenci un fitxer del mes passat.

Articles relacionats