كيفية تشغيل عملية Linux واحدة خارج نفق WireGuard
امنح برنامجًا واحدًا سياق شبكة خاصًا به حتى يخرج من مضيف WireGuard بنفق كامل، ثم أصلح قواعد التمرير والتعليم التي تعيقه.
لا يمكنك استثناء برنامج من مضيف WireGuard بنفق كامل عن طريق تعديل المسارات. فالمسارات تختار مسارًا حسب الوجهة، وما تريد استثنائه هو عملية، لذا لا يملك النواة ما يطابقه. النهج القابل للتنفيذ هو منح تلك العملية سياق شبكة خاصًا بها: مساحة أسماء لها واجهتها وعناوينها ومسارها الافتراضي، وتُوصل بالمضيف عبر زوج veth. شغّلت هذا على Ubuntu 24.04 مع wireguard-tools 1.0.20210914، ولم تكن مساحة الأسماء هي المشكلة أبدًا — بل سياسة التمرير في المضيف وقواعد التعليم في النفق.
اختر نوع السياق الذي تحتاجه أولًا
تظهر شكلان في الممارسة. إذا كان المضيف يشغّل نفقًا كاملًا ويجب أن يخرج برنامج واحد عبر مسار مزود الخدمة، فأنت تبني مساحة أسماء ثانية وتوصلها بالمضيف وتدع المضيف يمرر البيانات ويترجمها لها. وإذا كانت مساحة الأسماء تحمل بالفعل واجهة VPN وتحتاج فقط إلى تشغيل أمر بداخلها، فهذه حالة أمر ip netns exec العادي، ومعظم عمل التوجيه منجز بالفعل.
لا يمنحك أي من الشكلين قاعدة مقيدة بمعرّف عملية واحد. يطابق Netfilter العناوين والمنافذ والعلامات والواجهات؛ ولا يوجد جدول توجيه لكل عملية. يمكن للتعليم أن يوجّه البيانات، لكن يجب تطبيق العلامة على حزم حددتها بالفعل، وهذه هي المشكلة نفسها على طبقة أدنى. مساحة الأسماء تفصل المكدس بأكمله لشجرة العمليات تلك، ولهذا فهي الإجابة المعتادة.
إذا كان الشرط حقًا ألا يخرج أي شيء من النفق، فأوقف النفق بدلًا من ذلك. مساحة الأسماء موجودة للحالة المختلطة: برنامج واحد خارج، وكل شيء آخر داخل، على الجهاز نفسه، في الوقت نفسه.
أنشئ السياق الثاني واربطه بالمضيف
تصميم توضيحي: يمتلك المضيف واجهة WireGuard تحمل المسار الافتراضي، ومساحة أسماء شبكة تُسمى clearnet موصولة بالمضيف عبر زوج veth. العناوين أدناه أمثلة.
ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1
تستطيع مساحة الأسماء هذه الآن الوصول إلى المضيف ولا شيء آخر. على المضيف تمرير البيانات وإعادة كتابة عنوان المصدر، لأن 192.168.100.0/24 خاصة والموجه الأعلى لا يملك مسارًا للعودة إليها:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE
تحقق من جانب مساحة الأسماء قبل المضي قدمًا.ip netns exec clearnet ip route يجب أن يُظهر مسار veth والمسار الافتراضي عبر 192.168.100.1، ويجب أن يستجيب ping إلى ذلك العنوان. إذا فشل ping إلى عنوان المضيف، فالعناوين أو حالة الوصلة خاطئة ولن تساعد أي قاعدة جدار حماية.
عندما تُحلّ الأسماء ولا يعود شيء، اقرأ FORWARD
يبدو الفشل الكلاسيكي كخطأ في التوجيه: تحل مساحة الأسماء اسمًا، وتغادر الحزمة، ولا يصل أي رد أبدًا. على المضيفين الذين يوزّعون سياسة FORWARD من نوع DROP — تفعل ذلك عدة توزيعات ومعظم الصور المحصّنة — تُسقط الحزمة في طريقها، والخطأ الذي يطبعه التطبيق لا يقول شيئًا عن التصفية.
اقرأ السلسلة قبل إضافة أي شيء:
iptables -S FORWARD
nft list chain inet filter forward
ثم اسمح بالبيانات في الاتجاهين، مع عدادات، حتى تعرف ما إذا كانت القاعدة قد طابقت يومًا:
iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'
القاعدة التي عدّاد حزمها صفر ليست في المسار. إما أن أسماء الواجهات تختلف عما افترضته، أو أن قاعدة سابقة في السلسلة قبلت الحزمة أو أسقطتها أو أعادتها أولًا. أصلح الترتيب، لا نص القاعدة.
بيانات الرد هي النصف الذي ينساه الناس. تحتاج قاعدة العودة إلى اسم veth نفسه زائد مطابقة حالة الاتصال، أو قبول واجهة عادي إذا كنت تبقي السياسة مفتوحة. أضف قاعدة الصادر وحدها فتعود الأعراض الأصلية، وقاعدتك الجديدة جالسة هناك وتبدو صحيحة.
أبعِد قواعد التعليم الخاصة بالنفق عن المسار الجديد
هذه الخطوة تحوّل مساحة أسماء عاملة إلى أخرى تسرّب. تُثبّت إعدادات WireGuard عادة سياسة علامة جدار حماية مع قواعد التوجيه الخاصة بها وجدول مخصص، فتعود الحزم غير المعلّمة إلى الجدول الرئيسي بينما تستخدم الحزم المعلّمة جدول النفق. تُقيَّم البيانات الممررة من مساحة الأسماء مقابل التوجيه بالسياسة أثناء خروجها، وبحسب طريقة كتابة تلك القواعد قد تهبط في جدول النفق.
إضافتان تفصلان المسارين. عُد مبكرًا في سلسلة mangle لشبكة مساحة الأسماء الفرعية، وأضف قاعدة قائمة على المصدر تضع تلك الشبكة الفرعية في الجدول الرئيسي:
iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100
الأولوية 100 تتقدم على قواعد النفق على مضيفي، لذا يقرر الجدول العادي لتلك المصادر. لا تنسخ الرقم بشكل أعمى: الأولويات التي wg-quick يثبتها تختلف بين الإصدارات وبين إعدادات IPv4 و IPv6، لذا شغّل ip rule show واختر أولوية تقع أمام قواعد النفق على جهازك.
تحقق باستخدام بحث خاص بالمصدر بدلًا من الوثوق بقائمة القواعد:
ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1
إذا أبلغ الأمر الأول عن واجهة WireGuard، فالقاعدة الجديدة ليست أمام سياسة النفق بعد. وإذا أبلغ عن واجهة WAN بينما لا يزال الثاني يُظهر المسار الافتراضي لـ veth، فالمضيف ومساحة الأسماء غير متفقين وعليك إعادة قراءة جدولي التوجيه.
ابدأ العملية التي تفتح الاتصال
بدء الأمر سطر واحد، لكن ابدأ العملية التي تنشئ المقبس فعليًا.ip netns exec clearnet curl -s https://ifconfig.me هو أصغر اختبار صادق: يُظهر العنوان الذي تقدّمه مساحة الأسماء للعالم، لا العنوان الذي سيستخدمه المضيف.
بالنسبة لخدمة، اربط مساحة الأسماء بالمسار كي تبقى العملية فيها طوال حياتها:
[Service]
NetworkNamespacePath=/run/netns/clearnet
التطبيقات الرسومية هي حيث يفشل نهج السطر الواحد بهدوء. المتصفح الذي يُطلق من قائمة يسلّم الطلب غالبًا إلى نسخة تعمل بالفعل خارج مساحة الأسماء، فتظهر النافذة الجديدة وما زالت البيانات تخرج عبر النفق. امنحه ملف تعريف منفصلًا كي تُنشأ نسخة جديدة فعلًا، ثم تحقق من سياق العملية بدلًا من التخمين:
readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet
يجب أن يتطابق المخرجان. يعمل الاختبار نفسه مع أي برنامج طويل التشغيل، ويستحق القيام به مرة لكل تطبيق بدلًا من افتراض أن المشغّل فعل ما قصدته.
يتطلب حل الأسماء قرارًا خاصًا به. إنشاء مساحة أسماء لا يمنحها إعداد محلل أسماء؛ وتُدعم الملفات لكل مساحة أسماء عبر /etc/netns/<name>/resolv.conf، وبدونها ترث سلوكًا يسهل قراءته خطأً. يحتاج IPv6 إلى المعالجة نفسها: إذا لم يكن لمساحة الأسماء مسار افتراضي v6 بينما يفضّل التطبيق v6، فقد تتعطل الطلبات قبل الرجوع، ما يبدو كنفق معطل.
افحص الإطار، لا عنوان الخروج فقط
عنوان عام عامل يثبت المسار، لا المتطلب كله. امشِ في الباقي بهذا الترتيب:
ip netns exec clearnet ip route get 1.1.1.1يُظهر المسار الافتراضي لـ veth، لا واجهة WireGuard.- تزداد عدادات FORWARD على القاعدتين أثناء تشغيل طلب.
- تُبلغ عملية التطبيق عن inode مساحة الأسماء الذي تتوقعه.
- بعد إعادة التشغيل توجد مساحة الأسماء قبل أن تبدأ الخدمة؛ والوحدة التي تعمل قبل ذلك تفشل، أو الأسوأ، تعمل خارج مساحة الأسماء.
ثم قرر ما ينبغي أن يحدث عندما يسقط النفق. تستمر مساحة الأسماء في العمل، وهذا هو هدف التمرين وأيضًا الخطر: يبقى البرنامج المستثنى متصلًا بينما يتوقف كل شيء آخر. سجّل ذلك كخيار سياسة، وكن واضحًا بشأن ما لا يغطيه الاستثناء — فالهوية الحسابية وحالة المتصفح المحفوظة ومزود DNS لديك كلها خارج نطاق مساحة أسماء الشبكة، والتعامل مع الاستثناء كإخفاء للهوية هو الخطأ الذي يعيش أطول من الإعداد.