ยูนิตอาจดูถูกต้อง systemctl start อาจรายงานความสำเร็จ และสิบวินาทีต่อมาบริการก็อยู่ในสถานะไม่ทำงาน หรือมันเริ่มใหม่ทุกครึ่งนาทีจนกว่าขีดจำกัดการเริ่มจะหยุดมัน ทั้งสองพฤติกรรมไม่ใช่ความผิดพลาดของเครือข่าย: ยูนิตอธิบายอายุของโปรเซสที่ไม่ตรงกับสิ่งที่ไคลเอนต์ทำจริง ไคลเอนต์อาจ fork แล้วออก หรือกำหนดค่าซิสชันแล้วออกทันที

ทำไมยูนิตจึงกลายเป็นไม่ทำงานไม่กี่วินาทีหลังเริ่มสำเร็จ

systemd อนุมานสถานะจากโปรเซสที่มันเริ่มเอง ดังนั้น Type= จึงเป็นการกล่าวอ้างเกี่ยวกับโปรเซสนั้น ไม่ใช่เอกสารประกอบ ด้วย Type=simple ยูนิตนับว่าใช้งานอยู่ตราบที่คำสั่งทำงาน และกลายเป็นไม่ทำงานเมื่อคำสั่งกลับมา ไคลเอนต์ที่ส่งต่อการเชื่อมต่อไปยังตัวช่วยแล้วออกจึงดูเหมือนพัง แม้อุโมงค์จะทำงานอยู่ บันทึกจะแสดงรูปแบบเริ่มและหยุดที่อ่านได้เหมือนไบนารีที่เสีย

อ่านประเภทของยูนิตคู่กับพฤติกรรมของไคลเอนต์ก่อนแตะการกำหนดค่าเครือข่าย

เลือกประเภทที่ตรงกับไคลเอนต์

สองรูปแบบครอบคลุม CLI ของผู้จำหน่ายส่วนใหญ่: คำสั่งที่กำหนดค่าซิสชันแล้วออก และคำสั่งที่ fork ตัวช่วยก่อนกลับมา แต่ละแบบต้องใช้รูปยูนิตที่ต่างกัน

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

oneshot ร่วมกับ RemainAfterExit=true ทำให้ยูนิตยังใช้งานอยู่หลังคำสั่งกลับมา ซึ่งตรงกับรูปแบบกำหนดค่าแล้วออก และคำสั่งหยุดให้บริการปิดอย่างสะอาด ไคลเอนต์ที่ fork ยังคงรูปเดิมแต่ต้องใช้ 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 เท่านั้นยังไม่ได้ทดสอบลำดับการบูตที่ควรแก้

บทความที่เกี่ยวข้อง