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

اعرف أين وُلدت الحزمة

ترتيب الخطافات في Netfilter يفصل ثلاث حالات، وواحدة فقط منها تشمل FORWARD:

OriginPathHook that sees it
Local processOUTPUT then POSTROUTINGOUTPUT, POSTROUTING
Addressed to a local servicePREROUTING then INPUTPREROUTING, INPUT
Received for another hostPREROUTING, FORWARD, POSTROUTINGFORWARD

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

حزمتان، قصة واحدة

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

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

فضاءات الأسماء تنقل الحدّ

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

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

اسأل أولًا ما إذا كنت تحتاج إلى وسم أصلًا

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

التصنيف لازم عندما يعتمد القرار على شيء لا يستطيع المسار التعبير عنه، مثل المصدر أو المستخدم أو العملية. للحركة الواردة يعمل الوسم في PREROUTING. وللحركة المحلية يجب أن يحدث الوسم في مرحلة خرج قادرة على إطلاق بحث مسار جديد بعد ضبط الوسم. في nftables يكون ذلك سلسلة من نوع route على خطاف الخرج؛ وسلسلة تصفية خرج عادية ستضبط القيمة وتترك المسار كما هو.

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

تحقّق من البحث والعدّاد معًا

nft list ruleset
ip route get 198.51.100.25
ip route get 198.51.100.25 mark 0x1

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

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

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

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