เกิดอะไรขึ้นเมื่อคุณเปลี่ยนผู้ออกใบรับรอง VPN
การเปลี่ยน CA ของ VPN เปลี่ยนความไว้วางใจและตัวตนแยกจากกัน ผู้ตรวจสอบตรวจอะไร ทำไมอุโมงค์เก่าจึงรอด และจะพิสูจน์ว่าทั้งสองทิศทางทำงานได้อย่างไร
การเปลี่ยนผู้ออกใบรับรอง VPN ไม่ใช่การสลับไฟล์ ในวินาทีที่ CA ใหม่ลงนามในใบรับรองแรก ทุกผู้ตรวจสอบที่ยังเชื่อถือเฉพาะตัวเก่าต้องตัดสินใจ และโฮสต์ที่ไม่เคยได้รับสมอใหม่ก็ยังคงปฏิเสธเพื่อนที่ดี ผมเคยเห็นมันพังทั้งสองทาง: เกตเวย์เรียนรู้ CA ใหม่แต่ไคลเอนต์ไม่ จึงเชื่อมต่อใหม่ไม่สำเร็จ ขณะที่อุโมงค์ที่ขึ้นอยู่แล้วยังคงอยู่และทำให้เหตุขัดข้องดูเหมือนปัญหาเส้นทาง นี่คือสิ่งที่เปลี่ยน ตามลำดับที่ความล้มเหลวปรากฏ
การเปลี่ยนครั้งเดียว สองการเปลี่ยนแปลงแยกกัน
ผู้ออกใบรับรองคือชื่อ กุญแจสาธารณะ และกุญแจส่วนตัวที่ลงนาม ผู้ตรวจสอบไม่เคยไว้วางใจ «CA» แบบนามธรรม พวกเขาไว้วางใจใบรับรองเฉพาะใบหนึ่งที่อยู่ในที่เก็บความไว้วางใจอยู่แล้ว และยอมรับผู้ออกก็ต่อเมื่อห่วงโซ่ลายเซ็นไปถึงสำเนาที่เก็บไว้นั้น การเปลี่ยน CA จึงเปลี่ยนสองสิ่งซึ่งล้มเหลวแยกจากกัน: สมอใดได้รับการยอมรับ และตัวตนของเพื่อนรายใดถูกออกภายใต้สมอเหล่านั้น
การติดตั้ง VPN ส่วนใหญ่ตรวจสอบทั้งสองทิศทาง ไคลเอนต์พิสูจน์ตัวตนใบรับรองของเกตเวย์ และเกตเวย์พิสูจน์ตัวตนใบรับรองของไคลเอนต์ การหมุนที่รีเฟรชเฉพาะชุดไคลเอนต์ทำให้เซิร์ฟเวอร์ยังคงปฏิเสธทุกไคลเอนต์ที่ยังนำเสนอตัวตนจาก CA เก่า และทางกลับกันก็พบได้บ่อยพอ ๆ กัน ก่อนอื่นให้ทำบัญชีจุดบังคับใช้: ที่เก็บความไว้วางใจของไคลเอนต์ ไฟล์ ca ของเกตเวย์ พร็อกซีที่สิ้นสุด TLS ด้านหน้า และโพรบที่ตรวจสอบปลายทางจากภายนอก
ผู้ตรวจสอบตรวจอะไร ตามลำดับ
การตรวจสอบเส้นทางไต่จากใบรับรองของเพื่อนผ่านตัวกลางใด ๆ จนถึงสมอที่เชื่อถือได้ ในแต่ละขั้นจะตรวจสอบลายเซ็น ตรวจว่าใบรับรองแต่ละใบอยู่ในช่วงเวลาที่ใช้ได้ และยืนยันว่าข้อจำกัดพื้นฐานและการใช้งานกุญแจอนุญาตให้ผู้ออกลงนามได้ จากนั้นแอปพลิเคชันจึงดูใบรับรองปลายทาง: ชื่อทางเลือกของตัวบุคคลต้องครอบคลุมชื่อที่เรียก และการใช้งานกุญแจแบบขยายต้องอนุญาตการพิสูจน์ตัวตนเซิร์ฟเวอร์หรือไคลเอนต์
หากต้องการทำขั้นตอนนั้นซ้ำแบบออฟไลน์ ให้ชี้ -CAfile ไปที่ชุดที่คุณจะปรับใช้จริง ไม่ใช่ที่เก็บของระบบ มิฉะนั้นคุณกำลังทดสอบโฮสต์ ไม่ใช่การเปลี่ยนแปลง:
openssl verify -CAfile new-ca.crt gateway.crt
openssl verify -CAfile new-ca.crt -untrusted intermediate.crt client.crt
openssl x509 -in gateway.crt -noout -subject -issuer -dates
openssl s_client -connect gw.example.net:443 -CAfile new-ca.crt
คำสั่งนั้นใช้ได้เฉพาะกับตัวรับฟัง TLS ธรรมดาเช่นหน้าผู้ดูแลระบบ HTTPS ของเกตเวย์ ช่องควบคุมของ OpenVPN มาก่อน TLS ดังนั้น s_client จึงตรวจสอบการจับมือของอุโมงค์ไม่ได้
กฎการสร้างเส้นทางเบื้องหลังข้อผิดพลาดเหล่านั้นอยู่ใน RFC 5280 ส่วนที่ 6 กฎเหล่านี้อธิบายความล้มเหลวที่ดูเหมือนเป็นเรื่องตามอำเภอใจ: ตัวกลางที่หมดอายุซึ่งไม่มีใครจำได้ ใบรับรองที่การใช้งานกุญแจห้ามลงนาม หรือข้อจำกัดชื่อที่ตัดโฮสต์ที่คุณกำลังทดสอบออก
ทำไมอุโมงค์เก่ายังทำงานอยู่
ทั้ง TLS และ OpenVPN รักษาเซสชันที่สร้างไว้ให้ยังมีชีวิตหลังการจับมือสิ้นสุดลง ไม่มีสิ่งใดตรวจสอบใบรับรองของเพื่อนซ้ำทุกแพ็กเก็ต ไคลเอนต์ที่เชื่อมต่อก่อนการเปลี่ยนแปลงจึงยังส่งผ่านทราฟฟิกต่อไปจนกว่าจะเจรจาใหม่ เชื่อมต่อใหม่ หรืออุโมงค์ล่ม ช่องว่างนี้เองที่ทำให้การเปลี่ยน CA ดูดีได้เป็นชั่วโมงแล้วล้มเหลวในจังหวะที่แย่ที่สุด: แล็ปท็อปตื่นจากโหมดหลับ การแมป NAT หมดอายุ เกตเวย์รีสตาร์ต
การกลับมาใช้เซสชันซ้ำยังยืดภาพลวงตานี้ต่อไปอีก ไทเก็ตเซสชัน TLS ทำให้ไคลเอนต์กลับมาได้โดยไม่ต้องส่งใบรับรองซ้ำ และการกลับมาใช้ซ้ำข้ามการตรวจสอบเส้นทางเพราะการจับมือครั้งแรกทำไปแล้ว การทดสอบที่ซื่อตรงจึงเป็นการจับมือเต็มรูปแบบในโปรเซสใหม่ รีสตาร์ตไคลเอนต์แทนการเชื่อมต่ออุโมงค์ใหม่ และบนโปรไฟล์ทดสอบให้พิจารณาปิดไทเก็ต เพื่อให้เส้นทางการกลับมาใช้ซ้ำซ่อนห่วงโซ่ที่แตกไม่ได้
แยกชั้นกุญแจแบบคงที่ออกจากเรื่องนี้ tls-auth เพิ่ม HMAC ให้ช่องควบคุม tls-crypt เข้ารหัสและพิสูจน์ตัวตนช่องนั้น และทั้งสองไม่บรรทุกวัสดุใบรับรอง การหมุนอย่างใดอย่างหนึ่งจึงเป็นการเปลี่ยนแปลงแยกที่มีโหมดล้มเหลวของตัวเอง การติดตั้งที่ผสมทั้งสองจะลงเอยด้วยไคลเอนต์ที่กุญแจคงที่ปกติ ใบรับรองล้าสมัย และข้อความข้อผิดพลาดไม่กล่าวถึงทั้งสอง
กับดักของการใช้ชื่อตัวบุคคลซ้ำ
เป็นการน่าล่อใจที่จะใช้ชื่อที่โดดเด่นของผู้มาก่อนซ้ำ เพื่อไม่ให้สิ่งใดปลายน้ำต้องเปลี่ยน การทำเช่นนั้นรักษาบรรทัดผู้ออกให้คงที่ในอินเทอร์เฟซและทำลายสัญญาณเดียวที่คุณต้องการ ใบรับรองสองใบที่มีตัวบุคคลเหมือนกันแต่กุญแจต่างกันแยกกันด้วยชื่อไม่ได้ ชุดที่มีสมอทั้งสองจึงให้ผู้สมัครสองรายแก่ผู้ตรวจสอบและไม่มีกฎให้เลือก
การสร้างเส้นทางอาจเลือกใบที่ผิด รายงานว่า «ไม่สามารถรับใบรับรองของผู้ออกภายในได้» ทั้งที่สมอที่ถูกต้องมีอยู่ หรือสำเร็จบนโฮสต์หนึ่งและล้มเหลวบนอีกโฮสต์ที่มีชุดเดียวกัน เพราะลำดับผู้สมัครต่างกัน หากต้องใช้ชื่อซ้ำ ให้เก็บสมอทั้งสองไว้ในไฟล์แยกกันระหว่างการเปลี่ยนผ่านและโหลดอย่างชัดเจน และรวมเข้าด้วยกันเมื่อทุกเพื่อนนำเสนอผู้ออกใหม่แล้วเท่านั้น มิฉะนั้นให้ตั้งชื่อสามัญที่แตกต่างแก่ตัวแทน เพื่อให้บันทึกและข้อความข้อผิดพลาดบอกว่าผู้ออกใดเป็นผู้ให้ใบรับรองแก่เพื่อนที่ล้มเหลว
การหมุนที่ไม่ทำให้เครือข่ายล่ม
สำหรับการเปลี่ยนตามแผน ให้ยอมรับสมอทั้งสองในช่วงเวลาจำกัดแทนการสลับในขั้นตอนเดียว ออก CA ใหม่และตัวกลางของมัน วางสมอใหม่ไว้ข้างสมอเก่าในชุดของผู้ตรวจสอบแต่ละราย และหลังจากนั้นจึงเริ่มออกใบรับรองของเพื่อนจากสมอนั้น เพื่อนที่มีตัวตนเก่าจะถูกตรวจสอบกับสมอเก่า รายใหม่ทำงานกับสมอใหม่
เมื่อทำตามลำดับนั้น ทุกขั้นตอนย้อนกลับได้ ความล้มเหลวที่คุณหลีกเลี่ยงคือการสลับพร้อมกัน โดยไคลเอนต์ที่พลาดการอัปเดตชุดจะพบกับเกตเวย์ที่ปลดระวางสมอเก่าไปแล้ว การจับมือตาย และไม่มีบันทึกใดบอกว่าฝั่งใดล้าสมัย
ปลดระวางในทิศทางตรงข้าม ออกตัวตนทั้งหมดที่ต้องอยู่รอดอีกครั้ง ยืนยันว่าแต่ละรายนำเสนอห่วงโซ่ใหม่ แล้วจึงถอดสมอเก่าออกจากชุด ปลดกุญแจส่วนตัวของ CA เก่าออกจากบริการ เพราะผู้ออกที่ยังลงนามได้หมายความว่าการหมุนยังไม่เสร็จ เก็บใบรับรองและบันทึกการออกไว้เพื่อการตรวจสอบ ผู้ออกที่สูญหายจะถูกกู้คืนสู่ความไว้วางใจเดิม ส่วนการรั่วไหลต้องใช้ตัวตนใหม่และไม่กลับไปใช้สมอเก่า
ตรวจสอบผลลัพธ์ ไม่ใช่รายการไฟล์
ไฟล์ความไว้วางใจในไดเรกทอรีที่คาดหวังพิสูจน์ได้น้อยนัก แอปพลิเคชันอาจอ่านเส้นทางอื่น รูปแบบอื่น หรือสำเนาในแพ็กเกจที่การอัปเกรดแทนที่ ตรวจสอบพฤติกรรมที่ปลายทั้งสอง ไม่ใช่การมีอยู่ของไฟล์
ยืนยันว่าการเชื่อมต่อใหม่ด้วยตัวตนใหม่สำเร็จ แล้วยืนยันว่าตัวตนที่ออกโดย CA ที่ปลดระวางถูกปฏิเสธ การทดสอบที่สองคือสิ่งที่ผู้คนข้ามไป และเป็นเพียงสิ่งเดียวที่แสดงว่าอำนาจเดิมไม่ให้สิทธิ์เข้าถึงอีกต่อไป เมื่อการติดตั้งพึ่งพา CRL หรือ OCSP ให้ตรวจสอบว่าจุดกระจายในใบรับรองใหม่แก้ได้ และเพื่อนที่สอบถามเข้าถึงผู้ตอบได้
ปิดท้ายด้วยไคลเอนต์ที่ไม่เคยเชื่อมต่อเลย: ล้างสถานะโปรไฟล์ เชื่อมต่อ และอ่านห่วงโซ่ที่เจรจา เพื่อนที่กลับมาใช้เซสชันที่แคชไว้จะรายงานอย่างเบิกบานว่าการย้ายสำเร็จ ทั้งที่ไม่ได้ตรวจสอบสิ่งใดเลย