Varningen om flera skript låter som ett klagomål om schemaläggning, så den uppenbara lösningen är att ordna om raderna tills den försvinner. Det är inte ett klagomål om schemaläggning. En senare --up-definition ersätter kommandot som redan är sparat för det steget, och parsern säger det, vilket betyder att av dina två skript har exakt ett någonsin kört. Det andra står inte i kö bakom det; det är borta.

Därför förtjänar varningen uppmärksamhet även om den inte är fatal: det den förutspår är en DNS-uppdatering eller en ruttändring som tyst slutade ske.

Varningen handlar inte om ordning

OpenVPN sparar ett enda användarskriptkommando för up-steget. När parsern möter en annan definition, från profilen, en inkluderad fil eller kommandoraden, ersätter den det den redan höll och skickar varningen. Inget sammanfogas, inget körs två gånger, och det finns ingen ordningsfråga. Kommandot som överlever är det parsern såg sist, därför kan en flyttad rad ändra vinnaren medan det andra skriptet förblir dött.

Samma mönster gäller för de andra skriptstegen: ett kommando var. Om två arbeten båda måste ske behöver de en enda ingångspunkt, inte två direktiv som liknar en lista.

Hitta båda definitionerna i den verkliga starten

Börja med vad daemonen faktiskt tog emot, inte med profilen du redigerade. ps -ef och enhetens ExecStart visar kommandoraden, som kan lägga till --up från en container-entrypoint eller en wrapper; en distributions init-fil kan göra samma sak. systemctl cat openvpn-server@server avslöjar vad tjänsten själv bidrar med, och en rekursiv grep i konfigurationskatalogen hittar filnivådefinitionerna. Dubbletter kommer oftast från olika lager, och det är just därför redigering av en enda fil inte ändrar något.

Att kopiera ett skript till en annan katalog eller byta namn på det tar inte heller bort ett direktiv. Parsern räknar definitioner, inte filer.

Låt en hook äga arbetet

Den hållbara lösningen är en enda dispatcher som kör båda åtgärderna i en medveten ordning. Ett kort shellskript med set -eu som anropar den nödvändiga integrationen och sedan den lokala åtgärden och vidarebefordrar "$@" så att argumentgränserna överlever, håller beteendet på ett ställe som kan granskas. Att vidarebefordra argument bevarar dem bara; det bevisar inte att de två hjälparna förväntar sig samma gränssnitt, så läs var och ens kontrakt. Bestäm vad ett fel ska göra och om delvisa ändringar måste rullas tillbaka.

Om startaren erbjuder en stödd utökningshook, föredra den framför handbyggd kedja. En containeravbild eller ett leverantörspaket har ofta en dokumenterad plats för extra arbete, och att använda den hindrar en uppgradering från att skriva över din dispatcher.

Städning hör till motsvarande down-steg. En up-åtgärd som skriver om DNS eller lägger till rutter behöver en dokumenterad återställning, och en dispatcher som bara hanterar starten är en halv design.

Bekräfta integrationen, inte bara tystnaden

Att ta bort dubblettvarningen är den enkla delen; integrationen måste fortfarande fungera. Kontrollera resolverstatus efter anslutning med resolvectl status eller genom att läsa /etc/resolv.conf, och bekräfta rutter med ip route. Koppla sedan från och anslut igen, eftersom en snabbt kedjad hook tenderar att lämna något kvar från föregående session. journalctl -u openvpn-server@server -b visar om din dispatcher kördes och vad den skrev ut.

Håll hookens rättigheter där de hör hemma. Att höja script-security eller köra daemonen med fler rättigheter är ingen lösning för en ersatt hook; det utökar vad varje framtida skript kan göra, inklusive ett som en angripare får namnge.

Tecknet på att åtgärden är verklig är inte tystnad i loggen. Det är DNS-svaret, ruttposten och städningen som alla fungerar efter två återanslutningar.

Relaterade artiklar