بدأت من الخارج، كما يفعل المستخدم: كتبت الاسم في متصفح هاتف على بيانات الجوال ورأيت الاتصال معلقًا حتى انتهت المهلة. كان الاسم يُحلّ، فكان DNS سليمًا. كما كانت صفحة تمرير المنافذ في الراوتر المنزلي طريقًا مسدودًا، لأن عنوان WAN فيها كان يعرض 100.64.31.42، وهذا ليس عنوانًا يوجّهني إليه مزوّد من الإنترنت. هذا الرقم يفسّر العطل كله: الخط يقع خلف carrier-grade NAT، لذا فإن العنوان العام على جهتي من النفق يخص المزوّد. فيما يلي المسار الذي سلكته من ذلك التبويب المعلّق إلى خدمة تستجيب.

ابدأ من العميل واتجه إلى الداخل

قبل تغيير أي قاعدة، أثبت أين تتوقف السلسلة. على الحاسوب المحمول نفّذت dig +short files.example.net وحصلت على عنوان خادم VPS، وهذا استبعد DNS قديمًا على جهازي. ثم انتهت مهلة curl -v --connect-timeout 5 files.example.net:5022 بدلًا من أن يُرفض. هذا الفرق مهم: انتهاء المهلة يعني عادة أن الحزم تُسقط في الطريق، أما الرفض فيعني أن شيئًا أجاب وقال لا.

كانت الخطوة التالية إلى الداخل هي خادم VPS نفسه. لم يُظهر ss -ltnp شيئًا يستمع على 5022، وهذا كان متوقعًا قبل وجود قاعدة DNAT. وعلى الجهاز نفسه أكّد wg show (أو ip -br a show tun0 مع OpenVPN) أن النظير المنزلي يعمل وله handshake حديث. إذا كان النظير متوقفًا فلن تساعد أي قاعدة NAT، والضوء الأخضر في صفحة VPN على الراوتر المنزلي لا يعني شيئًا.

أكّد أن الخط المنزلي فعلًا خلف CGNAT

قارن العنوان الذي يبلّغ عنه الراوتر على واجهة WAN بما تراه خدمة خارجية. كل ما يقع في 100.64.0.0/10، أي من 100.64.x.x إلى 100.127.x.x، هو نطاق العناوين المشتركة من RFC 6598 ولا يمكن الوصول إليه من الإنترنت. وتصل إلى الاستنتاج نفسه عندما يدّعي الراوتر عنوانًا خاصًا عاديًا بينما تُرجع نتيجة بحث عام شيئًا غير ذي صلة. وقد يأتي خط CGNAT بعنوان عام لا يدوم إلا حتى الإيجار التالي، فيبدو تمرير المنفذ عاملًا ساعة ثم يموت بصمت.

بعض المزوّدين يمنحون فعلًا عنوانًا عامًا حقيقيًا لكنهم يحجبون المنفذين الداخلين 80 و443 على الحسابات السكنية. إذا كانت خدمتك ويب فقط وعنوان WAN عامًا فعلًا، فاسأل الدعم قبل بناء relay. وإن لم يكن، فالتصميم أدناه ينطبق على كل منفذ بالتساوي، ويستحق إيقاف التجربة على جانب الراوتر: المترجم في شبكة المزوّد ينهي الاتصال قبل أن يصل إلى واجهة WAN لديك.

وجّه الاسم إلى عنوان خادم VPS

DNS لا يمرّر حركة المرور، لذا يجب أن يحتوي سجل A للخدمة على العنوان العام لخادم VPS. سجل A يشير إلى 192.168.1.20 يُحلّ بشكل مفيد فقط للعملاء الموجودين أصلًا داخل VPN؛ ومن الإنترنت يُحلّ إلى عنوان لا يستطيع أحد توجيهه. أما الوصول الإداري إلى خادم VPS نفسه فأبقي له اسمًا منفصلًا، حتى لا أخلط أبدًا بين المضيف الذي يشير إليه سجل.

إذا كان كل من خادم VPS والجهاز المنزلي يقدّم HTTP، فأعطِ كلًا منهما اسمه الخاص ودع خادم VPS يقرّر من يجيب. دمجهما في اسم واحد والأمل بأن يختار الوسيط الخلفية الصحيحة هو بالضبط ما يجعلك تنقّح المضيف الخطأ طوال أصيل.

منفذ واحد بـ DNAT، وSSH يبقى على 22

الخيار المباشر هو NAT الوجهة على خادم VPS. فعّل تمرير الحزم للنواة العاملة واحتفظ في القاعدة بعنوان النفق لخادم المنزل، لا بعنوان LAN الخاص به:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d 198.51.100.10 --dport 5022 -j DNAT --to-destination 10.8.0.2

اترك SSH إلى خادم VPS نفسه على 22 ومرّر منفذًا آخر، مثل 5022، إلى جهاز المنزل. إن مرّرت 22 إلى جهاز متوقف فستفقد الطريق الوحيد الذي كان يمكنه إصلاحه. المنطق نفسه ينطبق على الوسيط: أبقِ منفذ إدارة خادم VPS خارج قواعد الـ relay.

اجعل القواعد دائمة بمجرد أن تعمل. على Debian أو Ubuntu يكتبها apt install iptables-persistent ثم netfilter-persistent save إلى /etc/iptables/rules.v4. وعلى مضيف يعمل بـ firewalld فإن المكافئ هو تمرير منفذ دائم على المنطقة، ويحتاج firewall-cmd --reload قبل أن يُطبّق. أما القواعد التي تعيش في الذاكرة فقط فتختفي عند أول إعادة تشغيل للصيانة من المزوّد، عادة في ساعة سيئة.

أصلح مسار العودة أو تجنّب الحاجة إليه

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

إصلاحان يعملان. أعطِ جهاز المنزل مسار سياسة كي تعود الحركة من النفق عبر النفق:

ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100

أو دع خادم VPS يعيد كتابة المصدر كي يكون للرد عنوان يستطيع الوصول إليه، ودع conntrack يقلبه عند الخروج:

iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1

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

تحقّق من المسار كله من الخارج

تحقّق من شبكة ليست خادم VPS ولا المنزل: هاتف على بيانات الجوال، أو shell رخيص في مكان آخر. من المتوقع أن يبلّغ nc -vz files.example.net 5022 عن اتصال ناجح، وأن يُظهر openssl s_client -connect files.example.net:443 -servername files.example.net شهادة الاسم العام. ثم افحص مجموعة الأمان أو جدار السحابة عند المزوّد. قاعدة DNAT التي لا ترى حزمة أبدًا تُحجب عادة طبقة واحدة فوق المضيف.

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

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