كيف تثبّت تطبيق لينكس واحدًا على شبكة VPN بقواعد UID
قاعدة UID لا ترى إلا المقابس المحلية، والاستثناء المعتاد للواجهة المدوّرة يقتل النفق. وجّه الحساب أولًا، ثم صفِّ وتحقق من كل خطوة.
تثبيت برنامج واحد على VPN في لينكس هو في الأساس مشكلة توجيه، وقاعدة الجدار الناري لا تحدد إلا ما يحدث بعد اختيار المسار۔ إذا طابقت UID البرنامج في OUTPUT قبل أن يملك النفق المسار الافتراضي، فستسقط القاعدة الحركة نفسها التي كنت تريد حمايتها۔ والقاعدة نفسها لا ترى أيضًا عملية المحلل التي تجيب استعلامات DNS للبرنامج۔ اضبط الترتيب بشكل صحيح وسيصبح حساب واحد بلا امتيازات محدّدًا موثوقًا للنفق المنقسم۔
امنح الحساب مسارًا قبل الحكم
مطابقة المالك تجيب سؤالًا واحدًا: هل بنى المقبس المحلي الذي يتبع هذا UID الحزمة؟ لا تختار واجهة، ولا تستطيع تحريك الحركة التي يرسلها الجدول الرئيسي أصلًا عبر بطاقة الشبكة الفعلية۔ ولهذا تحجب قاعدة UID بلا مسار مطابق البرنامج بدلًا من إعادة توجيهه۔
أرسل الحساب أولًا عبر جدوله الخاص، ثم دع الجدار الناري يؤكد النتيجة۔ يعمل هذا على مضيف يفهم iproute2 فيه uidrange، وهو ما ip rule help يبلّغ عنه في سطر واحد۔ يحمل الجدول 100 مسارًا افتراضيًا عبر النفق، والقاعدة ترسل UID 1000 وحده إلى ذلك الجدول۔ كل شيء آخر يبقى على الجدول الرئيسي ويواصل استخدام الوصلة الفعلية۔
ip rule add uidrange 1000-1000 table 100 ip route add default dev tun0 table 100
الحساب الثاني الذي يحتاج نفقًا مختلفًا يحصل على الجدول 101 وقاعدته الخاصة، لأن ملفَي تعريف لا يمكن أن يملكا المسار الافتراضي في الجدول نفسه معًا۔ ملفات NetworkManager تعريف على مستوى النظام، لذا يبقى هذا الجزء يدويًا، وتختفي القواعد عند إعادة التشغيل ما لم يعِدها شيء۔ اكتب الجداول في سكربت بدء إلى جانب تعريف النفق، حتى لا تترك إعادة الاتصال حسابًا على المسار الخطأ۔
لماذا يقتل استثناء الواجهة المدوّرة النفق
معظم النسخ المنسوخة من القاعدة تسقط كل حزمة لا تخرج عبر الواجهة المدوّرة۔ النفق ليس واجهة مدوّرة، لذا يسقط ذلك الشكل حركة النفق أيضًا، وتبدو النتيجة كـ VPN ميت لا كخطأ في الجدار الناري۔
بحلول وقت تشغيل OUTPUT، يكون النواة قد اختار واجهة خروج بالفعل، لذا -o يُقارن بجواب المسار لا بترويسة الحزمة۔ ويُستشار مطابقة المالك في OUTPUT وPOSTROUTING فقط، والحزم المُمرَّرة لا تحمل مقبسًا ليقرأه۔ يعني هذا المزيج أن الاستثناء يجب أن يسمّي واجهة النفق وينفي تلك المطابقة، لا أن ينفي الواجهة المدوّرة۔
لا تزال الواجهة المدوّرة تستحق ACCEPT خاصًا بها فوق DROP، لأن أول حزمة DNS من البرنامج تذهب إلى المخزن المحلي عبر lo۔ ضع القاعدتين بهذا الترتيب، فيصل الحساب إلى المخزن، ثم إلى النفق، ولا شيء آخر۔
iptables -I OUTPUT 1 -o lo -m owner --uid-owner vpnapp -j ACCEPT iptables -A OUTPUT -m owner --uid-owner vpnapp ! -o tun0 -j DROP
IPv6 مجموعة قواعد منفصلة، والزوج المخصص لـ v4 فقط يترك ip6tables دون مساس۔ البرنامج الذي يفضّل سجلات AAAA سيخرج حينها عبر الوصلة الفعلية دون أن يصل إلى DROP أبدًا۔ اعكس القاعدتين في ip6tables، أو عطّل IPv6 على المضيف عندما لا يحمل النفق عنوان v6۔ القواعد المضافة يدويًا تختفي أيضًا عند إعادة التشغيل، فاحفظها بـ netfilter-persistent save أو أعد بناء المنطق نفسه كجدول nftables تحمّله وحدة الإقلاع۔
تأتي أجوبة DNS من عملية أخرى
استعلام البرنامج إلى 127.0.0.53 يعبر ACCEPT الخاص بالواجهة المدوّرة، وهناك تتوقف مطابقة UID۔ يمرر محلل المخزن الاستعلام صعودًا من حساب خدمته الخاص، فقاعدة مربوط بـ vpnapp لا ترى الاستعلام الثاني أبدًا۔ إذا اختار المحلل خادمًا محليًا للوصلة، عادت الأجوبة عبر بطاقة الشبكة الفعلية بينما تبقى حزم البرنامج نفسها في النفق۔ النتيجة المرئية نفق عامل بأسماء معطلة، أو أسماء يجيب عنها خادم لم تختره أنت۔
أصلح دقة الأسماء على وصلة النفق لا على التطبيق۔ أعط ملف تعريف النفق خادم DNS ونطاق توجيه، ثم أكّد بـ resolvectl query وresolvectl status tun0 أن المحلل يستخدمه للأسماء المهمة۔ داخل فضاء أسماء الشبكة تختفي المشكلة، لأن محلل الفضاء لا يعرف إلا النفق۔
تحقق من القاعدة من الحساب نفسه
اسأل النواة أي مسار يحصل عليه UID، ثم نفّذ طلبًا بذلك الحساب وقارن عنوان الخروج بعنوان حسابك۔ إذا أفاد كلاهما بالعنوان نفسه، فالقاعدة تطابق شيئًا آخر غير الحركة التي اختبرتها۔ يعرض الأمر الأول أدناه بحث المسار دون إرسال حزمة، ما يفصل خطأ التوجيه عن خطأ الجدار الناري۔
ip route get 1.1.1.1 uid 1000 sudo -u vpnapp curl -s https://ifconfig.co
تعرض العدادات ما إذا كانت قاعدة قد اشتغلت يومًا۔ شغّل iptables -vnL OUTPUT، واقرأ عدد الحزم بجانب كل قاعدة، واعتبر صفرًا بجانب DROP بعد حركة حقيقية خطأ في المطابقة۔
الحركة المُمرَّرة تقع خارج هذا التصميم۔ الحاوية أو VM خلف جسر ليس لها مقبس محلي يملكه vpnapp، لذا لا تشتغل مطابقة المالك أبدًا وتتبع تلك الحزم سياسة FORWARD بدلًا من ذلك۔ إذا وجب تغطية ذلك العمل، فاختبره منفصلًا واكتب سياسة مربوطة بالجسر أو بعنوان الحاوية۔ يصمد التصميم عندما يشير الجدول واستثناء الواجهة والمحلل وقواعد v6 كلها الاتجاه نفسه؛ اترك أي واحد منها وسيتسرب الحساب أو يفقد الاتصال۔