يتصفح المضيف عبر النفق بينما الحاوية المجاورة له لا تصل إلى شيء. نشر منفذ من حاوية تشغّل عميل VPN خاصًا بها أسوأ: يصل الطلب ولا يغادر الرد أبدًا. كلاهما قرار توجيه على المضيف، وDocker مجرد رسول.

ثلاثة أسئلة تحدد أي الحالتين أمامك، ولا تستغرق أكثر من دقيقة.

فشلان يظهران بالطريقة نفسها

الأول مشكلة في مسار العودة. يُترجم المنفذ المنشور إلى الحاوية، ويصل الطلب، ويُوجَّه الرد عبر المسار الافتراضي للمضيف، الذي وجّهه عميل OpenVPN إلى tun0. يغادر الرد من عنوان لا يتوقعه النظير البعيد، فيُسقط. الثاني تصادم بادئات: جسر Docker الافتراضي يملك 172.17.0.0/16 ونفق المؤسسة يدفع النطاق نفسه.

تُصلَح الأولى بجدول توجيه، والثانية بإعادة ترقيم الجسر. التعديل قبل معرفة أي الحالتين هو ما يعطّل حاوية عاملة.

قرر بثلاثة أسئلة

السؤال الأول: هل يختفي الفشل عند إيقاف VPN؟ إذا كان كل شيء يعمل والنفق متوقف، فاشتبه في مسار العودة. السؤال الثاني: هل يسرد ip route show table all البادئة نفسها مرتين، مرة على جسر ومرة على tun0؟ هذا هو التصادم. السؤال الثالث: هل العنوان المتأثر حاوية أم جهاز ضيف NAT أم جهاز ضيف موصول بجسر؟

السؤال الثالث مهم لأن لكل حالة إصلاحًا صحيحًا مختلفًا، وتطبيق إصلاح الحاوية على جهاز ضيف libvirt يهدر أمسية كاملة.

ip route
ip route show table all | grep -E '172\.1[7-9]|10\.8'
docker network inspect bridge --format '{{.IPAM.Config}}'

مسار العودة: جدول لعنوان مصدر واحد

عندما يجب أن تغادر حركة الحاوية عبر الواجهة الفيزيائية بينما يستخدم المضيف نفسه النفق، فإن التوجيه المعتمد على المصدر هو أصغر تغيير. أضف قاعدة تطابق عنوان الحاوية وأرسلها إلى جدول مخصص. لا يتحرك أي شيء آخر على المضيف.

ip rule add from 172.22.0.3 lookup 10
ip route add default via 172.22.0.1 table 10

كل حزمة مصدرها ذلك العنوان تراجع جدول 10 أولًا، وجدول 10 يرسلها إلى بوابة الجسر بدلًا من النفق.

تحقق باستخدام ip route get 1.1.1.1 from 172.22.0.3. يجب أن تذكر الإجابة واجهة الجسر، لا tun0. القواعد المضافة بهذه الطريقة تختفي عند إعادة التشغيل، لذا ضعها في الوحدة أو خطاف الشبكة الذي يملك الحاوية.

النمط نفسه ينطبق على حاوية WireGuard، حيث يحتاج مسار الرد أيضًا إلى قاعدة صريحة.

تصادم البادئات: أعد ترقيم الجسر

جدول التوجيه يرسل بادئة واحدة إلى مكان واحد. إذا دفع VPN البادئة 172.17.0.0/16 بينما جسر Docker موجود بالفعل هناك، تفوز المتريكية الأقل: يثبّت Docker مساره المتصل عند متريكية 0، ويصل المسار المدفوع عند 50. ثم يبدو النفق معطلًا بينما يستمر Docker في العمل، أو العكس، حسب ترتيب التثبيت. أعد ترقيم الجسر بدلًا من مصارعة المتريكية.

{
  "bip": "10.200.0.1/24",
  "default-address-pools": [{"base": "10.201.0.0/16", "size": 24}]
}

أعد تشغيل Docker بعد التغيير وأعد إنشاء الشبكات المبنية بمجمّع العناوين القديم. تغيير المتريكية بدلًا من ذلك ينقل الصراع فقط إلى الإقلاع التالي.

الأجهزة الافتراضية تحتاج إجابة مختلفة مرة أخرى

جهاز ضيف libvirt على شبكة NAT الافتراضية يرث توجيه المضيف ويتوقف عن الوصول إلى الخارج بمجرد أن يملك نفق المضيف المسار الافتراضي. نقل الجهاز الضيف إلى جهاز موصول بجسر أو macvtap يمنحه مساره الخاص على الشبكة الفيزيائية. في virt-manager، أضف عتادًا، اختر Network، اضبط المصدر على جهاز المضيف macvtap، أبقِ virtio كنموذج، ثم عطّل واجهة NAT القديمة.

جهاز macvtap الضيف عادةً لا يستطيع الوصول إلى مضيفه. هذا سلوك متوقع لا عيب، ويجب أن يرد في الملاحظة التي تتركها.

بالنسبة لجهاز ضيف يحتاج فقط شبكة LAN المحلية للمضيف، قد يملك عميل المزوّد المفتاح المفقود: مع Mullvad، يعيد mullvad lan set allow إمكانية الوصول المحلية دون لمس libvirt. وعندما يجب أن تكون حاوية قابلة للوصول عبر النفق فقط، اربط المنفذ المنشور بعنوان النفق، -p 10.8.0.5:8080:8080، بدلًا من نشره على كل عنوان.

مقالات ذات صلة