عنوان IPv6 المحلي للوصلة لا يعمل عبر VPN: لماذا يتوقف fe80 عند الوصلة
عنوان fe80:: لا يعني شيئًا إلا على وصلة واحدة. اطّلع على سبب عجز VPN الموجّه عن نقله، وكيف يظهر الفشل، وأي عنوان تستخدم بدلًا منه.
تُشغّل النفق، وتُرسل ping إلى fe80::1 مع النفق كواجهة مصدر، فلا يعود شيء. ليست قاعدة جدار حماية نسيتها. العنوان المحلي للوصلة لا يعني شيئًا إلا على الوصلة الواحدة التي تكوّن فيها، وVPN الموجّه ليس تلك الوصلة. عنوان fe80::1 الخاص بالموجّه البعيد يعيش على مقطع الشبكة المحلية البعيد؛ وأنت على بُعد قفزة واحدة على مقطع مختلف، ولا يملك IPv6 أي آلية تسمح للموجّه بإعادة توجيه حزم العنوان المحلي للوصلة إطلاقًا.
بادئة fe80 تصف نطاقًا لا مدى
العنوان الأحادي المحلي للوصلة هو fe80::/10، والخصيصة المميّزة ليست الرقم بل النطاق. العنوان صالح على وصلة واحدة فقط، وكل واجهة تكوّن واحدًا من معرّفها الخاص، ولهذا يمكن لجهازين لا علاقة بينهما على شبكتين لا علاقة بينهما أن يستجيبا معًا لعنوان fe80::1 دون أي تعارض. البادئة تقول ببساطة “على وصلة ما”؛ أما الوصلة نفسها فتأتي من السياق.
على مضيف، ذلك السياق هو المنطقة، أو معرّف النطاق، الذي تُلحقه بعد علامة النسبة المئوية: fe80::1%eth0 على Linux، وfe80::1%3 أو fe80::1%12 على Windows وفي الأدوات التي تُظهر فهارس الواجهات. يحلّ النواة العنوان مع فهرس الواجهة ثم يُرسل. وإذا حذفت المنطقة صار الوجهة غامضة، فلا يملك مكدّس الشبكة وسيلة لاختيار مقطع.
لماذا لا يستطيع النفق الموجّه إيصاله
VPN الموجّه واجهة نقطة إلى نقطة تحمل عناوينها الخاصة، وعادةً /64 من فضاء IPv6 الفريد المحلي أو الخاص داخل النفق. الشبكة المحلية البعيدة وصلة منفصلة، تُبلَغ عبر نقطة نهاية النفق التي توجّه وتُمرّر نيابةً عنك. هذان مقطعان متمايزان، لذا لا يكون عنوان من أحدهما وجهةً صالحة على الآخر.
قاعدة التمرير صريحة في المعيار وليست خصوصية في عميلك: الموجّهات لا تمرّر حزمًا مصدرها أو وجهتها عنوان محلي للوصلة. ولهذا تموت الحزمة حتى عندما يبدو جدول التوجيه سليمًا. أضف مسارًا للبادئة fe80::/64 يشير إلى النفق، فإما يرفضه مكدّس مطابق للمعيار أو يقبله ويُسقط كل حزمة مطابقة: نطاق الوجهة يقول “هذه الوصلة فقط”، وواجهة الخروج ليست تلك الوصلة.
اكتشاف الجيران يعزّز الحد نفسه. تحلّ المضيفات القفزات التالية المحلية للوصلة عبر التماس الجيران المرسل إلى بثّ مجموعات محدد النطاق بحد قفزات 255، حتى تستطيع الموجّهات رفض أي شيء يُمرَّر. وجعل ذلك يعمل عبر نفق يعني توسطًا في الاكتشاف لمقطع بعيد، وهو جسر من الطبقة 2 بقبعة مختلفة.
ثمة فشل ثانٍ أهدأ، وهو يُوقع من يحاولون فرض المسار على أي حال: المنطقة. أي منطقة تكتبها محليًا تسمّي واجهة النفق، بينما العنوان الذي تريده مربوط بواجهة الشبكة المحلية البعيدة. لا يتطابقان أبدًا، فلا يمكن توجيه الحزمة إلى الواجهة الصحيحة عند الطرف البعيد.
كيف يبدو الفشل عمليًا
مخرجات الأدوات عند خطأ في النطاق تبدو كخطأ توجيه أو جدار حماية، ولهذا بالضبط يقضي الناس عصرًا كاملًا في الطبقة الخطأ.
| What you run | What you see | What it means |
|---|---|---|
| ping fe80::1 with no zone | Invalid argument on Linux, or a transmit failure on Windows | The stack cannot pick an interface for an ambiguous destination |
| ping -6 -I tun0 fe80::1 | Destination unreachable, or a silent timeout | The address is not on the tunnel link, so there is nothing on-link to answer |
| ssh user@fe80::1 after the tunnel is up | Hangs, then no route to host | The SYN never left the machine in a deliverable form; the server logs nothing |
| ip -6 neigh show dev tun0 | Empty table | No neighbor entry can exist for a link-local host that is not on this link |
| fe80::/64 inside AllowedIPs or route-ipv6 | Config accepted, traffic still dropped | The tunnel carried the packet; the receiving stack refused to forward it |
الصف الثالث يهدر أكبر قدر من الوقت، لأن عميل ssh بلا مخرجات يبدو مشكلة خدمة استماع. إن كان لديك أي منفذ دخول، فافحص الطرف البعيد وتأكد مما إذا كان sshd مربوطًا بكل العناوين أم بواحد فقط.
استخدم عنوانًا كُتب ليكون موجّهًا
لأي شيء تحتاج إلى الوصول إليه عبر النفق، استخدم العنوان الذي أُعطي للخدمة لهذا الغرض: عنوان أحادي عالمي، أو عنوان فريد محلي من fc00::/7، وهو المدى المحجوز لهذه الحالة الداخلية تحديدًا. تأكد من أن المستمع يربطه فعلًا، وتأكد من مسار العودة وأي قاعدة جدار حماية على المضيف.
انظر إلى المضيف البعيد بدلًا من التخمين. يعرض ip -6 addr show العناوين الموجودة، ويعرض ss -6 -ltn ما يستمع إليه البرنامج الخفي. الخدمة المربوطة بـ fe80:: فقط لا تُبلَغ إلا من مقطعها، وهو عادةً إعداد افتراضي لم يختره أحد عن قصد ويمكن تغييره بموافقة المسؤول.
عندما يتعذر فعلًا إعادة ربط الخدمة، فارفع الجسر إلى طبقة التطبيق بدلًا من طبقة الشبكة. مرحّل على المضيف البعيد يستمع إلى عنوان قابل للتوجيه ويتصل بالعنوان المحلي للوصلة يحل المشكلة دون توسيع أي مقطع:
socat TCP6-LISTEN:8080,bind=[fd00:1:2::10] TCP6:[fe80::1%eth0]:80هنا تقع المنطقة على الجانب الصحيح، على المضيف الذي يملك فعلًا eth0 على تلك الوصلة. يتحدث عميلك إلى fd00:1:2::10، وهو عنوان يُوجَّه طبيعيًا، ويجعل المرحّل قفزة العنوان المحلي للوصلة محلية. والحيلة نفسها تنفع لواجهة ويب لجهاز أو لوحة BMC قديمة لا تعلن إلا عنوانًا محليًا للوصلة.
متى يكون الجسر هو الجواب فعلًا، وما الذي يجب فحصه
بعض عمليات النشر تحتاج فعلًا مقطعًا مشتركًا واحدًا: جهاز لا يتحدث إلا باكتشاف العنوان المحلي للوصلة، أو جهاز يعتمد على البثّ المجموعي، أو مختبر يعيد إنتاج شبكة محلية مسطحة. تلك مشكلة طبقة 2 وتحتاج جوابًا من طبقة 2، مثل جهاز tap مجسور إلى الواجهة البعيدة أو منتج عميل بوضع مجسور صريح. ويكلّفك ذلك حركة البثّ والبثّ المجموعي عابرةً النفق، إضافة إلى اكتشاف الجيران الذي يجب أن يعمل من طرف إلى طرف.
لا تحاول تقريبه بإضافة fe80::/64 إلى ملف تعريف موجّه. فذلك ينتج أسوأ حالة على الإطلاق: يبدو الإعداد منتهيًا، ويعرض جدول التوجيه مدخلًا، وكل حزمة لا تزال تُسقَط في مكان ما بين مكدّسين كلاهما يتصرف بشكل صحيح.
تحقق بالواجهة لا بالـ ping. يخبرك ip -6 addr show tun0 هل كوّنت وصلة النفق عنوانًا محليًا للوصلة خاصًا بها، ويخبرك ip -6 route get fe80::1%tun0 بما ستفعله النواة فعلًا بوجهة محددة النطاق. وعندما تقول النواة إن الوجهة غير قابلة للوصول على تلك الواجهة، فلن يغيّر أي إعداد نفق ذلك، وحان وقت التوقف عن تحرير ملف التعريف.
تسلسل قصير يحسم السؤال:
- اقرأ العنوان على المضيف البعيد ولاحظ هل هو fe80:: أم بادئة قابلة للتوجيه.
- إن كان fe80::، فأعد ربط الخدمة أو رحّل على ذلك المضيف أو اجسر المقطع؛ وإن كان قابلًا للتوجيه، فأصلح المسار أو جدار الحماية أو عنوان الربط.
- أعد فحص المنطقة في كل مرة تعيد الاختبار، لأن الأمر المنسوخ يحتفظ عادةً بالواجهة الخطأ.
المصادر: RFC 4291، معمارية عنونة IPv6.