openconnect tué : les routes et le DNS pointent toujours vers le tunnel
Un processus openconnect mort peut laisser des routes et des entrées de résolution installées. Parcourez le chemin d’arrêt, envoyez le signal que votre build documente, puis nettoyez.
Le tunnel est tombé, mais la machine se comporte encore comme s’il était monté : une requête reste bloquée jusqu’au délai d’expiration, et une route pointe vers une interface qui n’existe plus. C’est la signature d’un processus openconnect mort sans avoir lancé son assistant de déconnexion. L’état réseau qu’il a créé est toujours installé, et rien d’autre sur le système ne sait comment le supprimer.
Parcourez la machine dans l’ordre où l’état a été créé : processus, lien, route, résolveur. Chaque étape vous dit si le client est réellement parti ou s’il s’est seulement détaché de votre terminal, et cette distinction décide si vous devez réparer quoi que ce soit.
Commencez par le processus, pas par la configuration
Ouvrez un terminal et demandez ce qui tourne encore avant de toucher à une route. pgrep -a openconnect liste chaque instance avec ses arguments, ce qui montre le fichier pid et le script qui lui a été donné. Un processus que vous n’attendiez pas explique le tunnel fantôme plus vite que n’importe quel journal.
Si rien ne tourne, regardez le lien. ip link show tun0 vous dit si l’interface a survécu, et ip route show dev tun0 liste les routes encore liées à celle-ci. Vérifiez ensuite le résolveur avec resolvectl status. Notez les trois sorties avant de les modifier, car c’est cet enregistrement qui vous permettra plus tard de distinguer une entrée périmée d’une nouvelle.
Une interface qui disparaît emporte normalement ses routes avec elle. Les routes qui survivent au lien signifient généralement que le processus est encore vivant ou qu’un second client possède le périphérique.
Le script auxiliaire est ce qui annule les changements
openconnect ne supprime pas lui-même l’interface, les routes ni les entrées du résolveur. Il appelle un assistant externe, /etc/vpnc/vpnc-script dans un build amont et /usr/share/vpnc-scripts/vpnc-script dans les paquets Debian et Ubuntu, choisi avec -s. Le même script qui monte le tunnel est celui qui le démonte.
Si le processus se termine sans appeler cet assistant, l’état reste. Le manuel OpenConnect est explicite : le routage et le service de noms ne fonctionneront pas correctement sans le script, et il décrit l’assistant comme le composant qui démonte l’état de l’interface à la sortie. C’est pourquoi le chemin compte lorsque vous lancez le client avec -s.
Le signal qui atteint ce chemin a changé selon les versions. Le manuel de la 7.06 traite SIGTERM comme une sortie immédiate qui saute le script. Les builds actuels documentent INT et TERM comme un arrêt propre, où la session est déconnectée et l’assistant s’exécute. Lisez la section SIGNALS du binaire que vous avez réellement au lieu de supposer l’un ou l’autre comportement.
man openconnect | sed -n '/^SIGNALS/,/^LIMITATIONS/p'
Envoyez le signal que votre build documente
Une fois le signal connu, arrêtez le processus par pid plutôt que par motif.
pgrep -a openconnect
sudo kill -INT "$(cat /var/run/openconnect.pid)"
Répétez ensuite les trois vérifications de la première section au lieu de faire confiance au code de sortie. ip link show tun0 devrait échouer, ip route show dev tun0 ne devrait rien afficher, et resolvectl status ne devrait plus lister le lien VPN.
SIGHUP n’est pas un bouton d’arrêt : il déconnecte, exécute le script et laisse la session reprenable avec --cookie. SIGUSR2 force une reconnexion immédiate. SIGKILL saute entièrement le nettoyage, ce qui est exactement l’état dont traite cet article.
Réparez le résolveur sans remplacer resolv.conf
Sur la plupart des systèmes Ubuntu /etc/resolv.conf est un lien symbolique vers systemd-resolved, pas un fichier que vous devriez modifier. Le remplacer casse la résolution de noms pour tous les réseaux, pas seulement le VPN. Supprimez plutôt l’enregistrement du tunnel :
resolvectl revert tun0
resolvectl query example.com
Si le système utilise resolvconf plutôt que systemd-resolved, l’enregistrement par interface persiste jusqu’à ce qu’on lui dise de lâcher le lien, et resolvconf -d tun0 est l’action équivalente. Vérifiez quel résolveur est utilisé avant de choisir la commande.
Une requête toujours dirigée vers un serveur derrière le lien mort reste bloquée jusqu’au délai d’expiration, et ce retard ressemble à un serveur DNS cassé plutôt qu’à une route résiduelle.
Rendez la prochaine déconnexion ennuyeuse
Gardez le même chemin de fichier pid au démarrage et à l’arrêt en passant --pid-file à chaque fois, ou lancez openconnect sous une unité dont le KillSignal correspond au signal que votre version documente. Tester d’abord au premier plan vous montre les messages d’arrêt que l’assistant imprime.
Connectez-vous, déconnectez-vous et exécutez les trois vérifications une fois. Une sortie propre ne laisse ni lien VPN, ni route VPN, ni entrée de résolveur VPN. Si l’une des trois survit, vous savez maintenant quel composant n’a pas nettoyé. L’enquête suivante part alors de cette réponse plutôt que d’une requête bloquée.