Убит openconnect: маршрутите и DNS още сочат към тунела
Мъртъв процес openconnect може да остави инсталирани маршрути и записи в резолвера. Извървете пътя на спиране, изпратете сигнала, който вашата сборка документира, и почистете.
Тунелът е спрян, но машината все още се държи така, сякаш работи: заявка виси, докато изтече времето ѝ, а маршрут сочи към интерфейс, който вече не съществува. Това е подписът на процес openconnect, който е умрял, без да стартира помощника си за прекъсване. Мрежовото състояние, което е създал, все още е инсталирано и нищо друго в системата не знае как да го премахне.
Минете през машината в реда, в който е създадено състоянието: процес, връзка, маршрут, резолвер. Всяка стъпка ви казва дали клиентът наистина е изчезнал, или само е откачен от терминала ви, и това разграничение решава дали изобщо да поправяте нещо.
Започнете с процеса, а не с конфигурацията
Отворете терминал и попитайте какво още работи, преди да пипате маршрут. pgrep -a openconnect изброява всеки екземпляр с аргументите му, което показва pid файла и скрипта, който му е даден. Процес, който не сте очаквали, обяснява фантомния тунел по-бързо от всеки журнал.
Ако нищо не работи, погледнете връзката. ip link show tun0 ви казва дали интерфейсът е оцелял, и ip route show dev tun0 изброява маршрутите, които все още са вързани към него. След това проверете резолвера с resolvectl status. Запишете и трите изхода, преди да ги промените, защото точно този запис е начинът по-късно да различите остарял запис от нов.
Изчезнал интерфейс обикновено отнася маршрутите си със себе си. Маршрути, които надживяват връзката, обикновено означават, че процесът е още жив или втори клиент притежава устройството.
Скриптът-помощник е това, което отменя промените
openconnect не премахва сам интерфейса, маршрутите или записите в резолвера. Той извиква външен помощник, /etc/vpnc/vpnc-script при upstream сборка и /usr/share/vpnc-scripts/vpnc-script при пакетите на Debian и Ubuntu, избран с -s. Същият скрипт, който вдига тунела, е и този, който го разглобява.
Ако процесът излезе, без да извика този помощник, състоянието остава. Ръководството на OpenConnect казва изрично, че маршрутизацията и услугата за имена няма да работят правилно без скрипта, и описва помощника като компонента, който разглобява състоянието на интерфейса при изход. Ето защо пътят има значение, когато стартирате клиента с -s.
Кой сигнал стига до този път се промени между версиите. Ръководството за 7.06 третира SIGTERM като незабавен изход, който пропуска скрипта. Текущите сборки документират INT и TERM като чисто спиране, при което сесията се отписва и помощникът се изпълнява. Четете секцията SIGNALS на двоичния файл, който всъщност имате, вместо да предполагате едното от двете поведения.
man openconnect | sed -n '/^SIGNALS/,/^LIMITATIONS/p'
Изпратете сигнала, който вашата сборка документира
След като знаете сигнала, спрете процеса по pid, а не по шаблон.
pgrep -a openconnect
sudo kill -INT "$(cat /var/run/openconnect.pid)"
След това повторете трите проверки от първия раздел, вместо да се доверявате на кода на изхода. ip link show tun0 трябва да се провали, ip route show dev tun0 не трябва да отпечатва нищо, и resolvectl status вече не трябва да изброява VPN връзката.
SIGHUP не е бутон за стоп: той прекъсва, изпълнява скрипта и оставя сесията възобновяема с --cookie. SIGUSR2 принуждава незабавно повторно свързване. SIGKILL пропуска почистването напълно и това е точно състоянието, за което е тази статия.
Поправете резолвера, без да заменяте resolv.conf
В повечето системи Ubuntu /etc/resolv.conf е символна връзка към systemd-resolved, а не файл, който трябва да редактирате. Замяната му чупи разрешаването на имена за всяка мрежа, не само за VPN. Вместо това премахнете регистрацията на тунела:
resolvectl revert tun0
resolvectl query example.com
Ако системата използва resolvconf, а не systemd-resolved, записът за интерфейса остава, докато не му се каже да пусне връзката, и resolvconf -d tun0 е еквивалентното действие. Проверете кой резолвер се използва, преди да изберете командата.
Заявка, все още насочена към сървър зад мъртвата връзка, виси, докато изтече времето ѝ, и това забавяне изглежда като счупен DNS сървър, а не като остатъчен маршрут.
Направете следващото прекъсване скучно
Дръжте пътя на pid файла еднакъв при стартиране и спиране, като подавате --pid-file всеки път, или стартирайте openconnect под unit чийто KillSignal съвпада със сигнала, който вашата версия документира. Тестването първо на преден план ви показва съобщенията за спиране, които помощникът печата.
Свържете се, прекъснете и изпълнете трите проверки веднъж. Чистият изход не оставя нито VPN връзка, нито VPN маршрут, нито запис в VPN резолвера. Ако един от трите оцелее, вече знаете кой компонент не е почистил. Следващото разследване тогава започва от този отговор, а не от висяща заявка.