Il tunnel è giù, ma la macchina si comporta ancora come se fosse su: una risoluzione resta appesa finché non scade, e una rotta punta a un’interfaccia che non esiste più. È la firma di un processo openconnect morto senza eseguire il suo helper di disconnessione. Lo stato di rete che ha creato è ancora installato, e nient’altro sul sistema sa come rimuoverlo.

Percorri la macchina nell’ordine in cui è stato creato lo stato: processo, link, rotta, resolver. Ogni passo ti dice se il client è davvero sparito o si è solo staccato dal tuo terminale, e questa distinzione decide se riparare qualcosa.

Inizia dal processo, non dalla configurazione

Apri un terminale e chiedi cosa è ancora in esecuzione prima di toccare una rotta. pgrep -a openconnect elenca ogni istanza con i suoi argomenti, mostrando il file pid e lo script che le è stato dato. Un processo che non ti aspettavi spiega il tunnel fantasma più in fretta di qualsiasi log.

Se non c’è nulla in esecuzione, guarda il link. ip link show tun0 ti dice se l’interfaccia è sopravvissuta, e ip route show dev tun0 elenca le rotte ancora legate ad essa. Poi controlla il resolver con resolvectl status. Annota tutti e tre gli output prima di modificarli, perché è quella registrazione che ti permetterà più tardi di distinguere una voce obsoleta da una nuova.

Un’interfaccia che scompare di solito porta con sé le sue rotte. Le rotte che sopravvivono al link di solito significano che il processo è ancora vivo o che un secondo client possiede il dispositivo.

È lo script ausiliario che annulla le modifiche

openconnect non rimuove da solo l’interfaccia, le rotte o le voci del resolver. Chiama un helper esterno, /etc/vpnc/vpnc-script in una build upstream e /usr/share/vpnc-scripts/vpnc-script nei pacchetti Debian e Ubuntu, scelto con -s. Lo stesso script che alza il tunnel è quello che lo smonta.

Se il processo esce senza chiamare quell’helper, lo stato resta. Il manuale di OpenConnect è esplicito: il routing e il servizio dei nomi non funzioneranno correttamente senza lo script, e descrive l’helper come il componente che smonta lo stato dell’interfaccia all’uscita. Ecco perché il percorso conta quando avvii il client con -s.

Quale segnale raggiunga quel percorso è cambiato tra le versioni. Il manuale della 7.06 tratta SIGTERM come un’uscita immediata che salta lo script. Le build attuali documentano INT e TERM come un arresto pulito, in cui la sessione viene disconnessa e l’helper viene eseguito. Leggi la sezione SIGNALS del binario che hai davvero invece di dare per scontato l’uno o l’altro comportamento.

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

Invia il segnale documentato dalla tua build

Una volta noto il segnale, ferma il processo per pid anziché per pattern.

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

Poi ripeti i tre controlli della prima sezione invece di fidarti dello stato di uscita. ip link show tun0 dovrebbe fallire, ip route show dev tun0 non dovrebbe stampare nulla, e resolvectl status non dovrebbe più elencare il link VPN.

SIGHUP non è un pulsante di arresto: disconnette, esegue lo script e lascia la sessione riprendibile con --cookie. SIGUSR2 forza una riconnessione immediata. SIGKILL salta del tutto la pulizia, ed è esattamente lo stato di cui parla questo articolo.

Ripara il resolver senza sostituire resolv.conf

Sulla maggior parte dei sistemi Ubuntu /etc/resolv.conf è un collegamento simbolico a systemd-resolved, non un file che dovresti modificare. Sostituirlo rompe la risoluzione dei nomi per ogni rete, non solo per la VPN. Invece, rimuovi la registrazione del tunnel:

resolvectl revert tun0
resolvectl query example.com

Se il sistema usa resolvconf anziché systemd-resolved, la voce per interfaccia persiste finché non le viene detto di rilasciare il link, e resolvconf -d tun0 è l’azione equivalente. Controlla quale resolver è in uso prima di scegliere il comando.

Una risoluzione ancora diretta a un server dietro il link morto resta appesa finché non scade, e quel ritardo sembra un server DNS guasto più che una rotta rimasta.

Rendi noiosa la prossima disconnessione

Mantieni lo stesso percorso del file pid all’avvio e allo spegnimento passando --pid-file ogni volta, oppure esegui openconnect sotto un’unità il cui KillSignal corrisponda al segnale documentato dalla tua versione. Provare prima in primo piano ti mostra i messaggi di spegnimento stampati dall’helper.

Connettiti, disconnettiti ed esegui i tre controlli una volta. Un’uscita pulita non lascia alcun link VPN, alcuna rotta VPN né alcuna voce del resolver VPN. Se uno dei tre sopravvive, ora sai quale componente non ha ripulito. L’indagine successiva parte allora da quella risposta invece che da una risoluzione appesa.

Articoli correlati