عرض جهاز LAN على أحد عناوين النفق الخاصة بالبوابة لا يحتاج إلا سطرًا واحدًا من NAT. ومع ذلك يظل الاتصال فاشلًا، لأن الجهاز الذي يردّ لا يعرف أن عنوان العميل يمكن الوصول إليه عبر تلك البوابة. تتبّع الحزمة من العميل إلى الداخل، ثم تتبّع الرد عائدًا إلى الخارج، وسيظهر النصف المفقود بوضوح.

ابدأ من منظور العميل

العميل في هذا المثال يوجد في مجمّع VPN 10.62.0.0/24 ويتصل بـ 10.62.0.1 على المنفذ 8080. هذا العنوان ملك للبوابة نفسها، لذلك تصل الحزمة إلى نواة البوابة لا إلى نظير آخر. خلف البوابة توجد الشبكة المحلية 172.21.4.0/24. تملك البوابة 172.21.4.10، والجهاز الذي يقدّم HTTP فعليًا هو 172.21.4.40.

العنوان الذي ينتمي إلى نظير VPN آخر لا يُستبدل بعنوان خدمة البوابة. إذا كان العميل يتصل بعنوان نظير، فلا علاقة لأي قاعدة على البوابة بالأمر، وهذا الشرح كله لا ينطبق.

حدّد ترجمة الوجهة عن قصد

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

iptables -t nat -A PREROUTING -i tun0 -s 10.62.0.0/24 -d 10.62.0.1 -p tcp --dport 8080 -j DNAT --to-destination 172.21.4.40:80

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

دع حدود إعادة التوجيه تتفق

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

iptables -A FORWARD -i tun0 -o lan0 -d 172.21.4.40 -p tcp --dport 80 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

القبول غير المشروط لكل تدفق DNAT أوسع من هذا التصميم، وسيسمح أيضًا بتعيينات يضيفها شخص آخر لاحقًا. سمِّ الوجهة والمنفذ، ودع الباقي يفشل مغلقًا. إذا بقيت العدادات على قاعدة إعادة التوجيه صفرًا بينما ترتفع عدادات NAT، فالحزمة تُسقَط قبل قاعدتك. اقرأ ترتيب السلسلة بدلًا من إضافة نسخة ثانية.

على الجهاز أن يردّ بطريقة ما

بعد الترجمة يرى الجهاز مصدرًا في 10.62.0.0/24. يذهب رده إلى بوابته الافتراضية، وهي موجّه الشبكة المحلية لا بوابة VPN، ما لم يخبره شيء بغير ذلك. ترتيبان يحلّان ذلك، وهما ليسا متكافئين. مسار على الجهاز أو على موجّه الشبكة المحلية يرسل 10.62.0.0/24 إلى 172.21.4.10 مع الحفاظ على مصدر العميل. أما ترجمة مصدر محدودة فتخفي العميل خلف عنوان الشبكة المحلية للبوابة بدلًا من ذلك.

ip route add 10.62.0.0/24 via 172.21.4.10 dev eth1
iptables -t nat -A POSTROUTING -s 10.62.0.0/24 -d 172.21.4.40 -o lan0 -p tcp --dport 80 -j SNAT --to-source 172.21.4.10

اختر بحسب ما تحتاجه الخدمة. السياسة لكل عميل والسجلات ذات المعنى تريد الصيغة الموجّهة؛ أما جهاز لا يمكن منحه مسارًا، أو خدمة يجب أن ترى عنوان شبكة محلية، فيشيران إلى الصيغة المترجَمة. لا تلجأ إلى قاعدة masquerade عامة لجعل رد واحد يعمل. فهي تخفي كل عميل عن كل وجهة، وتكسر بهدوء السياسات التي تعتمد على عناوين المصدر.

لا تختبر من البوابة نفسها

الطلب الذي يُنشأ على البوابة نحو 10.62.0.1 يخرج عبر سلسلة OUTPUT، لا عبر PREROUTING الواردة. وفشله أو نجاحه لا يقول شيئًا عن القاعدة المواجهة للعميل، ومن هنا يستنتج الناس أن قاعدة عاملة معطوبة.

conntrack -L | grep 172.21.4.40
tcpdump -ni any 'port 8080 or port 80'

نفّذ طلب عميل حقيقي واقرأ الاثنين. يُظهر مدخل conntrack الترجمة التي طُبّقت، وتُظهر الالتقاطات ما إذا كانت الحزمة عبرت إلى الشبكة المحلية وما إذا رجع رد نحو النفق. استخدم اتصالًا جديدًا بعد تغيير القواعد، لأن الحالة القائمة تحتفظ بتعيينها السابق وستظل تفشل بالطريقة القديمة. ثم أكّد المحادثة كاملة: عنوان الجهاز، وإذن إعادة التوجيه، ومسار الرد، وكلها تصف التدفق نفسه.

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