openconnect قُتل: المسارات وDNS لا تزال تشير إلى النفق
قد تترك عملية openconnect ميتة مسارات وإدخالات محلل مثبتة. امشِ في مسار الإيقاف، وأرسل الإشارة التي توثّقها نسختك، ثم نظّف.
النفق متوقف لكن الجهاز ما زال يتصرف كأنه يعمل: يستمر الاستعلام معلقًا حتى تنتهي مهلته، ويشير مسار إلى واجهة لم تعد موجودة. هذه بصمة عملية openconnect ماتت دون تشغيل مساعد فصل الاتصال. حالة الشبكة التي أنشأتها ما زالت مثبتة، ولا شيء آخر في النظام يعرف كيف يزيلها.
امشِ في الجهاز بالترتيب الذي أُنشئت به الحالة: العملية، ثم الوصلة، ثم المسار، ثم المحلل. تخبرك كل خطوة ما إذا كان العميل قد ذهب فعلًا أم انفصل فقط عن طرفيتك، وهذا التمييز يحدد ما إذا كنت ستصلح أي شيء أصلًا.
ابدأ بالعملية، لا بالإعدادات
افتح طرفية واسأل عمّا لا يزال يعمل قبل أن تلمس أي مسار. pgrep -a openconnect يسرد كل نسخة مع وسائطها، وهو ما يُظهر ملف pid والسكربت الذي أُعطي لها. العملية التي لم تتوقعها تفسّر النفق الشبح أسرع من أي سجل.
إذا لم يكن هناك شيء يعمل، فانظر إلى الوصلة. ip link show tun0 يخبرك ما إذا كانت الواجهة قد نجت، و ip route show dev tun0 يسرد المسارات التي لا تزال مرتبطة بها. ثم تحقق من المحلل بواسطة resolvectl status. سجّل المخرجات الثلاثة كلها قبل تغييرها، لأن ذلك السجل هو ما يمكّنك لاحقًا من تمييز إدخال قديم من إدخال جديد.
الواجهة التي تزول تأخذ مساراتها معها عادةً. بقاء المسارات بعد الوصلة يعني عادةً أن العملية ما زالت حية أو أن عميلًا ثانيًا يملك الجهاز.
سكربت المساعد هو ما يتراجع عن التغييرات
لا يزيل openconnect الواجهة أو المسارات أو إدخالات المحلل بنفسه. بل يستدعي مساعدًا خارجيًا، /etc/vpnc/vpnc-script في بناء المنبع و /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 تحت وحدة يكون KillSignal فيها مطابقًا للإشارة التي توثّقها نسختك. الاختبار في المقدمة أولًا يريك رسائل الإيقاف التي يطبعها المساعد.
اتصل وافصل وشغّل الفحوص الثلاثة مرة واحدة. الخروج النظيف لا يترك وصلة VPN ولا مسار VPN ولا إدخال محلل VPN. إذا نجا واحد من الثلاثة، فأنت تعرف الآن أي مكوّن فشل في التنظيف. عندها يبدأ التحقيق التالي من ذلك الجواب لا من استعلام معلق.