Systemd กับ NetworkManager: ใครเป็นคนเริ่ม VPN ตอนบูต?
กลไกสามแบบสามารถดึงโปรไฟล์ Ubuntu เดียวกันขึ้นมาได้ แต่มีตัวกระตุ้นต่างกัน เอามาเทียบกัน เก็บเจ้าของไว้หนึ่งราย แล้วปลดตัวซ้ำออก
เครื่อง Ubuntu สองเครื่องจากอิมเมจเดียวกัน โปรไฟล์ VPN เดียวกัน แต่ผลตอนล็อกอินกลับตรงกันข้าม เครื่องหนึ่งอุโมงค์ขึ้นก่อนหน้าจอเดสก์ท็อปจะปรากฏ อีกเครื่องกลับไม่ขึ้นเลย ตัวแปรตรงนี้ไม่ใช่โปรไฟล์ สิ่งที่ต่างคือมีสามองค์ประกอบและมีเพียงตัวเดียวที่ได้รับคำสั่งให้เริ่มมัน ทั้งสามไม่ได้ใช้สวิตช์ตัวเดียวกัน
การเอามาวางเทียบกันเร็วกว่าการเดา แต่ละแบบล้มเหลวในลักษณะที่จำได้ และนั่นคือเหตุผลที่การเทียบครั้งนี้คุ้มค่า
ตัวเริ่มสามแบบกับตัวกระตุ้นที่ต่างกันสามทาง
บริการ openvpn ที่แพ็กเกจมาให้เป็นเส้นทางที่เก่าที่สุด สคริปต์ init ของมันอ่านรายการเริ่มอัตโนมัติจาก /etc/default/openvpn ถ้ารายการนั้นถูกคอมเมนต์ไว้หรือปล่อยว่าง สคริปต์จะเริ่มทุกคอนฟิกที่หาได้ในไดเรกทอรีนั้น ไม่ใช่เฉพาะตัวที่คุณเพิ่มเข้าไป ไฟล์เดียวที่เพิ่มให้อุโมงค์หนึ่งอาจดึงขึ้นมาหลายตัวโดยไม่ส่งเสียง
| Starter | What triggers it | Typical failure |
|---|---|---|
| Init script and templated units | Boot, plus anything in the autostart list | Starts every config, not the one you meant |
| NetworkManager secondary | Activation of the base Wi-Fi or Ethernet profile | Nothing happens until that base link comes up |
| Hand-written unit or wrapper | Whatever its WantedBy and ExecStart say | Runs a different binary or environment than your shell |
แถวที่สองคือแถวที่คนตั้งค่าผิด NetworkManager ถือโปรไฟล์ที่นำเข้าไว้และจะเริ่มมันให้ แต่ในฐานะตัวรองของอีกการเชื่อมต่อหนึ่งเท่านั้น หมายความว่าตัวกระตุ้นเป็นของลิงก์เครือข่าย ไม่ใช่ของ VPN
เทียบค่าใช้จ่ายในการตั้งค่ากับขอบเขตการใช้งาน
เส้นทางสคริปต์ init เสียค่าใช้จ่ายแค่บรรทัดเดียวและครอบคลุมทุกคอนฟิกบนเครื่อง เหมาะกับเราเตอร์แต่ไม่เหมาะกับแล็ปท็อปที่ต่อหลายเครือข่าย ส่วนเส้นทาง NetworkManager ต้องค้นหา UUID หนึ่งครั้งและผูกอุโมงค์ไว้กับการเชื่อมต่อฐานหนึ่งรายการ มันขึ้นบน SSID ของที่ทำงานและคงปิดอยู่บนเครือข่ายโรงแรม
unit ที่เขียนเองมีต้นทุนสูงที่สุดและให้การควบคุมมากที่สุด รวมถึงลำดับเทียบกับบริการอื่น ปัจจัยชี้ขาดคือขอบเขต ถ้าเครื่องมีเครือข่ายเดียวและอุโมงค์เดียว บริการที่แพ็กเกจมาก็ตรงไปตรงมาและคาดเดาได้ ถ้าอุโมงค์ต้องตาม 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 เพื่อให้ unit ที่สร้างขึ้นรับรายการใหม่ แล้วปิดอินสแตนซ์เทมเพลตที่คุณไม่ต้องการอีก การข้ามการรีโหลดจะทำให้ unit เก่ายังทำงานอยู่ และดูเหมือนว่าการเปลี่ยนแปลงไม่ได้ผลอะไร
การหยุดที่ค้างเป็นปัญหาอีกเรื่องหนึ่งซึ่งมีคำตอบจำกัด TimeoutStopSec กำหนดว่า systemd จะรอนานเท่าใดก่อนส่ง SIGKILL สถานที่ที่ถูกต้องในการตั้งค่าคือไฟล์ drop-in เพราะการแก้ unit ที่แพ็กเกจมาจะทำให้การเปลี่ยนแปลงหายไปตอนอัปเกรดครั้งถัดไป
ตรวจสอบว่าอะไรขึ้นมาจริง
รีบูตแล้วอ่านหลักฐานแทนที่จะเชื่อไฟล์คอนฟิก unit ที่เป็นเจ้าของอุโมงค์จะแสดงสถานะ active และเวลาที่เริ่มสอดคล้องกับการบูต และอินเทอร์เฟซ 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 ของ unit ชี้ไปที่ไบนารีที่คุณคิดจริง ๆ ไคลเอนต์ที่คอมไพล์เองหรือแพ็กเกจ snap มักต้องระบุพาธชัดเจนหรือใช้ตัวห่อ snap run เพราะ systemd ไม่ได้รับลำดับการค้นหาจากเชลล์ของคุณ การเทียบ command -v openvpn กับไฟล์ unit จะทำให้กระจ่างภายในไม่กี่วินาที
เขียนเจ้าของที่เลือกไว้ลงในบันทึกของเครื่อง ข้างชื่อโปรไฟล์ คนถัดไปที่ต้องแก้เรื่องอุโมงค์ไม่ขึ้นจะเริ่มจากบรรทัดนั้นแทนที่จะไล่เทียบใหม่ทั้งหมด