status=200/CHDIR: systemd ไม่เคยเริ่ม OpenVPN
ความล้มเหลว CHDIR หมายถึง systemd เข้าสู่ไดเรกทอรีไม่ได้ ไม่ใช่ OpenVPN อ่านโปรไฟล์ไม่ได้ ควรอ่าน unit ก่อนแตะการตั้งค่า VPN
บริการล้มเหลว บันทึกเอ่ยถึง spawn และไดเรกทอรี และปฏิกิริยาแรกคือตรวจการตั้งค่า VPN ทั้งที่ยังไม่มีอะไรถูกอ่านจากไฟล์นั้นเลย systemd ล้มเหลวขณะเตรียมโปรเซส ก่อนที่ไฟล์ปฏิบัติการจะเริ่มทำงาน จึงไม่มี parser ไม่มีใบรับรอง และไม่มีโฮสต์ระยะไกลถูกสอบถาม การอ่านรหัสสถานะเป็นข้อความเกี่ยวกับ systemd ไม่ใช่เกี่ยวกับ OpenVPN คือสิ่งที่ทำให้เรื่องนี้กลายเป็นการสอบสวนสั้น ๆ
อ่านรหัสสถานะก่อนแอปพลิเคชัน
รหัสตัวเลขหลังชื่อบริการระบุขั้นตอนที่ล้มเหลว ความล้มเหลวของไดเรกทอรีถูกรายงานเป็นสถานะ CHDIR ขณะที่ไฟล์ปฏิบัติการที่รันไม่ได้เป็นรหัสอีกชุดหนึ่งโดยสิ้นเชิง ทั้งสองดูคล้ายกันในบรรทัดสรุปและไม่มีอะไรเหมือนกันในสาเหตุ
ความแตกต่างนี้สำคัญเพราะจุดแก้อยู่คนละไฟล์ ความล้มเหลว CHDIR เกี่ยวกับเส้นทางและมุมมองของบริการต่อเส้นทางนั้น ความล้มเหลว exec เกี่ยวกับไบนารี ตัวแปลภาษา หรือเมานต์ที่ไม่เกี่ยวข้อง การเปลี่ยนรีโมต VPN รายการรหัสลับ หรือเส้นทางใบรับรองไม่สามารถแก้ทั้งสองอย่างได้
ยืนยันว่าความล้มเหลวเกิดตอนเริ่ม ไม่ใช่หลังการทำงานที่สำเร็จ หากบริการทำงานได้เมื่อวานและตอนนี้ล้มเหลวในขั้นเดียวกัน แสดงว่ามีบางอย่างเปลี่ยนในไดเรกทอรี สิทธิ์ของมัน หรือ unit เอง และการเปลี่ยนแปลงนั้นคือหลักฐานที่ต้องค้นหา
ถาม unit ว่าอยากอยู่ที่ไหน
อ่าน unit ที่มีผลจริง ไม่ใช่ไฟล์ที่คุณคิดว่าติดตั้งอยู่ เพราะ drop-in สามารถเขียนทับไดเรกทอรีทำงานได้โดยที่คุณไม่เคยแก้ unit หลัก เอาต์พุตของ show ตอบคำถามโดยตรง:
systemctl cat [email protected]
systemctl show [email protected] -p WorkingDirectory -p RootDirectory -p User -p ProtectHome
journalctl -u [email protected] -b --no-pager | tail -30
สำหรับเทมเพลตเซิร์ฟเวอร์ upstream ไดเรกทอรีทำงานคือไดเรกทอรีตั้งค่าเซิร์ฟเวอร์ และ ชื่ออินสแตนซ์เลือกโปรไฟล์ภายใน อินสแตนซ์ชื่อ branch จึงคาดหวังไฟล์ของตัวเองในไดเรกทอรีเดียวกัน และโปรไฟล์ที่วางไว้ที่อื่นไม่ตรงตามข้อกำหนดไดเรกทอรีทำงานเลย
เทียบสิ่งที่ unit ต้องการกับสิ่งที่มีอยู่ เส้นทางที่เคยมีอยู่ ลิงก์สัญลักษณ์ที่ชี้ไปที่อื่นแล้ว หรือชื่ออินสแตนซ์ที่ไม่ตรงกับไดเรกทอรีอีกต่อไป ล้วนเป็นการเปลี่ยนแปลงธรรมดาที่ก่อให้เกิดความล้มเหลวนี้
ตรวจเส้นทางตามที่บริการมองเห็น
เชลล์ของคุณกับบริการไม่ได้ใช้มุมมองระบบไฟล์เดียวกัน ไดเรกทอรีรากหรือ root image ที่ตั้งค่าไว้เปลี่ยนความหมายของเส้นทางสัมบูรณ์ภายใน unit และเส้นทางที่เห็นชัดบนโฮสต์อาจไม่มีอยู่ในเนมสเปซนั้น อ่านการตั้งค่าของ unit ก่อนเชื่อการทดสอบด้วยมือ
สิทธิ์ทำให้ปัญหารุนแรงขึ้น บริการรันในฐานะผู้ใช้ที่ระบุ และผู้ใช้นั้นต้องผ่านไดเรกทอรีแม่ทุกชั้นเพื่อไปถึงเป้าหมาย ไม่ใช่แค่อ่านเป้าหมายเอง ไดเรกทอรีที่ root อ่านได้แต่ผู้ใช้ของบริการผ่านไม่ได้ทำให้เกิดความล้มเหลวที่ดูเหมือนเส้นทางหายไป
namei -l /etc/openvpn/server
systemctl show [email protected] -p ProtectSystem -p ReadOnlyPaths
การตั้งค่าการเสริมความแข็งแรงก็เป็นส่วนหนึ่งของภาพนี้ unit ที่ ซ่อนไดเรกทอรีโฮมหรือทำให้ส่วนหนึ่งของระบบไฟล์อ่านได้อย่างเดียว ทำตามที่ถูกตั้งค่าไว้ และไดเรกทอรีทำงานต้องอยู่ในที่ที่ sandbox ยังเปิดเผยอยู่
แก้เจ้าของ แล้วคาดหวังข้อผิดพลาดอื่น
แก้เลย์เอาต์หรือ unit ผ่านผู้ที่เป็นเจ้าของการตั้งค่านั้น การย้ายโปรไฟล์ไปยังไดเรกทอรีที่คาดหวังเป็นการแก้ที่ชอบธรรมเมื่อเลย์เอาต์ผิด แต่ไม่ได้อธิบายไดเรกทอรีที่เข้าไม่ได้ จึงไม่ควรถือเป็นคำตอบทั่วไป
อย่าหลงทางลัดด้วยการขยายสิทธิ์บนต้นไม้การตั้งค่าหรือถอด sandbox ทั้งสองทำให้อาการหายไปพร้อมกับถอดการป้องกันที่ตั้งใจวางไว้ และความล้มเหลวครั้งหน้าจะตีความได้ยากขึ้น
รีสตาร์ทอินสแตนซ์และอ่านเหตุการณ์ถัดไปแทนการถือว่าสำเร็จ ข้อผิดพลาดถัดไปที่น่าจะเกิดคือ OpenVPN เปิดไฟล์การตั้งค่าของตัวเองไม่ได้ ซึ่งเป็นความคืบหน้า เพราะเข้าไดเรกทอรีทำงานได้แล้วและ parser กำลังทำงาน จากตรงนั้นให้ตามการแมปไฟล์จริงของ unit อย่ากลับไปแก้ปัญหาเครือข่าย
เอกสารอ้างอิงการทำงานของ systemd กำหนดว่าไดเรกทอรีทำงานถูกตีความร่วมกับไดเรกทอรีรากและ sandbox อย่างไร รูปแบบที่ควรจำนั้นง่าย แต่ละรหัสสถานะระบุขั้นตอนที่ต่างกัน และมีเพียงข้อผิดพลาดของแอปพลิเคชันเองที่อธิบายแอปพลิเคชัน