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

لماذا تصبح الوحدة غير نشطة بعد ثوانٍ من بدء ناجح

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

اقرأ نوع الوحدة إلى جانب سلوك العميل قبل أن تمسّ إعدادات الشبكة.

اختر النوع الذي يطابق العميل

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

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/protonvpn-cli connect -f
ExecStop=/usr/bin/protonvpn-cli disconnect

oneshot مع RemainAfterExit=true يُبقي الوحدة نشطة بعد عودة الأمر، وهو ما يطابق نمط الضبط ثم الخروج، كما يمنح أمر الإيقاف الخدمة إغلاقًا نظيفًا. العميل الذي ينسخ نفسه يحتفظ بالشكل ذاته لكنه يحتاج Type=forking لكي يتابع systemd العملية الابنة. اضبط Restart=on-failure و RestartSec=30 و StartLimitBurst محدودًا، حتى لا يتحول انقطاع المزوّد إلى حلقة إعادة تشغيل تدفن الخطأ.

لا تدع العميل الخاضع للإشراف يتحوّل إلى خادم في الخلفية

يصطدم المشرفون خارج systemd بالعائق نفسه. سكربت runit الذي يشغّل عميلًا متخادمًا يعود إلى المشرف فورًا، فيقرأ المشرف العودة كأنها انهيار ويبدأ نسخة أخرى. كل مشرف يتوقع أن يملك العملية الأمامية، كما يبقى sshd -D في المقدمة. أزل علم التخادم من الأوامر الخاضعة للإشراف واترك للمشرف تشغيل الخلفية. سكربتات التغليف التي تعود قبل وجود النفق تسبب الالتباس نفسه.

العملية التي تفصل نفسها تصبح غير مرئية لكل ما كان يُفترض أن يراقبها.

تنتهي الجلسة وتأخذ النفق معها

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

مستخدم الخدمة هو النصف الآخر من المشكلة نفسها. مفتاح يملكه root بالوضع 0600 غير قابل للقراءة لوحدة تعمل بحساب آخر، مهما حقّق sudo في صدفيتك.

systemctl cat openvpn-server@work
sudo chown -R openvpn:network /etc/openvpn/server
sudo find /etc/openvpn -type f -perm /077 -ls

رتّب التابعين بعد وجود العنوان

عندما يربط خادم نفسه بعنوان نفق لم يُنشأ بعد، يخرج برسالة Cannot assign requested address. الإصلاح هو ترتيب صريح لا حلقة إعادة محاولة.

[Unit]
After=network.target [email protected]
Requires=sys-devices-virtual-net-wg0.device

After= يرتّب المهام، بينما Requires= على وحدة الجهاز يربط التابع بوجود الواجهة، وهو أقوى من انتظار هدف الشبكة وحده. أعد تحميل المدير بعد التحرير وأعد تشغيل الخدمة التابعة، ثم اقرأ سجلها بدلًا من افتراض أن الترتيب سرى. أرسل مخرجات العميل إلى السجل عبر StandardOutput=journal أو خيار سجل، لأن عميلًا خاضعًا للإشراف يكتب إلى ملف لا يفتحه أحد يبدو تمامًا كعميل لم يبدأ أبدًا.

ثم أعد التشغيل مرة واحدة وتأكد أن الوحدة نشطة بعد ظهور جهاز النفق. الإصلاح الذي تُحقّق منه بـ systemctl start فقط لم يختبر ترتيب الإقلاع الذي كان المفروض إصلاحه.

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