Tunneln är nere, men maskinen beter sig fortfarande som om den vore uppe: en uppslagning hänger tills den time-outar, och en rutt pekar in i ett gränssnitt som inte längre finns. Det är signaturen för en openconnect-process som dog utan att köra sin frånkopplingshjälpare. Nätverkstillståndet den skapade är fortfarande installerat, och ingenting annat i systemet vet hur det ska tas bort.

Gå igenom maskinen i den ordning tillståndet skapades: process, länk, rutt, resolver. Varje steg berättar om klienten verkligen är borta eller bara frånkopplad från din terminal, och den skillnaden avgör om du ska reparera något alls.

Börja med processen, inte konfigurationen

Öppna en terminal och fråga vad som fortfarande körs innan du rör en rutt. pgrep -a openconnect listar varje instans med dess argument, vilket visar pid-filen och skriptet den fick. En process du inte förväntade dig förklarar spöktunneln snabbare än någon logg.

Om ingenting körs, titta på länken. ip link show tun0 berättar om gränssnittet överlevde, och ip route show dev tun0 listar rutter som fortfarande är bundna till det. Kontrollera sedan resolvern med resolvectl status. Notera alla tre utdata innan du ändrar dem, eftersom den registreringen är hur du senare skiljer en inaktuell post från en ny.

Ett gränssnitt som försvinner tar vanligtvis med sig sina rutter. Rutter som överlever länken betyder oftast att processen fortfarande lever eller att en andra klient äger enheten.

Det är hjälpsköriptet som rullar tillbaka ändringarna

openconnect tar inte bort gränssnittet, rutterna eller resolver-poster själv. Det anropar en extern hjälpare, /etc/vpnc/vpnc-script i en upstream-build och /usr/share/vpnc-scripts/vpnc-script i Debian- och Ubuntu-paketen, vald med -s. Samma skript som sätter upp tunneln är det som river den.

Om processen avslutas utan att anropa den hjälparen stannar tillståndet kvar. OpenConnect-handboken säger uttryckligen att routing och namntjänst inte kommer att fungera korrekt utan skriptet, och den beskriver hjälparen som komponenten som monterar ned gränssnittstillståndet vid avslut. Därför är sökvägen viktig när du startar klienten med -s.

Vilken signal som når den vägen ändrades mellan versioner. Handboken för 7.06 behandlar SIGTERM som en omedelbar avslutning som hoppar över skriptet. Nuvarande builds dokumenterar INT och TERM som ett rent stopp, där sessionen loggas ut och hjälparen körs. Läs avsnittet SIGNALS i den binärfil du faktiskt har i stället för att anta någon av de två beteendena.

man openconnect | sed -n '/^SIGNALS/,/^LIMITATIONS/p'

Skicka signalen som din build dokumenterar

När du känner till signalen, stoppa processen efter pid och inte efter mönster.

pgrep -a openconnect
sudo kill -INT "$(cat /var/run/openconnect.pid)"

Upprepa sedan de tre kontrollerna från första avsnittet i stället för att lita på exitstatusen. ip link show tun0 borde misslyckas, ip route show dev tun0 borde inte skriva ut något, och resolvectl status borde inte längre lista VPN-länken.

SIGHUP är inte en stoppknapp: den kopplar från, kör skriptet och lämnar sessionen återupptagbar med --cookie. SIGUSR2 tvingar fram en omedelbar återanslutning. SIGKILL hoppar helt över städningen, och det är precis det tillstånd den här artikeln handlar om.

Reparera resolvern utan att ersätta resolv.conf

På de flesta Ubuntu-system är /etc/resolv.conf en symbolisk länk in i systemd-resolved, inte en fil du borde redigera. Att ersätta den bryter namnuppslagning för alla nätverk, inte bara VPN. Ta i stället bort registreringen av tunneln:

resolvectl revert tun0
resolvectl query example.com

Om systemet använder resolvconf i stället för systemd-resolved finns posten per gränssnitt kvar tills den blir tillsagd att släppa länken, och resolvconf -d tun0 är motsvarande åtgärd. Kontrollera vilken resolver som används innan du väljer kommandot.

En uppslagning som fortfarande riktas mot en server bakom den döda länken hänger tills den time-outar, och den fördröjningen ser ut som en trasig DNS-server snarare än en kvarvarande rutt.

Gör nästa frånkoppling tråkig

Håll sökvägen till pid-filen identisk vid start och avstängning genom att skicka --pid-file varje gång, eller kör openconnect under en unit vars KillSignal matchar signalen som din version dokumenterar. Testa först i förgrunden visar dig avstängningsmeddelandena som hjälparen skriver ut.

Anslut, koppla från och kör de tre kontrollerna en gång. En ren avslutning lämnar varken VPN-länk, VPN-rutt eller VPN-resolver-post. Om en av de tre överlever vet du nu vilken komponent som inte städade. Nästa utredning börjar då från det svaret i stället för från en hängande uppslagning.

Relaterade artiklar