تعديل resolv.conf لا يُصلح DNS بعد فصل الـ VPN
مُحلِّل نفق ميت في أعلى القائمة يكلّفك مهلة انتظار واحدة لكل استعلام. تحقّق ممن يملك الملف، وأعد ضبط حالة الوصلة، وتوقّف عن تعديل المخرجات المولّدة.
تفصل الـ VPN، ولا يزال ping 1.1.1.1 يُجيب، وكل استعلام اسم يتعلّق قبل أن تستسلم الصفحة أخيرًا. ثم يُظهر cat /etc/resolv.conf خادم أسماء لم يوجد قط إلا داخل النفق، وهو عادةً أول القائمة. يبدو حذف ذلك السطر وكأنه يحل المشكلة لنحو عشر دقائق، إلى أن يُعيده تعليقٌ أو تجوال Wi-Fi أو إعادة تشغيل. الملف الذي عدّلته ليس الإعداد؛ بل هو عرض لحالة الوصلة يملكها مكوّن آخر.
لماذا يكلّفك إدخال واحد قديم ثوانٍ لكل استعلام
يمشي مُحلِّل glibc على قائمة خوادم الأسماء بالترتيب وينتظر انقضاء مهلة قبل تجربة التالي، وresolv.conf(5) يحدّ تلك القائمة بثلاثة إدخالات. ضع مُحلِّلًا من جهة النفق مثل 10.8.0.1 في الأعلى بعد أن يزول النفق، وسيدفع كل استعلام ثمن المهلة قبل أن ينتقل إلى خادم يُجيب. ولهذا تبدو العَرَض كوصلة ميتة لا كخطأ DNS: المتصفحات تتعطّل، وتنتهي مهلتها، وأحيانًا تُقدّم عنوانًا مخزّنًا يصبح قديمًا لاحقًا.
وهذا يفسّر أيضًا لماذا تصل الشكوى بصيغة «الإنترنت معطّل». فـ ping إلى عنوان IP يثبت أن الوصلة سليمة، ما يجعل العطل يبدو كأنه في التطبيق. قائمة المُحلِّل هي أول ما يُقرأ وآخر ما يُعدَّل.
الأسطورة: resolv.conf ملف إعدادات
اسأل ما هو المسار فعلًا قبل أن تغيّره:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
على مضيف يعمل بـ systemd-resolved هو رابط رمزي إلى ملف بديل يشير إلى 127.0.0.53، والخوادم الحقيقية تعيش في حالة لكل وصلة يطبعها resolvectl. على مضيف يعمل بـ NetworkManager قد يكون ملفًا يكتبه NetworkManager من الاتصال النشط. ومع بعض عملاء البائعين يكون ملفًا عاديًا يُعاد كتابته في مكانه عند الاتصال، وإن كنت غير محظوظ لا يُستعاد أبدًا عند الفصل. هؤلاء ثلاثة مالكين مختلفين، وتعديل الأولين يدويًا إما لا يفعل شيئًا وإما يدوم حتى حدث الشبكة التالي.
resolvectl status هو العرض الذي يقول الحقيقة: خوادم DNS لكل وصلة، ونطاقات التوجيه، وهل وصلة النفق ما زالت موجودة. وresolvectl query example.com يذهب أبعد ويُظهر أي واجهة أجابت. استخدم الاثنين قبل لمس أي ملف، وتذكّر أن متصفحًا لديه DNS آمن خاص به يتجاهل ذلك كله.
اعرف المالك قبل أن تعدّل أي شيء
عادةً تتنافس ثلاثة مكوّنات على الإعداد نفسه: systemd-resolved وNetworkManager وما ثبّته عميل الـ VPN. حدّد المكوّن الحيّ أولًا:
systemctl is-active systemd-resolved
nmcli connection show --active
ps aux | grep -E "openvpn|wg-quick|vpn"
إذا كان resolved نشطًا والرابط الرمزي يشير إلى ملفه البديل، فالملف العام مخرَج مولّد وتعديلك تجميلي. وإذا كان NetworkManager يملك الاتصال، فخوادم الأسماء تنتمي إلى ملف تعريف الاتصال، لذا الإصلاح تغيير خاصية عبر nmcli لا تعديل ملف. وإذا كان عفريت من البائع يعمل، فمسار الاستعادة الخاص به هو الوحيد الذي ينجو من الاتصال التالي.
نظّف حالة الوصلة التي تركها العميل
العميل المقتول لا يستطيع تشغيل خطاف التنظيف الخاص به. لا يمكن التقاط SIGKILL إطلاقًا، بينما يمكن التقاط SIGINT وSIGTERM، لذا نفق «توقّف للتو» بعد قتل قسري كثيرًا ما يترك تسجيل الواجهة وإدخال المُحلِّل معًا في مكانهما. ابحث عن الـ PID المحدد وأرسل الإشارة إلى ذلك وحده:
ps aux | grep -E "openvpn|wg-quick"
sudo kill <pid>
resolvectl revert tun0
لا تمدّ يدك إلى pkill -f vpn أو killall vpn قبل قراءة قائمة التطابقات كاملة. فالخيار -f يطابق سطر الأوامر كله، لذا قد يُنهي سكربت غلاف أو جلسة محرّر أو عملية غير ذات صلة يحتوي مسارها على السلسلة. إنهاء العملية الخطأ في منتصف التشغيل هو كيف يتحول مشكل مُحلِّل إلى ملف مفقود.
resolvectl revert يعيد ضبط إعداد DNS الوقتي لتلك الوصلة، وهو أضيق من إعادة تشغيل المُحلِّل وأضيق بكثير من تعديل الملف العام. وإذا كانت وصلة النفق قد زالت كليًا، فإن systemctl restart NetworkManager يعيد بناء حالة الاتصال وهو الخطوة التي تعود إليها خيوط المصدر دائمًا. راقب مدير خدمة لديه Restart=always، لأنه قد يعيد عميلًا مقتولًا، وإعدادات DNS الخاصة به، إلى العمل مباشرة.
الاتجاه الآخر: DNS مدفوع لم يصل قط
الصورة المعكوسة للإدخال القديم هي نفق بلا أي مُحلِّل صالح. خيار DNS في ملف التعريف طلبٌ؛ وعلى المكوّن الذي يدير الاتصال أن يسلّمه إلى المُحلِّل. وإذا أظهر السجل أن الخادم استُقبل لكن وصلة النفق لا تحمل أي إعدادات DNS، فالتكامل هو الناقص، لا الخادم.
اختبر التسليم بأدائه يدويًا، وهذا يفصل بين «الخادم خطأ» و«لم يطبّقه أحد»:
resolvectl dns tun0 10.10.10.10
resolvectl domain tun0 ~.
نطاق التوجيه الشامل يرسل كل اسم إلى تلك الوصلة، وهو ما يريده عميل النفق الكامل وما يجب ألا يستخدمه DNS المنقسم. تزول هذه الإعدادات عند الاتصال التالي. لجعلها دائمة في NetworkManager، عطّل DNS التلقائي، واضبط الخادم على الاتصال، وأضف النطاق:
nmcli connection modify office ipv4.ignore-auto-dns yes
nmcli connection modify office ipv4.dns 10.10.10.10
nmcli connection modify office ipv4.dns-search "~."
لنفق شركة يجب أن يُجيب على الأسماء الداخلية فقط، اسرد تلك المناطق بعلامة مدّ في البداية بدلًا من الشامل، ليبقى استخدام الأسماء العامة للمُحلِّل المحلي.
حلول مؤقتة تصبح الانقطاع التالي
نسخ resolv.conf قبل الاتصال واستعادته بعده سطر مشروع في دليل تشغيل، وهو حل مؤقت لا إصلاح. وهو يفشل بالضبط حين يهمّ الأمر، لأن تعطّلًا أو إعادة تشغيل قسرية تتخطى الاستعادة. اكتبه كحل مؤقت كي لا يبني عليه الشخص التالي.
تعطيل systemd-resolved وكتابة خوادم عامة ثابتة هو الحركة الشائعة الأخرى. يجعل الاتصال والفصل متوقعين ويزيل DNS لكل وصلة عن كل شبكة أخرى، وهذا يكسر DNS المنقسم للأسماء الداخلية ويُبطل الغرض من نفق يُقصد به إبقاء الاستعلامات داخله. تثبيت resolvconf وتثبيت خوادم عامة يكلّف الشيء نفسه بطبقة إضافية. اعتبر أيًّا منهما تشخيصًا: فإن أعاد التصفح، تكون قد تعلّمت أن تكامل المُحلِّل هو المعطوب، لا أن الخوادم العامة صحيحة.
الإصلاح الدائم هو مالك واحد لكل طبقة: قرّر أي مكوّن يملك DNS وصلة النفق وأيّهم يملك الافتراضي العام، واكتب ذلك، وأزل الآخرين من المسار. ثم تحقّق بعد الفصل باسم لا يحلّه إلا الـ VPN. فإن أجاب اسم خاص، فالتسجيل لم يُزل؛ وإن لم يُحلّ شيء إطلاقًا، فالملف يشير إلى خادم لم يبق له وجود. كلاهما مرئي في resolvectl قبل أن تفتح متصفحًا.