ข้อความบอกว่า OpenVPN โหลดใบรับรองแบบฝังในบรรทัดไม่ได้ แต่ชื่อไฟล์ที่คุณจำไว้บอกตรงกันข้าม สิ่งที่ parser ได้รับสำคัญกว่าสิ่งที่มีอยู่ในระบบไฟล์ เพราะคำสั่ง cert ยอมรับค่าสองชนิดที่แตกต่างกันโดยสิ้นเชิง ชนิดหนึ่งคือพาธที่มันเปิด อีกชนิดคือข้อความ PEM ที่เข้ามาอยู่ในคอนฟิกูเรชัน จนกว่าคุณจะรู้ว่าไคลเอนต์ที่กำลังทำงานได้รับรูปแบบใด การแก้ไขทุกครั้งจึงเป็นการเดา

สองรูปแบบการจัดเก็บ คำสั่งเดียว

คำสั่ง cert, key และ ca แต่ละคำสั่งยอมรับพาธหรือบล็อกแบบฝังในบรรทัด เมื่อค่าเป็นพาธ OpenVPN จะเปิดไฟล์นั้นและอ่านออบเจกต์จากดิสก์ เมื่อคอนฟิกูเรชันมีบล็อกที่คั่นด้วยแท็ก cert คำสั่งเดียวกันจะใช้เนื้อหาระหว่างแท็กเหล่านั้นแทน และไม่มีไฟล์แยกเข้ามาเกี่ยวข้อง

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

กลับกันไม่เป็นความจริง การวาง client.crt ไว้ข้างโปรไฟล์ที่ฝังข้อมูลของตัวเองไว้ไม่เปลี่ยนอะไร เพราะไม่มีสิ่งใดในคอนฟิกูเรชันอ้างถึงไฟล์นั้น นี่คือสาเหตุที่พบบ่อยที่สุดที่ไฟล์ซึ่งมีอยู่ชัดเจนกลับดูเหมือนถูกละเลย

บล็อกแบบฝังกลายเป็นออบเจกต์ได้อย่างไร

เนื้อหาแบบฝังถูกดึงออกจากคอนฟิกูเรชันและส่งให้ parser ของ PEM ในรูปข้อความ parser นั้นคาดหวังขอบเขตตามปกติ ได้แก่ บรรทัด BEGIN เพย์โหลด base64 และบรรทัด END ที่จับคู่กัน หากบล็อกถูกตัดขาดจากการคัดลอกที่ล้มเหลว ถูกห่อด้วย HTML โดยหน้าดาวน์โหลด หรือถูกเปิดในเอดิเตอร์ที่ทำให้ขีดกลางเป็นรูปแบบมาตรฐาน parser จะล้มเหลวบนเนื้อหาที่ดูเหมือนมีอยู่

<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>

นั่นจึงเป็นเหตุผลที่ถ้อยคำของข้อผิดพลาดชวนเข้าใจผิด คำว่า ฝังในบรรทัด อธิบายว่า loader มองไปที่ใด ไม่ใช่ว่าพบอะไรที่นั่น ไฟล์ที่ระบุชื่อในคอนฟิกและออบเจกต์ที่ฝังอยู่ในนั้นสามารถสร้างข้อร้องเรียนเดียวกันได้เมื่อไบต์พื้นฐานใช้งานไม่ได้

ตรวจสอบว่าโปรไฟล์ที่โหลดไว้ใช้รูปแบบใดจริง ๆ ไม่ใช่ไฟล์ที่เอดิเตอร์ของคุณเปิดขึ้นมาโดยบังเอิญ:

grep -nE '^(ca|cert|key) |^<(ca|cert|key)>' client.ovpn

พาธถูกตีความอย่างไร

ค่าพาธถูกเปิดโดยอ้างอิงกับไดเรกทอรีทำงานของไคลเอนต์ ไม่ใช่ไดเรกทอรีที่มีคอนฟิกูเรชัน ภายใต้ systemd ไดเรกทอรีทำงานนั้นคือสิ่งที่ยูนิตกำหนด และการรันแบบโต้ตอบจากเชลล์ของคุณสืบทอดสิ่งอื่นโดยสิ้นเชิง นี่คือเหตุผลที่ไฟล์คอนฟิกูเรชันเดียวกันอาจทำงานเมื่อทดสอบด้วยมือและล้มเหลวในฐานะบริการ

พาธแบบสัมพัทธ์สืบทอดความกำกวมเดียวกัน เมื่อเห็นชื่อไฟล์เปล่า ๆ ให้ถามว่าไดเรกทอรีปัจจุบันของโปรเซสในสภาพแวดล้อมจริงคืออะไร แทนที่จะสันนิษฐานว่าตรงกับเทอร์มินัลของคุณ

สำหรับใบรับรองที่จัดเก็บแยกไว้ การแยกวิเคราะห์แบบออฟไลน์ยืนยันออบเจกต์ก่อนที่คุณจะดีบักสิ่งใดเหนือมันขึ้นไป:

openssl x509 -in client.crt -noout -subject -issuer -dates
openssl pkey -in client.key -noout -check

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

ข้อผิดพลาดของ parser บอกอะไรได้และบอกอะไรไม่ได้

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

เมื่อการแยกวิเคราะห์สำเร็จ ความล้มเหลวถัดไปเป็นของขั้นตอนที่มาทีหลัง การปฏิเสธความไว้วางใจ ความไม่ตรงกันของวัตถุประสงค์ หรือความไม่ตรงกันของคีย์ถูกรายงานโดยคู่สนทนาหรือโดยชั้น TLS ไม่ใช่โดย loader การแทนไฟล์เดิมซ้ำ ๆ จะไม่ทำให้ข้อผิดพลาดนั้นเคลื่อนที่

เก็บครึ่งที่ละเอียดอ่อนไว้นอกรายงานสาธารณะระหว่างการสอบสวน แชร์ชื่อคำสั่ง ข้อความข้อผิดพลาด และโครงสร้างของบล็อก โดยนำวัสดุคีย์และเพย์โหลดที่ระบุตัวตนออก คู่มือ openvpn(8) อธิบายทั้งสองรูปแบบของคำสั่งไฟล์และพฤติกรรมไดเรกทอรีทำงานที่อยู่เบื้องหลัง

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