أضف قاعدة سياسة بالأمر ip rule فتعمل إلى أن تختفي الوصلة، وعندها تكون قد ذهبت ببساطة. لم يفشل شيء بصوت عالٍ: تغيّرت حالة النواة، ولم يكن أي مالك إعداد يعرف أن القاعدة يفترض أن توجد. هذا هو الفرق كله بين قاعدة تصمد وأخرى لا تصمد. على مضيف يعمل بـ systemd-networkd، الحل هو منح القاعدة مالكًا بدلًا من إعادة تشغيل الأمر بعد كل إعادة اتصال.

القاعدة لا توجد إلا إذا كان لها مالك

سياسة التوجيه في النواة حالة وليست إعدادًا. تعيش في النظام العامل، وأي شيء يهدم الواجهة التي تعتمد عليها قد يأخذها معه. أمر في الصدفة يغيّر تلك الحالة ولا يترك سجلًا للنية.

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

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

اقرأ الإصدار قبل أن تثق بإعداد

يُتحكم في سلوك الملكية بإعداد في networkd.conf، وهذا الإعداد غير موجود في إصدارات systemd الأقدم. تحقق من الإصدار المثبت قبل أن تبني تصميمك عليه، لأن مضيفًا أقدم يتصرف بشكل مختلف عن الوثائق التي تقرأها.

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

systemctl --version | head -1
networkctl --version | head -1
grep -R "ManageForeign" /etc/systemd/ /usr/lib/systemd/ 2>/dev/null

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

أعلن القاعدة والجدول الذي تشير إليه

القاعدة في ملف ‎.network‎ تسمي جدولًا، والاسم هو كل ما تفعله. لا تنشئ المسارات داخل ذلك الجدول، ولا تتحقق من أنها منطقية. إعلان القاعدة دون المسارات ينتج سياسة تطابق حركة المرور ثم تُسقطها.

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

[RoutingPolicyRule]
Family=ipv4
IPProtocol=tcp
SourcePort=443
Table=100
Priority=1000

[Route]
Destination=10.80.0.0/24
Gateway=10.80.0.1
Table=100

ثم أعد التحميل واقرأ حالة النواة بدلًا من الملف. الإعداد الذي حُلل بنظافة قد ينتج مع ذلك قاعدة لم تقصدها، ولا يتفق المنظوران إلا عندما يكون الإعلان كاملًا.

اختر مالكًا واحدًا للواجهة

مديران على نفق واحد ينتجان صراعًا يبدو كخطأ في كليهما. استيراد إعداد wg-quick قائم إلى networkd هو ترحيل وليس إضافة، وتشغيل الاثنين معًا يترك الواجهة وقواعدها تحت مالكين.

أنجز الترحيل دفعة واحدة: أوقف الوحدة القديمة، عطّلها، أعلن الواجهة ومساراتها في networkd، ثم أعد التحميل. تحقق من أن الوحدة القديمة لا يمكن أن تعود عند الإقلاع. الوحدة المتبقية التي تُعاد تنشيطها بعد إعادة التشغيل تكتب فوق الحالة التي أعلنتها للتو. أبقِ ملف الإعداد القديم حتى يصمد الجديد بعد إعادة اتصال، ثم تقاعده.

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

تدرّب على أحداث دورة الحياة

الإعداد ليس أفضل من سلوكه عبر الأحداث. أنزل الوصلة، ثم ارفعها، وأعد تشغيل الخدمة، وجدد العنوان. بعد كل واحدة، اقرأ قائمة القواعد ومحتويات الجدول.

sudo networkctl reload
ip rule show
ip route show table 100
sudo systemctl restart systemd-networkd

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

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