Тунелот е исклучен, но машината уште се однесува како да е вклучен: барањето виси додека не истече времето, а рута покажува кон интерфејс што повеќе не постои. Тоа е потписот на openconnect процес што умрел без да го стартува својот помошник за исклучување. Мрежната состојба што ја создал уште е инсталирана, и ништо друго во системот не знае како да ја отстрани.

Поминете ја машината по редоследот по кој е создадена состојбата: процес, врска, рута, резолвер. Секој чекор ви кажува дали клиентот навистина си заминал или само се откачил од вашиот терминал, и таа разлика одлучува дали воопшто да поправате нешто.

Започнете со процесот, а не со конфигурацијата

Отворете терминал и прашајте што е уште активно пред да допрете рута. pgrep -a openconnect ја наведува секоја инстанца со нејзините аргументи, што ја покажува pid датотеката и скриптата што ѝ е дадена. Процес што не сте го очекувале го објаснува фантомскиот тунел побрзо од секој лог.

Ако ништо не работи, погледнете ја врската. ip link show tun0 ви кажува дали интерфејсот преживеал, и ip route show dev tun0 ги наведува рутите што остануваат врзани за него. Потоа проверете го резолверот со resolvectl status. Запишете ги сите три излези пред да ги промените, бидејќи токму тој запис е начинот подоцна да разликувате застарен запис од нов.

Интерфејс што исчезнува обично ги зема своите рути со себе. Рути што ја надживуваат врската обично значат дека процесот уште е жив или дека вториот клиент го поседува уредот.

Токму помошната скрипта ги враќа промените

openconnect сам не ги отстранува интерфејсот, рутите или записите во резолверот. Тој повикува надворешен помошник, /etc/vpnc/vpnc-script во upstream build и /usr/share/vpnc-scripts/vpnc-script во пакетите Debian и Ubuntu, избран со -s. Истата скрипта што го крева тунелот е и онаа што го расклопува.

Ако процесот излезе без да го повика тој помошник, состојбата останува. Упатството за OpenConnect експлицитно наведува дека рутирањето и службата за имиња нема да работат правилно без скриптата, и го опишува помошникот како компонента што при излез ја расклопува состојбата на интерфејсот. Затоа патеката е важна кога го стартувате клиентот со -s.

Кој сигнал стигнува до таа патека се промени меѓу верзиите. Упатството за 7.06 го третира SIGTERM како веднаш излез што ја прескокнува скриптата. Тековните build-ови ги документираат INT и TERM како чисто запирање, при што сесијата се одјавува и помошникот се извршува. Прочитајте го делот SIGNALS на бинарната датотека што навистина ја имате, наместо да претпоставувате едно од двете однесувања.

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

Испратете го сигналот што го документира вашиот build

Кога ќе го знаете сигналот, запрете го процесот по 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 резолверот. Ако една од трите преживее, сега знаете кој компонент не исчистил. Следната истрага тогаш започнува од тој одговор, а не од висечко барање.

Поврзани статии