تقييد بوابة OpenVPN بشبكة محلية واحدة باستخدام قواعد UFW
دع عملاء النفق يصلون إلى شبكة فرعية واحدة ولا شيء غيرها. سلاسل حماية قبل القبول المبكر في UFW، وتصريح للمسار، واختبارات تثبت الحد.
احسم التصريح قبل أن تفتح ملف جدار الحماية: يجوز للعملاء الموثّقين فتح اتصالات إلى شبكة فرعية واحدة محددة، وعلي البوابة أن ترفض كل مسار عبور آخر حتى لو ثبّت العميل مسارات إضافية. تلك الجملة هي التصميم، وكل قاعدة أدناه موجودة لفرضه. أي شيء أوسع من ذلك، مثل فضاء العناوين الخاصة كله أو الخروج إلى الإنترنت عبر النفق أو حركة النِد للنِد، هو تصميم مختلف يحتاج قراراً خاصاً به. والقواعد مملة عمداً أيضاً، لأن الجدار الذكي هو الذي لا يستطيع أحد تدقيقه لاحقاً.
اكتب الطوبولوجيا والتصريح أولاً
يستخدم المثال خادم Community OpenVPN مع جهاز TUN في مساحة المستخدم باسم tun0، ومجمّع عملاء 10.77.0.0/24، وشبكة فرعية واحدة متصلة 192.168.60.0/24 على lan0. تحويل IPv4 يعمل بالفعل، وللشبكة المحلية مسار عودة إلى المجمّع، لذا لا شيء هنا يعتمد على الترجمة بينهما.
يتولى UFW جدار الحماية على هذا المضيف، ولا يجوز لأي مجموعة قواعد داخل حاوية أو جدول nftables منفصل أن يثبّت مسار قبول أبكر. اختصار تفريغ التدفق الذي يتخطى المرشّح سيجعل سلاسل الحماية زينة، لذا تأكد من عدم تنشيط أي منها. اترك تمرير client-to-client الخاص بـ OpenVPN معطلاً، لأن حركة النِد للنِد التي لا تعبر مرشّح نظام التشغيل أبداً لا يمكن تقييدها به. يبقى المستمع الخارجي وقواعد الإدارة كما هي، لأن هذا التغيير يحكم حركة النفق المفكوكة التشفير بدل أن يستبدل جدار الحماية.
ضع الحُرّاس قبل حالات القبول المبكر في UFW
لا يكفي السماح بالمسار ثم الرفض لبناء حد صارم. فقواعد before الافتراضية تقبل الحركة القائمة وبعض رسائل ICMP قبل الرجوع إلى أي قاعدة مستخدم، لذا يمكن لتدفق سُمح به الأسبوع الماضي أن يبقى خارج قيد الوجهة الجديد لمجرد أن لديه حالة قائمة. انسخ ملفات UFW واحتفظ بطرفية خارج النطاق مفتوحة قبل التحرير.
في قسم *filter من /etc/ufw/before.rules، صرّح بسلسلتين إلى جانب التصريحات القائمة وقبل أي سطر قاعدة.
:vpn-src-guard - [0:0]
:vpn-reply-guard - [0:0]مباشرة بعد التصريحات، وقبل سماحات الإدخال والتمرير، اقفز إليهما وحدّد ما تقبلانه.
-A ufw-before-input -i tun0 -j DROP
-A ufw-before-forward -i tun0 -j vpn-src-guard
-A ufw-before-forward -o tun0 -j vpn-reply-guard
-A vpn-src-guard -o lan0 -d 192.168.60.0/24 -s 10.77.0.0/24 -m conntrack --ctdir ORIGINAL -j RETURN
-A vpn-src-guard -j DROP
-A vpn-reply-guard -i lan0 -d 10.77.0.0/24 -s 192.168.60.0/24 -m conntrack --ctstate RELATED,ESTABLISHED --ctdir REPLY -j RETURN
-A vpn-reply-guard -j DROPأبقِ بقية القسم وسطر COMMIT الخاص به. لصق جدول مرشّح ثانٍ أو حذف قواعد لا علاقة لها هو الطريق الذي يحوّل تغيير جدار الحماية إلى انقطاع، والملف على بعد إعادة تشغيل واحدة من أن يصبح النسخة الوحيدة المهمة.
اقرأ ما يقبله كل حارس ويرفضه
تتابع السلسلة الأولى المعالجة فقط عندما يكون المصدر داخل المجمّع، والوجهة هي الشبكة الفرعية الوحيدة، وواجهة الخروج هي الشبكة المحلية، والحزمة تسير في الاتجاه الأصلي لتدفقها. وكل ما يصل من النفق غير ذلك يُسقط، بما في ذلك مصدر خارج المجمّع وأي وجهة تتجاوز الشبكة الفرعية المسموح بها.
حزمة النِد للنِد تدخل tun0 وتخرج منه، لذا تفشل في اختبار واجهة الشبكة المحلية قبل أن يصل الأمر إلى فحص الوجهة. كما تفشل الاتصالات الجديدة من الشبكة المحلية نحو العملاء في اختبار اتجاه الرد، وهو ما يغلق مسار الاستدعاء العكسي افتراضياً.
هدف RETURN يبقي سياسة UFW العادية فاعلة. هذه السلاسل تُرشّح، وتصريح المسار الذي تضيفه بعدها هو الذي يقرر ما إذا كانت الحزمة الناجية ستُقبل. هذا الفصل هو ما يتيح لك تغيير الشبكة الفرعية المسموح بها في مكان واحد لاحقاً. ولو كانت الحُرّاس تقبل الحزم مباشرة، لكان على كل قاعدة مستقبلية أن تُضاف مرتين.
صرّح بالشبكة الفرعية وأغلق الأبواب الجانبية
عاين تصريح المسار أولاً، ثم أسقط علامة المعاينة لتطبيقه: sudo ufw --dry-run route allow in on tun0 out on lan0 from 10.77.0.0/24 to 192.168.60.0/24. بعد ذلك راجع ترتيب قواعد المستخدم، لأن رفضاً أسبق يظل يتغلب على سماح لاحق. وتصريح لكامل الشبكة الفرعية شكل خاطئ أيضاً عندما ينبغي أن يكون منفذ HTTPS لمضيف واحد فقط هو المتاح.
لاحظ ما يفعله إسقاط الإدخال: لا يستطيع عملاء النفق الوصول إلى أي خدمة على البوابة نفسها، بما في ذلك مستمع DNS المرتبط بعنوان شبكتها المحلية. واستضافة DNS هناك تحتاج استثناءً مقصوداً قبل الإسقاط وعقد تصريح منقّحاً. وإذا كان UFW يدير IPv6، فأضف إسقاطات مطابقة لـ tun0 في before6.rules كذلك، لأن قائمة وجهات IPv4 لا تقول شيئاً عن حزم IPv6.
تحقق من السياسة المحمّلة، لا من المعاينة
عاين إعادة التحميل، وطبّقها في نافذة صيانة، واقرأ مجموعة القواعد الحيّة.
sudo ufw --dry-run reload
sudo ufw show rawتأكد من ظهور حُرّاس النفق قبل سماحات الحالة الافتراضية و ICMP. فـ ufw status العادي لا يعرض قواعد before المحرّرة يدوياً، ولهذا يستنتج المشغّلون أن قاعدة مفقودة بينما هي في الحقيقة محمّلة. اقرأ القائمة الخام من أعلى إلى أسفل بدل البحث عن جزء منها. وإذا ظهر الحُرّاس بعد سماح حالة، فالحد لا يفعل ما يقوله الملف.
ثم اختبر السلوك لا النص. افتح اتصالاً جديداً إلى مضيف مسموح وراقب الرد، ووجّه طلباً غير ضار إلى وجهة خارج الشبكة الفرعية وتأكد من موته، وجرّب اتصال نِد لنِد، وجرّب خدمة محلية على البوابة، وجرّب اتصالاً غير مطلوب من الشبكة المحلية إلى العميل. أدرج تدفقاً واحداً خارج النطاق كان قائماً قبل التغيير، وامسح ذلك التدفق وحده بدل تفريغ جدول التتبع كله للجهاز.
سجّل الحدود إلى جانب القواعد: هذا يقيّد العبور ولا شيء غيره. لا يمنع العميل من استخدام اتصاله بالإنترنت، ولا يمنع مضيفاً مسموحاً في الشبكة المحلية من تمرير الحركة أبعد، ولا يستبدل المصادقة داخل الخدمات المسموح بها.