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

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

ثلاثة مُشغِّلات بثلاثة محفزات مختلفة

خدمة openvpn المُحزَّمة هي أقدم مسار. يقرأ سكربت التهيئة الخاص بها قائمة تشغيل تلقائي من /etc/default/openvpn. وإذا كانت تلك القائمة معلَّقة أو متروكة فارغة، فإن السكربت يبدأ كل إعداد يجده في ذلك الدليل بدلًا من الإعداد الواحد الذي أضفته. وملف واحد أُضيف لنفق واحد قد يُشغِّل عدة أنفاق بصمت.

StarterWhat triggers itTypical failure
Init script and templated unitsBoot, plus anything in the autostart listStarts every config, not the one you meant
NetworkManager secondaryActivation of the base Wi-Fi or Ethernet profileNothing happens until that base link comes up
Hand-written unit or wrapperWhatever its WantedBy and ExecStart sayRuns a different binary or environment than your shell

الصف الثاني هو الذي يسيء الناس إعداده. يحتفظ NetworkManager بالملف الشخصي المستورد وسيبدأه، لكن فقط كثانوي لاتصال آخر، ما يعني أن المحفز يخص رابط الشبكة لا الـVPN.

قارن كلفة الإعداد ونطاقه

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

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

اختر مالكًا واحدًا وأزل الآخرين

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

# who is configured to start something?
grep -v '^#' /etc/default/openvpn
systemctl list-units 'openvpn*'
nmcli -g connection.secondaries connection show 'Work Wi-Fi'

# NetworkManager: attach the tunnel to the base link by UUID
TUNNEL=$(nmcli -g UUID connection show 'Corp Tunnel')
nmcli connection modify 'Work Wi-Fi' +connection.secondaries "$TUNNEL"

وإذا كان المسار المُحزَّم هو الذي يُسحب، فافعل ذلك بالترتيب الصحيح: اضبط AUTOSTART على none، ونفّذ systemctl daemon-reload لتلتقط الوحدات المولَّدة القائمة الجديدة، ثم عطّل النسخة القالبية التي لم تعد تريدها. وتخطي إعادة التحميل يبقي الوحدات القديمة نشطة، فيبدو الأمر كأن التغيير لم يكن له أثر.

التوقف الذي يتعلق مشكلة منفصلة لها جواب محدود. يحدّ TimeoutStopSec من مدة انتظار systemd قبل إرسال SIGKILL. والملف الإضافي drop-in هو المكان الصحيح لضبطه، لأن تعديل الوحدة المُحزَّمة يفقد التغيير عند الترقية التالية.

تحقق مما بدأ فعليًا

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

systemctl is-enabled openvpn-client@office
systemctl status openvpn-client@office --no-pager
nmcli -f GENERAL.STATE,connection.secondaries connection show 'Work Wi-Fi'
ip -brief link show tun0

ثمة فحص آخر ينتمي إلى هنا: تأكد من أن ExecStart في الوحدة يشير إلى الملف التنفيذي الذي تظنه. فالعميل المُجمَّع محليًا أو حزمة snap تحتاج غالبًا إلى مسار صريح أو غلاف snap run، لأن systemd لا يرث ترتيب البحث في الصدفة لديك. ومقارنة command -v openvpn بملف الوحدة تحسم ذلك في ثوانٍ.

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

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