لماذا يردّ خدمتك العامة على Linux عبر VPN بدلًا من ذلك
يمكن لخدمة محلية أن تقبل على eth0 وتردّ عبر VPN بنفق كامل. قاعدة مصدر مع جدول WAN كامل تُبقي تلك الردود على المسار الأصلي.
لا شيء في المقبس يتذكّر أي واجهة حملت الطلب، لذا يمكن لمسار افتراضي عبر VPN بنفق كامل أن يلتقط ردًّا ينتمي إلى WAN. الخدمة لا تتجاهل الواجهة الواردة؛ فليكن التوجيه في Linux يعتمد على الوجهة وسياسة المصدر عند توجيه رد يُنشأ محليًّا. قاعدة قائمة على المصدر يمكنها أن ترسل ردود الخدمة وحدها عبر جدول WAN كامل، وتترك الخروج العادي على النفق. يبقى المنفذ مفتوحًا بينما يغادر الرد عبر المسار الخاطئ، ولهذا تبدو العَرَض من جانب واحد.
المفهوم الخاطئ: الردود تتبع الواجهة التي وصلت عبرها
يبدو منطقيًّا أن حزمة تصل على eth0 يجب أن تغادر على eth0. يمكن كتابة مرشّحات حزم بلا حالة بهذه الطريقة، ويُظهر tcpdump على جانب الوارد الطلب تمامًا حيث تتوقّع. التوجيه لا يعمل بهذه الطريقة للحركة التي ينشئها المضيف نفسه.
بمجرد أن تقبل الخدمة الاتصال، يصبح ردّها حزمة جديدة تُنشأ محليًّا. يستشير النواة قواعد التوجيه لوجهة الرد ومصدره، والمسار الافتراضي للـVPN جواب صالح تمامًا. لا شيء في المقبس يتذكّر أي واجهة حملت الطلب.
لهذا تبدو العَرَض من جانب واحد: تصل الطلبات وتختفي الردود. ولهذا أيضًا لا تغيّر قاعدة جدار ناري للمنفذ الوارد شيئًا. الحزمة لا تُحجب في طريق الدخول؛ بل تُوجَّه إلى مكان آخر في طريق الخروج. تتبَّع الرد ببحث مؤهَّل بالمصدر وسيصبح الانحراف ظاهرًا.
ما يوجّهه النواة فعليًّا: عنوان المصدر
المقبض الذي تحتاجه هو العنوان المحلي الذي تستخدمه الخدمة للردود. على مضيف يحمل عنوان eth0 توضيحيًّا 192.0.2.10/24 وبوابة 192.0.2.1، يكون ذلك العنوان موجودًا على الواجهة. على جهاز سحابي افتراضي قد يكون العنوان العام مترجمًا في المنبع وغائبًا عن الضيف، لذا استخدم العنوان الذي يحمله المضيف فعلًا.
افحص الحالة الحالية قبل حجز رقم جدول أو أولوية قاعدة. فالقواعد السياسية القائمة قد تُظلِّل قاعدة جديدة، وقد يحمل جدول قديم بالرقم نفسه مسارات غير ذات صلة:
ip -4 addr show dev eth0
ip -4 rule show
ip -4 route show table all
ثم اختر جدولًا بحسب المصدر. تطابق القاعدة الردود التي تحمل 192.0.2.10 بالفعل، وهي بالضبط الحركة المنتهية محليًّا التي تريد استثناءها. الحركة المُمرَّرة والحزم من عناوين محلية أخرى لا تطابق.
ابنِ جدول عودة كاملًا، لا نصف مسار افتراضي
جدول فيه مسار افتراضي فقط لا يكفي. على النواة أن تحلّ البوابة، وهذا الحل يحتاج البادئة المتصلة في الجدول نفسه. الجدول الذي تنقصه تلك البادئة يفشل في حلّ البوابة حتى عندما يبدو مساره الافتراضي صحيحًا. أضف الاثنين معًا ثم وجّه قاعدة المصدر إلى الجدول:
ip -4 route add table 100 192.0.2.0/24 dev eth0 src 192.0.2.10
ip -4 route add table 100 default via 192.0.2.1 dev eth0
ip -4 rule add priority 1000 from 192.0.2.10/32 lookup 100
استخدم البادئة والبوابة الحقيقيتين بدل نسخ المثال. فلواجهة سحابية مضبوطة كـ /32 مع بوابة على الرابط تحتاج مسارًا متصلًا مختلفًا، وجدول مبني من بادئة خاطئة يفشل عند القفزة الأولى. تعبّر السمة src عن المصدر المفضّل لذلك المسار؛ وهي لا تحلّ محل قاعدة المصدر.
الترتيب مهم أيضًا. القاعدة العريضة ذات رقم الأولوية الأقل تُقيَّم أولًا، لذا يجب الوصول إلى قاعدة المصدر قبل أي قاعدة قد تعيد هذه الحركة إلى الجدول الرئيسي. تحقّق من الأولويات باستخدام ip rule show بعد إضافتها، لا عند الإقلاع فقط.
تحقّق ببحث مؤهَّل بالمصدر
اطلب من النواة توجيه وجهة اختبار من عنوان الخدمة. يجب أن يسمّي الجواب eth0 وبوابة WAN، لا النفق:
ip -4 route get 198.51.100.25 from 192.0.2.10
ثم أنشئ اتصالًا مصرَّحًا جديدًا وراقب الاتجاهين. البحث الذي يختار الجدول الصحيح بينما يظل الاتصال الحيّ فاشلًا يشير إلى ترشيح المسار العكسي أو قاعدة جدار ناري، لا إلى الجدول. افحص تلك الضوابط قبل تعطيل أي شيء عالميًّا.
ضع المسارات النهائية والقاعدة تحت مدير الشبكة الذي يملك الواجهة. تغييرات العناوين وتجديد DHCP وإعادة اتصال VPN كلها تعيد كتابة حالة النواة، والقاعدة المضافة يدويًّا تختفي أو تشير إلى بوابة قديمة بعد الحدث التالي.
أين يتوقّف هذا الاستثناء
تستثني القاعدة الحركة المنتهية محليًّا من عنوان مصدر واحد. وهي لا تغطّي المنافذ المنشورة عبر Docker ولا DNAT ولا الخدمات المُمرَّرة عبر المضيف، لأن تلك الحزم تُوجَّه كحركة تمرير ولا تحمل مصدر المضيف المحلي بالطريقة نفسها أبدًا. تحتاج تلك التصاميم عادةً إلى علامة تُضبط عند الدخول وإلى قاعدة تطابق العلامة.
كما أنها لا تُظهر عنوان المضيف العام على الواجهة. عندما يملك NAT في المنبع ذلك العنوان، يجب أن يغادر الرد عبر المسار الذي يتوقّعه ذلك NAT، ولهذا يجب أن يعكس جدول WAN البوابة والبادئة الأصليتين بدل نطاق عام مخمَّن.
أبقِ الاستثناء موثَّقًا برقم جدوله وأولوية قاعدته وعنوان المصدر الدقيق. فأي تغيير تالٍ في VPN أو الواجهة قد يكسره بصمت، وملاحظة تسمّي القيم الثلاث أسرع في الفحص من إعادة اكتشاف العَرَض من تقرير عميل.
إذا ظلّت الخدمة تردّ على المسار الخاطئ بعد نجاح البحث المؤهَّل بالمصدر، فقارن عنوان المصدر للمقبس الحيّ بالعنوان المذكور في القاعدة. الخدمة المرتبطة بعنوان شامل قد تختار مصدرًا مختلفًا عن العنوان الذي اختبرته، وهذا التباين هو الفجوة المتبقية.