NAT يحدد عنوان المصدر الذي يراه خادم VPN فعليًا
عنوان حاسوبك المحمول لا يصل أبدًا إلى خادم VPN. يعيد NAT كتابته عند آخر قفزة، ويُسنَد عنوان IP للنفق لاحقًا. كيف تقارن الطرفين.
تتخيل أن خادم VPN يقرأ عنوان حاسوبك المحمول من الحزمة ويكتبه في سجل. ما يقرأه هو ما وضعته آخر قفزة NAT في الترويسة الخارجية، وهو على هاتف يعمل كنقطة اتصال غالبًا عنوان يتقاسمه مئات المشتركين الآخرين. عنوان جهازك أنت 192.168.x.x لا يعبر الإنترنت في تلك الترويسة أبدًا، وعنوان النفق يمنحه الخادم بعد أن يكون الاتصال قائمًا بالفعل. فحين يختلف سجل الخادم عن ip addr على الحاسوب المحمول، لا يكون أي منهما خاطئًا؛ إنهما يصفان طبقتين مختلفتين من جلسة واحدة.
ثلاثة عناوين، واحد فقط منها في السجل
الارتباك يأتي من دمج ثلاثة عناوين في عنوان واحد. لكل منها مالك مختلف، ويعيش في ترويسة مختلفة، ويصل إلى الخادم عبر مسار مختلف.
| Address | Who assigns it | Where it sits | Visible to the VPN server |
|---|---|---|---|
Device address, e.g. 192.168.1.24 | Your router via DHCP | Outer header, before translation | No, rewritten in place |
| Translated address and port | Router, ISP CGNAT, or both | Outer header, after translation | Yes, this is the tuple it logs |
Tunnel address, e.g. 10.8.0.6 | The VPN server itself | Inner header, after decapsulation | Yes, but it chose it |
الصف الأوسط وحده مجهول وقت الاتصال. يكتبه الخادم في جدول أقرانه أو ملف الحالة أو سجل التدفق حسب البرنامج الخفي: يسميه WireGuard نقطة النهاية، ويسميه ملف حالة OpenVPN Real Address، ويبلغ عنه strongSwan كمضيف بعيد لجلسة IKE_SA. تتجدد تلك القيمة كلما وصلت حزمة من مصدر مختلف، فتتغير دون أن يعيد أحد تشغيل أي شيء.
الصف السفلي هو ما يقرأه الناس خطأً كادعاء هوية. إنه يحدد خانة في إعداد الخادم، لا شخصًا، لأن الخادم اختاره من مجمعه الخاص. يمكن أن يحصل مستخدمان على عنوان النفق نفسه في يومين مختلفين، ويمكن لشخص واحد أن يحمل عنوانين من جهازين.
لماذا تتغير المجموعة المسجلة بينما يبقى النفق قائمًا
ترجمة العناوين جدول بمؤقت، لا ارتباط دائم. يحتفظ موجّه المنزل بتعيين UDP الخاص به فترة بعد آخر حزمة، ويعيد بوابة المشغل تدوير المنافذ وفق جدولها الخاص، ويعود الهاتف الذي ينتقل من Wi-Fi إلى LTE بمصدر مختلف تمامًا. الإعدادات الافتراضية لـ conntrack في Linux معيار مفيد هنا: nf_conntrack_udp_timeout يساوي 30 ثانية والنسخة الخاصة بالبث 120، لذا يمكن لنفق هادئ أن يفقد تعيينه قبل أن يلاحظ المستخدم ذلك بوقت طويل.
ينجو النفق لأن البروتوكول يصادق على النظير، لا على العنوان. WireGuard عديم الحالة بعد المصافحة، فأي حزمة موثقة تحدّث نقطة النهاية المخزنة ويُصلح إعادة الربط نفسه مع الحزمة التالية؛ ولهذا يوجد persistent-keepalive = 25، لإبقاء التعيين دافئًا أثناء الخمول. ويؤدي --float في OpenVPN المهمة نفسها، فيسمح لعميل موثق بالاستئناف من عنوان ومنفذ جديدين. وفي إصداري 2.4 و2.5 حيث يكون float معطلاً افتراضيًا، تعيد إعادة الربط ضبط الجلسة ويتصل العميل من جديد.
يصل IPsec إلى ذلك بأجزاء متحركة أكثر. يلاحظ IKEv2 الترجمة عبر مقارنة بصمات المصدر والوجهة في حُمولات كشف NAT، ويتحول إلى تغليف UDP 4500، ويتابع رسائل الإبقاء إلى المجموعة الجديدة. وعندما تُحجب رسائل الإبقاء تبقى SA قائمة على الورق بينما يتوقف المرور في اتجاه واحد بصمت.
ما يمكن للخادم إسناده، وما لا يمكنه
الأسطورة التي تستحق القتل هي أن الترجمة تخفيك عن المشغل. إنها تغيّر اللافتة، لا الملاحظة. بوابة خلف NAT المشغل ترى فضاء 100.64.0.0/10 أو عنوانًا عامًا واحدًا يتقاسمه كثير من المشتركين، ويمكنها مع ذلك ربط التدفق بموضوع شهادة، وبمفتاح WireGuard عام، وبعنوان نفق مُسنَد، وبعدادات البايت، وبإطار زمني. لا شيء من ذلك يحتاج عنوان LAN الخاص بك.
الحدود تسير في الاتجاه الآخر أيضًا. عنوان مشترك في سجل يشير إلى بوابة، لا إلى منزل؛ وجلستان من العنوان المترجم نفسه على منفذين مختلفين هما جهازان مختلفان؛ والعنوان نفسه في يومين مختلفين قد يكون مشتركين لا علاقة بينهما إذا أُعيد تدوير المنفذ. والخادم الذي يسجل مفاتيح الأقران فقط لا يستطيع ربط أحدهم بعميل دون قاعدة بيانات الحسابات، والخادم الذي يسجل العناوين فقط لا يستطيع التمييز بين حاسوب محمول وهاتف خلف الموجّه نفسه.
قارن الطرفين بدلًا من التخمين
لحسم ما حدث، التقط الاتصال نفسه عند الطرفين في اللحظة نفسها وقارن المجموعة، لا العنوان. على العميل، قبل أي ترجمة:
ss -uapn 'dport = :51820'
ip -4 route get 203.0.113.10
wg show wg0 endpoints
ثم اقرأ إدخال الترجمة على الموجّه أو بوابة CGNAT، وما يصل أخيرًا إلى الخادم:
conntrack -L -p udp --dport 51820
tcpdump -ni eth0 udp port 51820
ثلاثة أنماط تفسر معظم حالات عدم التطابق. منفذ المصدر عند الخادم يختلف عن المنفذ المحلي بينما تتطابق الوجهة: ترجمة منافذ عادية. عنوان المصدر عند الخادم ينتمي إلى نطاق ISP ليس نطاقك: طبقة NAT إضافية على الأقل. تتوقف الحزم بعد فترة خمول ثم تعود بمنفذ جديد: انتهت صلاحية التعيين، وليس عطل توجيه. وإذا كانت الطوابع الزمنية متباعدة أكثر من ثانية أو ثانيتين، فأنت تقارن محاولتين مختلفتين.
أين يُحدث الاختلاف الأعطال
الانقطاعات التي تبدو كأعطال خادم تبدأ عادة هنا. قاعدة وصول مثبتة على عنوان منزلك تفشل بعد تغيّر استئجار ISP. وقاعدة fail2ban تطابق عنوانًا مترجمًا تحظر كل مشترك خلف تلك البوابة دفعة واحدة. ونظير موقع-إلى-موقع بعنوان بعيد ثابت يتوقف عن تجديد المفاتيح بعد تغيّر وصلة متنقلة. كان بروتوكول النفق سليمًا؛ أما الافتراض بشأن المجموعة الخارجية فلم يكن كذلك.
الارتباك نفسه يظهر عند طرف الخادم. إذا كان جهاز VPN نفسه خلف NAT فأنت تحتاج إلى إعادة توجيه منفذ وإلى مسار توجيه عامل؛ ويغطي دليل strongSwan للتوجيه تلك الحالة في IPsec. والخادم الذي لا يُبلغ إلا على عنوان خاص لا يرى أبدًا المجموعة المترجمة التي يقدمها عملاؤه، وهذه مشكلة مختلفة عن ترجمة العملاء.
اعمل بهذه الفحوص الأربعة بالترتيب وتوقف عند أول واحد يفشل:
- التقط عند الطرفين في الوقت نفسه؛ وتأكد من تطابق منفذ المصدر ومنفذ الوجهة والطوابع الزمنية.
- اقرأ قائمة أقران الخادم بحثًا عن العنوان الذي يحمله الآن، لا العنوان الذي توقعته.
- افحص جدول conntrack أو NAT بحثًا عن الإدخال وعمره المتبقي.
- تأكد من أن عنوان واجهة النفق على العميل يطابق ما أسنده الخادم، لا عنوان LAN.
إذا اتفق الالتقاطان على المجموعة وظل النفق فاشلًا، فليست الترجمة مشكلتك؛ انتقل إلى المصافحة وإلى جدول التوجيه داخل النفق.