Kör uppgifter efter VPN från dispatchern, inte från if-up
En gammal gränssnittskrok ser inte en VPN-anslutning. Matcha vpn-up mot profilens UUID, håll uppgiften repeterbar och planera för en frånkoppling som aldrig utlöses.
Ett skript som måste köras efter att VPN:en kommer upp behöver en händelse från komponenten som äger anslutningen. En fil som läggs i en gammal mapp för nätverkskrokar är inte en återkallelse för varje VPN som NetworkManager, pppd eller en fristående OpenVPN-process kan skapa. Var och en av dessa ägare rapporterar en annan händelse med en annan miljö, så ägaren måste identifieras innan kroken väljs. Annars är skriptet korrekt och körs helt enkelt aldrig.
För en VPN som hanteras av NetworkManager är dispatchern rätt plats, och vpn-up är rätt åtgärd.
Använd vpn-up, inte gränssnittshändelsen
Dispatchern skiljer up från vpn-up. Den första rapporterar ett aktiverat gränssnitt; den andra rapporterar en aktiverad VPN-anslutning. Att Wi-Fi kommer upp betyder bara att den underliggande länken finns; tunneln förhandlar kanske fortfarande, eller autentiseras aldrig.
Skriptet tar emot gränssnittet och åtgärden, medan anslutningsdetaljer kommer via miljön, inklusive profilens UUID och VPN:ens IP-gränssnitt. Läs de variablerna i stället för att härleda identitet från enhetsnamn.
Begränsa matchningen till en anslutning
Matcha på anslutningens UUID, eller en annan identitet som dispatchern tillhandahåller, i stället för ett tun-prefix eller ppp0. Gränssnittsnamn är inte stabila, det kan finnas mer än en tunnel samtidigt, och två profiler kan bära samma visningsnamn. Att matcha ett tun-prefix betyder att skriptet till slut utlöses för en anslutning som ingen tänkte röra. Det kan också utlösas två gånger för en profil när en återanslutning bygger om enheten.
Gör uppgiften idempotent. En återkallelse som lägger till en rutt vid varje anrop fyller till slut tabellen med dubbletter, och det är den andra kopian som förstör routningen.
Vet vad aktiveringen inte bevisar
vpn-pre-up körs innan NetworkManager rapporterar att VPN:en är fullt aktiverad, och hanteraren väntar på dessa skript. Använd ett blockerande steg bara när uppgiften verkligen hör hemma där, eftersom en långsam kontroll fördröjer den aktivering som alla andra komponenter väntar på att se.
Att rutter finns bevisar inte att ett program lyssnar, att ett privat namn löses upp eller att en användarsession finns. Kontrollera det separat med en begränsad tidsgräns, och rapportera vilket lager som misslyckades i stället för att försöka igen med hela kedjan.
Respektera kontexten som skriptet körs i
Dispatcherns skript körs som root, utanför varje användarsession. Anta inte att den inloggade användarens miljö, grafiska session eller upplåsta nyckelring är tillgänglig. Ingen borde svara på en saknad skrivbordskontext genom att göra varje autentiseringsuppgift läsbar för varje process. Håll arbete i användarsessionen i en användartjänst eller en sessionshjälpare som återkallelsen kan signalera utan att imitera användaren.
Ägarskap och rättigheter på skriptet spelar också roll. En fil som körs som root och som vilken användare som helst kan ersätta är en väg till privilegiehöjning, och det är en iakttagelse oberoende av om VPN-logiken är korrekt.
Planera för frånkopplingen som aldrig utlöses
NetworkManager dokumenterar att vpn-pre-down inte sänds ut vid tvingade frånkopplingar som ett oväntat avslut eller förlorad anslutning. Därför är städning som bara bygger på en mjuk pre-down ofullständig av konstruktion. Varje delat tillstånd som skriptet ändrar behöver en annan ägare som kan återställa det efter en krasch, och den återställningsvägen måste testas i stället för antas.
Testa kroken med en normal anslutning, en återanslutning, en avsiktlig frånkoppling och en utdragen kabel. Registrera UUID:t, åtgärden och gränssnittet som utlöstes, utan att logga hemligheter. Den registreringen är det enda tillförlitliga beviset på att kroken kördes för den anslutning du menade, och det är den som gör nästa ändring säker.