تطبيق داخل مساحة أسماء شبكة VPN لا يمكن الوصول إليه من الشبكة المحلية
تمنح مساحة أسماء الشبكة برنامجًا واحدًا نفقًا خاصًا به وواجهة استرجاع خاصة به. انشر منفذه فقط عبر قفزة socat أو زوج veth بدلًا من المضيف.
خدمتك تعمل على الجهاز، والنفق قائم، ومع ذلك لا يزال المتصفح على مكتبك ينتظر دون رد. لا شيء معطوب بالمعنى المعتاد: التطبيق يستمع داخل مساحة أسماء شبكة، وتلك الحزمة غير مرئية للشبكة المحلية. واجهة الاسترجاع الخاصة به تنتمي إلى مساحة الأسماء، لذا لا يملك عميل على جهاز آخر أي عنوان يصل إلى المنفذ. قفزة واحدة مقصودة، أو زوج veth واحد، يصلح الأمر دون تحريك بقية المضيف.
لماذا لا يستجيب شيء على عنوان الشبكة المحلية
مساحة الأسماء حزمة شبكة كاملة: واجهات ومسارات وقواعد جدار حماية وواجهة استرجاع خاصة. العملية التي تُطلق عبر ip netns exec ترى تلك الحزمة ولا ترى غيرها، لذا يُحل العنوان الذي تربطه داخل مساحة الأسماء وحدها. عنوان 127.0.0.1 الخاص بالمضيف هو واجهة استرجاع أخرى تمامًا.
لهذا يفشل curl على المضيف بينما ينجح الأمر نفسه داخل مساحة الأسماء. التطبيق سليم؛ العنوان ببساطة غير موجود في حزمة المضيف.
انشر منفذًا واحدًا عبر قفزة socat
socat يجسر الحزمتين في مساحة المستخدم، وهذا يكفي عندما يجب أن يعبر منفذ TCP واحد. يستمع الجانب المضيف على الشبكة المحلية، ولكل اتصال مقبول يشغّل socat ثانيًا داخل مساحة الأسماء يتصل بواجهة استرجاع التطبيق. تصل العملية الداخلية إلى التطبيق تمامًا كما يفعل عميل محلي. لا يتغير شيء في توجيه مساحة الأسماء، فيواصل التطبيق استخدام النفق كمخرجه الوحيد.
socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork
تحتاج العملية الخارجية إلى root أو إلى الإمكانية اللازمة لدخول مساحة الأسماء. إذا سقط الـ VPN يفقد التطبيق مساره ويفشل المنفذ المنشور مغلقًا، وهذا هو السلوك الذي تريده من سجن.
استخدم زوج veth عندما يعبر أكثر من منفذ
زوج veth هو الجواب الصحيح عندما يجب أن تعبر عدة منافذ أو بروتوكولات، أو عندما تحتاج مضيفات أخرى إلى بدء اتصالات. يبقى أحد الطرفين في المضيف وينتقل الآخر إلى مساحة الأسماء، و/30 صغير يمنح الجانبين عنوانًا مستقرًا. ثم يرسل مسار مضيف عنوان مساحة الأسماء عبر الزوج.
ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpn
ip addr add 10.77.0.1/30 dev veth0
ip link set veth0 up
ip netns exec vpn ip addr add 10.77.0.2/30 dev veth1
ip netns exec vpn ip link set veth1 up
لا تضف مسارًا افتراضيًا عبر المضيف إلا إذا كنت تنوي كسر السجن. ينبغي أن يبقى النفق هو المخرج، لذا لا يمكن الوصول عبر الزوج إلا إلى عنوان الخدمة المنشور. أعطِ مساحة الأسماء ملف محللًا خاصًا بها أيضًا، لأن ip netns exec يقرأ /etc/netns/vpn/resolv.conf وبدونه يكون تحليل الأسماء داخل السجن فارغًا.
اختبر من جهاز آخر، لا من المضيف
شغّل الاختبار من جهاز ثانٍ، لأن المضيف يستطيع الوصول إلى مستمع محلي عبر مسارات لا تقول شيئًا عن الشبكة المحلية. تحقق أولًا مما ارتبط به التطبيق فعليًا داخل مساحة الأسماء، ثم اتصل بالعنوان المنشور من الخارج. الارتباط بكل عنوان هناك لا يوسّع السجن، لأن البدل العام لا يزال ينتمي إلى مساحة الأسماء ولا يمكن للشبكة المحلية رؤيته.
ip netns exec vpn ss -lntp
إذا نجح اتصال المضيف وفشل اتصال الشبكة المحلية، فالقطعة الناقصة هي القفزة أو المسار، لا عنوان الربط. ابدأ OpenVPN داخل مساحة الأسماء بدلًا من نقل جهاز tun حي إليها، لأن نقل الواجهة يوقفها وقد يمسح مسارات لا تستطيع إصلاحها من الخارج بعد ذلك. أبقِ أوامر الاستعادة على الطرفية، لا داخل السجن.