Let’s Encrypt ย่อสายโซ่ความเชื่อถือให้สั้นลง
(letsencrypt.org)- Let’s Encrypt เปลี่ยนไปใช้สายโซ่ใบรับรองที่สั้นลงซึ่งจบที่ ISRG Root X1 โดยไม่ต่ออายุ cross-sign ที่จะหมดอายุในวันที่ 30 กันยายน 2024
- ในช่วงเปิดตัวแรก ๆ root ของตนเองยังไม่ได้รับความเชื่อถืออย่างเพียงพอ จึงพึ่งพา DST Root CA X3 ของ IdenTrust แต่ตอนนี้ขอบเขตความเชื่อถือของ ISRG Root X1 กว้างขึ้นมากแล้ว
- การ cross-sign ให้ root ที่เพิ่มเข้ามาในปี 2021 เพื่อรองรับ Android รุ่นเก่าเป็นมาตรการชั่วคราว และทำให้อุปกรณ์ Android เก่าสามารถเชื่อถือใบรับรอง Let’s Encrypt ต่อไปได้อีก 3 ปี
- ในช่วง 3 ปีที่ผ่านมา สัดส่วนอุปกรณ์ Android ที่เชื่อถือ ISRG Root X1 เพิ่มจาก 66% เป็น 93.9% และเมื่อเลิกใช้ cross-sign ปริมาณไบต์ของใบรับรองใน TLS handshake ก็ลดลงมากกว่า 40%
- ผู้ใช้ Android 7.0 หรือต่ำกว่า แนะนำให้ใช้ Firefox Mobile และผู้ดูแลเว็บไซต์กับผู้พัฒนาไคลเอนต์ ACME ควรตรวจสอบการจัดการ chain ให้สอดคล้องกับกำหนดการเปลี่ยนผ่านในปี 2024
เบื้องหลังการยุติ cross-sign
- ในช่วงเปิดตัวแรก ๆ Let’s Encrypt ได้ cross-sign ใบรับรอง intermediate ด้วย DST Root CA X3 ของ IdenTrust เพื่อให้ใบรับรองได้รับความเชื่อถืออย่างกว้างขวาง
- เป็นวิธีที่ทำให้ใบรับรองที่ออกโดย intermediate certificate ดังกล่าวได้รับความเชื่อถือ แม้ root ของตนเองอย่าง ISRG Root X1 จะยังไม่ได้รับความเชื่อถืออย่างแพร่หลาย
- เมื่อเวลาผ่านไป ISRG Root X1 ก็ได้รับ ความเชื่อถืออย่างกว้างขวาง ด้วยตัวเอง
- ปลายปี 2021 intermediate certificate ที่ถูก cross-sign และตัว DST Root CA X3 เองมีกำหนดหมดอายุ
- ในขณะนั้นเบราว์เซอร์รุ่นใหม่ ๆ เชื่อถือ root ของ Let’s Encrypt แล้ว แต่อุปกรณ์ Android มากกว่าหนึ่งในสามยังใช้ OS เวอร์ชันเก่าอยู่
- อุปกรณ์เหล่านี้อาจไม่สามารถเชื่อถือเว็บไซต์ที่ใช้ใบรับรอง Let’s Encrypt ได้อย่างกะทันหัน
- ในปี 2021 Let’s Encrypt ใช้การ cross-sign โดยตรงที่ root แทนการ cross-sign ที่ intermediate certificate เพื่อสร้างมาตรการชั่วคราวที่คงอยู่ได้นานกว่า DST Root CA X3
- มาตรการนี้ทำให้อุปกรณ์ Android รุ่นเก่าเชื่อถือใบรับรอง Let’s Encrypt ต่อไปได้อีก 3 ปี
- cross-sign ดังกล่าวจะหมดอายุในวันที่ 30 กันยายน 2024
เหตุผลที่เปลี่ยนเป็น chain ที่สั้นลง
- Let’s Encrypt จะไม่ขอ cross-sign ใหม่เพื่อยืดเวลาความเข้ากันได้อีกต่อไป
- ในช่วง 3 ปีที่ผ่านมา สัดส่วนอุปกรณ์ Android ที่เชื่อถือ ISRG Root X1 เพิ่มจาก 66% เป็น 93.9%
- Android 14 สามารถ อัปเดต trust store ได้โดยไม่ต้องอัปเดต OS ทั้งหมด ทำให้สัดส่วนนี้อาจเพิ่มขึ้นอีก
- การเลิกใช้ cross-sign ลดจำนวนไบต์ของใบรับรองที่ส่งใน TLS handshake ได้ มากกว่า 40%
- ต้นทุนการดำเนินงานก็ลดลงอย่างมาก ทำให้ Let’s Encrypt สามารถมุ่งใช้งบประมาณกับการปรับปรุงความเป็นส่วนตัวและความปลอดภัยได้
กำหนดการเปลี่ยนผ่านปี 2024
- วันพฤหัสบดีที่ 8 กุมภาพันธ์ 2024: หยุดให้ cross-sign เป็นค่าเริ่มต้นในการร้องขอไปยัง API endpoint
/acme/certificate- สมาชิกส่วนใหญ่จะมี ACME client ตั้งค่า chain ที่จบที่ ISRG Root X1 และเว็บเซิร์ฟเวอร์จะให้ chain ที่สั้นลงใน TLS handshake
- chain ที่ยาวกว่าซึ่งจบที่ cross-sign ที่ใกล้หมดอายุยังสามารถร้องขอเป็น alternate chain ได้ต่อไป
- วันพฤหัสบดีที่ 6 มิถุนายน 2024: หยุดให้บริการ chain แบบ cross-sign ที่ยาวกว่าโดยสมบูรณ์
- เป็นช่วงเวลาก่อน cross-sign หมดอายุนานกว่า 90 วันเล็กน้อย ซึ่งเท่ากับอายุการใช้งานของใบรับรอง 1 ใบ
- กำหนดการนี้มีไว้เพื่อให้สมาชิกมีรอบการออกใบรับรองเต็มอย่างน้อยหนึ่งรอบในการย้ายออกจาก chain แบบ cross-sign
- วันจันทร์ที่ 30 กันยายน 2024: ใบรับรอง cross-sign หมดอายุ
- สำหรับผู้ใช้ส่วนใหญ่ ไม่ควรถือเป็นเหตุการณ์พิเศษ และความล้มเหลวของ client ควรเกิดขึ้นไปแล้วในช่วง 6 เดือนก่อนหน้า
สิ่งที่ผู้ใช้และผู้ดูแลระบบควรตรวจสอบ
- ผู้ใช้ Android 7.0 หรือต่ำกว่า อาจต้องดำเนินการเพื่อให้ยังเข้าถึงเว็บไซต์ที่ปกป้องด้วยใบรับรอง Let’s Encrypt ได้ต่อไป
- Let’s Encrypt แนะนำให้ติดตั้งและใช้ Firefox Mobile ซึ่งใช้ trust store ของตนเองแทน trust store ของ Android OS
- ผู้ดูแลเว็บไซต์ ควรตรวจสอบสถิติการใช้งานเว็บไซต์และสตริง user-agent ที่ใช้งานอยู่ในไตรมาส 2 และ 3 ของปี 2024
- หากการเข้าชมจาก Android ลดลงอย่างกะทันหัน อาจมีผู้ใช้ Android 7.0 หรือต่ำกว่าจำนวนมาก
- แนะนำให้ให้คำแนะนำผู้ใช้กลุ่มดังกล่าวให้ใช้ Firefox Mobile
- ผู้พัฒนาไคลเอนต์ ACME ต้องดาวน์โหลดและติดตั้ง certificate chain ที่ API ให้มาอย่างถูกต้องทุกครั้งที่ออกและต่ออายุใบรับรอง
- รูปแบบปัญหาในอดีตรวมถึงกรณีที่ไม่ดาวน์โหลด chain เลยและให้เฉพาะ end-entity certificate เท่านั้น
- อีกกรณีคือไม่ดาวน์โหลด chain แต่ให้ chain ที่ hardcode ไว้
- และยังมีกรณีที่ดาวน์โหลด chain เฉพาะตอนออกครั้งแรก แต่ไม่ดาวน์โหลดอีกครั้งเมื่อต่ออายุ
- คำถามเกี่ยวกับการเปลี่ยนผ่านสามารถถามได้ที่ community forum ของ Let’s Encrypt
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
จำได้ว่า Let's Encrypt เคยประกาศว่าจะทำการเปลี่ยนผ่านนี้ในช่วงฤดูร้อนปี 2019 แล้วเลื่อนออกไปหลังรับฟัง ฟีดแบ็กจากชุมชน
ตอนนั้นผมเป็นหนึ่งในคนที่เรียกร้องอย่างหนักให้ทบทวนใหม่ แต่ไม่คิดว่าในเรื่องนี้พวกเขาจะเลื่อนออกไปได้นานถึง 4 ปีครึ่ง เกินความคาดหมายไปมาก ขอบคุณที่ดูแลระบบนิเวศ TLS อย่างรอบคอบขนาดนี้
ถ้าจะครอบคลุมอุปกรณ์ Android 95% ต้องรองรับไปถึง Android 7.0 Nougat เมื่อเดือนสิงหาคม 2016
https://en.wikipedia.org/wiki/Android_Nougat
ส่วนการครอบคลุมอุปกรณ์ iOS 95% ใช้แค่ iOS 14 เมื่อเดือนกันยายน 2020 ก็พอ และถ้าดูแค่ 90% Android คือ 8.1 (2017), iOS คือ 15 (2021)
https://iosref.com/ios-usage
https://en.wikipedia.org/wiki/IOS_14
ดูเหมือน Apple จะทำได้ดีกว่าในการโน้มน้าวหรือเปิดทางให้ผู้คนย้ายไปใช้ระบบปฏิบัติการที่ใหม่กว่า
สาเหตุที่อุปกรณ์ไม่ได้อัปเดตคือผู้ผลิตหยุดให้การอัปเดต
ตามหน้า CA bundle ของ curl บันเดิลของ Mozilla มีขนาดประมาณ 200KB หลังแตกไฟล์ และ Chrome app บน Android ของผมมีขนาด 25MB ดังนั้นการเพิ่มขนาดแอป 1% เพื่อให้ทันสมัยอยู่เสมอดูสมเหตุสมผล
แน่นอนว่าแอปอื่น ๆ ก็อาจต้องการ CA ล่าสุดด้วย แต่ก็น่าพิจารณาว่าจำเป็นต้องมี CA ทั้งหมดไหม หรือมีแค่ CA ที่มีโอกาสจะใช้งานจริงก็พอ
หากผู้ผลิตราคาถูกบางรายบอกว่าจะไม่อัปเดตให้ลูกค้า Google ก็ทำอะไรได้ไม่มากนัก อาจกำหนดได้ว่าถ้าจะได้รับหรือคงการรับรอง Android ต้องให้การอัปเดตเป็นระยะเวลาหนึ่ง แต่ถึงจุดหนึ่งผู้ผลิตรายนั้นก็อาจเลิกใช้ Android ไปเลย
แถม Qualcomm เองก็ไม่ให้ เคอร์เนลและบล็อบที่อัปเดตแล้ว สำหรับชิปเซ็ตเก่าเมื่อเวลาผ่านไป แม้ Google จะเจรจาให้ยืดออกจาก 18 เดือนอันน่าสมเพชในอดีตได้แล้ว แต่ Qualcomm ก็ไม่มีหน้าที่ต้องให้ความร่วมมือมากกว่านี้ พอ Google เริ่มทำชิปเซ็ตของตัวเอง ความสนใจต่อปัญหานี้ก็ลดลงไปบ้าง
ไม่ได้หมายความว่านี่เป็นเรื่องดี แต่ด้วยโมเดลของ Android โดยมากก็แทบหลีกเลี่ยงไม่ได้ที่จะเป็นแบบนี้ และโมเดลของ Apple ทำให้ควบคุมส่วนเหล่านี้ได้มากกว่า
วิธีที่ทำให้ cross-signature เก่ายังคงทำงานต่อได้ค่อนข้างน่าสนใจ
cross-signature ใหม่ค่อนข้างแปลกตรงที่มีอายุยาวไปหลังการหมดอายุของ DST Root CA X3 นี่เป็นทางออกที่เป็นไปได้เพราะ Android จงใจไม่บังคับใช้วันหมดอายุของใบรับรองที่ใช้เป็น trust anchor
จริง ๆ แล้ว trust anchor ทำงานต่างจากใบรับรองอื่น ๆ อยู่พอสมควร ซึ่งอาจทำให้ประหลาดใจได้
[1] https://letsencrypt.org/2020/12/21/extending-android-compati...
[2] https://alexsci.com/blog/name-non-constraint/
เท่าที่จำได้ ปัญหาใหญ่ข้อหนึ่งคือ OpenSSL รุ่นเก่าตรวจสอบการหมดอายุของ root anchor นี่ยังไม่ใช่ทั้งหมด ตอนนั้นที่บริษัท Ubuntu ต้องแพตช์อะไรบางอย่างเพื่อรับมือสถานการณ์นี้ และแพตช์เพิ่งออกมาก่อนหมดอายุไม่กี่วัน ทำให้บางระบบล่มไปชั่วครู่ เราต้อง rebuild Docker image จำนวนมากเพื่อแก้ปัญหา
ผมคิดว่าที่ใช้วิธีอ้อมนี้เพราะมันสุดโต่งและไม่เคยมีแบบอย่างมาก่อน แต่ส่วนต่างของค่าใช้จ่ายเมื่อเทียบกับการขอ cross-sign จาก root ที่ยังไม่หมดอายุและเข้ากันได้กว้างขวางคงมหาศาลมาก การทดสอบก็คงต้องทำอย่างมหาศาลเช่นกัน แม้จะไม่สมบูรณ์แบบ แต่ก็น่าประทับใจที่โดยรวมผ่านไปได้ค่อนข้างราบรื่น
1 time_check = now()
2 for cert in Cn to C0
3 if time_check < cert.valid_from || time_check > cert.valid_to
4 return EXPIRED
5 time_check = cert.issue_time
6 return NOT_EXPIRED
แต่พอค้นดูแล้ว ในความเป็นจริงมันทำงานแบบที่ไม่มีบรรทัดที่ 5 ทำให้การตรวจสอบเวลาทั้งหมดอิงกับเวลาปัจจุบัน ใบรับรองทุกใบใน chain ต้องยังใช้ได้อยู่ตอนนี้
ใบรับรอง code signing ทำงานในแบบที่ผมเคยคิดว่า TLS ก็ทำแบบนั้น โค้ดที่มี timestamp แล้วจะยังคงใช้ได้แม้ root certificate หมดอายุไปแล้ว ตราบใดที่ root ยังใช้ได้ ณ เวลาที่ timestamp นั้นถูกประทับไว้
หวังว่าการหมดอายุของใบรับรองแบบ cross-sign จะไม่ส่งผลอะไรกับคนส่วนใหญ่ แต่ครั้งก่อนที่ DST cross-sign หมดอายุ นั้นไม่ใช่แบบนั้น
เท่าที่จำได้ GnuTLS จัดเส้นทาง (path) หลังหมดอายุได้ไม่ถูกต้อง ดูเหมือนมันสร้างได้แค่เส้นทางไปยังใบรับรองที่หมดอายุแล้ว รายงานว่าหมดอายุ แล้วหยุดทำงานโดยไม่สนใจเส้นทางอื่นที่เป็นไปได้
ที่แย่กว่านั้นคือ GnuTLS เป็นไลบรารี TLS ที่ apt ใช้เมื่อใช้ HTTPS แม้ HTTPS จะไม่ใช่ค่าเริ่มต้น แต่ทีมความปลอดภัยของเราต้องการ vendor แพ็กเกจทั้งหมดเพื่อส่งมอบอย่างปลอดภัย ซึ่งโดยตัวมันเองก็สมเหตุสมผล แต่ต้นทุนคือเกิดเหตุขัดข้อง เหมือนว่าจะถูกแก้ใน Bullseye แล้ว และบังเอิญโชคดีมากที่เป็นช่วงประมาณแค่หนึ่งสัปดาห์ก่อนหมดอายุ Azure ก็เจอเหตุขัดข้องหลายอย่างที่เกี่ยวข้องกับการหมดอายุนั้นด้วย
นอกจากการใช้ HTTP ที่ไม่เข้ารหัสแล้ว มีแนวทางแก้ไขที่เสนอไว้บ้างไหมที่จะทำให้ TLS ไม่เป็นองค์ประกอบที่เปราะบางที่สุดบนเว็บอีกต่อไป?
การเปลี่ยนแปลงไม่รู้จบอย่างการเลิกใช้โปรโตคอล การหมดอายุของใบรับรอง และการเปลี่ยนทดแทน ดูเหมือนเป็นการขยาย planned obsolescence มากเกินไป
ส่วนที่ไม่ดีซึ่งนำไปสู่ planned obsolescence คืออุปกรณ์ถูกตัดขาดจากอัปเดตของผู้ผลิตเร็วเกินไป และบุคคลที่สามก็อัปเดตให้ไม่ได้
แนวทางแก้ที่ผมชอบคือมีกฎหมายว่า หากผู้ผลิตจำเป็นต้องหรืออยากหยุดผลิตอัปเดตความปลอดภัยก่อนครบ 10 ปีหลังเลิกขาย ก็ต้องเปิดทุกอย่างเป็นโอเพนซอร์ส หรือให้ผู้ซื้อทุกคนได้รับเงินคืนเต็มจำนวน
เหตุผลที่ต้องทำแบบนั้นคือการเพิกถอนแบบกระจายทั่วโลกเป็นปัญหาที่ยากอย่างไร้เหตุผล จึงลดอายุใบรับรองเพื่อลดขอบเขตความเสียหาย เป็นการบรรเทาปัญหาที่การผูกบางส่วนระหว่างผู้ใช้กับใบรับรองแทบจะเพิกถอนไม่ได้
แน่นอนว่านี่ไม่ได้ช่วยปลอบใจมากนัก แต่โลกของใบรับรองอายุสั้นหลัง ACME ยังให้ประสบการณ์นักพัฒนาดีกว่าโลกฝันร้ายของใบรับรอง Verisign อายุยาว และควรจำไว้ว่าทางเลือกแทน TLS ก็เลี่ยงไม่ได้ที่จะเจอปัญหาคล้ายกัน
รูปแบบใบรับรอง x509 แทบไม่ได้เปลี่ยนมาเป็นเวลานานแล้ว
การเปลี่ยนแปลงของโปรโตคอลน่าจะเริ่มนิ่งแล้ว TLS 1.2 ถูกนำมาใช้ในปี 2008 และยังถือว่าใช้ได้อยู่ จึงยากจะมองว่าเป็นของใหม่อีกต่อไป มีคนจำนวนมากตรวจสอบอย่างละเอียดแล้ว ก็หวังว่าปัญหาส่วนใหญ่จะถูกเปิดเผยออกมาแล้ว
ในความคิดผม สิ่งที่ Let's Encrypt ทำโดยพื้นฐานก็อาจมองได้ว่าเป็น DANE อยู่แล้ว ถ้าอย่างนั้นก็แค่รองรับไปเลยไม่ได้หรือ แน่นอนว่าอาจมีกรณีใช้งานที่ DANE ไม่เหมาะสม
ผมไม่เห็นเหตุผลที่ความสมบูรณ์แบบจะต้องมาขวางสิ่งที่ดีพอ และใครที่ต้องการก็ควรให้ใช้ DANE ได้
คำว่า “สามารถลดต้นทุนการดำเนินงานลงอย่างมาก และนำเงินไปทุ่มกับการปรับปรุงความเป็นส่วนตัวและความปลอดภัยได้” หมายความว่าพวกเขาจ่ายเงินระดับหลายล้านดอลลาร์สำหรับ cross-sign หรือ?
ค่าใช้จ่ายรวมในปีเดียวกันอยู่ที่ 5.1 ล้านดอลลาร์ ดังนั้นรายจ่ายนี้จึงคิดเป็นเกือบ 10% ของงบประมาณ
[0]: https://beta.candid.org/profile/9328188?keyword=46-3344200&a...
มีใครรู้เบื้องหลังไหมว่าบริษัทใบรับรองยอม cross-sign ให้ได้อย่างไร? Let’s Encrypt ไม่ได้ฆ่าโมเดลธุรกิจของพวกเขาไปหมดเลยหรือ?
บริษัทอย่าง RapidSSL หรือ GoDaddy คงไม่ยอม cross-sign ให้ Let’s Encrypt เว้นแต่จะได้รับข้อเสนอเงินระดับ “ซื้อธุรกิจ CA ทั้งหมดของเราไปเลย”
แต่การขายใบรับรอง DV ไม่ใช่โมเดลธุรกิจของ IdenTrust ดังนั้นตามที่มีคนคาดไว้ที่อื่น พวกเขาอาจยินดีให้ cross-sign ด้วยเงินไม่ถึงหกหลักก็ได้ ด้วยกลไกการทำงานของ TLS root certificate นั้น cross-sign ของ IdenTrust ก็มีประโยชน์ต่อ LE พอ ๆ กับ cross-sign จาก CA ที่ทำกำไรมหาศาล
IdenTrust ก็ไม่ได้ดูเหมือนจะเจ๊ง
1 IdenTrust 48.5% 53.6%
2 DigiCert Group 13.1% 14.5%
3 Sectigo (Comodo Cybersecurity) 12.1% 13.4%
4 GlobalSign 6.1% 6.7%
5 Let's Encrypt 5.8% 6.4%
6 GoDaddy Group 4.8% 5.3%
https://en.wikipedia.org/wiki/Certificate_authority
เมื่อปลายปี 2021 ตอนที่ใบรับรองระดับกลางแบบ cross-sign และตัว DST Root CA X3 เองหมดอายุ ว่ากันว่าแม้เบราว์เซอร์รุ่นใหม่ทั้งหมดจะเชื่อถือ root ของ LE แล้ว แต่อุปกรณ์ Android มากกว่าหนึ่งในสามยังคงรันระบบปฏิบัติการเก่าอยู่ ทำให้มีโอกาสที่เว็บไซต์ที่ใช้ใบรับรอง LE จะกลายเป็นไม่น่าเชื่อถือขึ้นมาทันที
เพิ่งรู้เมื่อไม่กี่สัปดาห์ก่อนว่า ดูเหมือนว่า ผู้ใช้ ubiquiti ก็ได้รับผลกระทบด้วย
ช่วงหลังย้ายแบ็กเอนด์จาก AWS ไปยังเซิร์ฟเวอร์โลคัล เลยต้องเปลี่ยนจาก Letsencrypt ที่ใช้ประจำไปเป็น ZeroSSL
เพราะอุปกรณ์ IoT รุ่นปี 2016 ที่ยังรองรับอยู่ไม่มี root certificate ที่จำเป็นต่อการตรวจสอบใบรับรอง LE น่าจะเกี่ยวข้องกับการหมดอายุในปี 2021 ของ root certificate R3 ที่ LE ใช้อยู่
ค่อนข้างช็อกที่ใบรับรองเพียงใบเดียวหมดอายุแล้วอาจทำให้ผลิตภัณฑ์ที่ขายไปทั้งหมดกลายเป็นอิฐได้ ในกรณีนี้ยังมี root certificate ที่ใช้ได้ของผู้ให้บริการรายอื่นอยู่ เลยไม่ใช่ปัญหาใหญ่
ถึงขั้นยังคงออกใบรับรองต่อหลังจากวันที่ CA/Browser Forum กำหนดไว้ด้วย ตอนนั้นผมนึกว่าทุกคนคงตระหนักแล้วว่าการใช้ Web PKI แต่ไม่มีวิธี push อัปเดตนั้นเข้ากันไม่ได้ แต่ดูเหมือนจะไม่ใช่
ตั้งแต่ไม่นานหลังเริ่มมีการใช้ cross-sign ก็ถอด ใบรับรอง cross-sign ออกจากไซต์ที่มุ่งเป้าเดสก์ท็อปมาตลอด
เพราะเกิดปัญหาความเข้ากันได้ที่ก่อนหน้านี้ไม่มี และตัวตรวจสอบใบรับรองบางตัวสะดุดกับ root certificate ที่หมดอายุ ผู้ใช้ที่ได้รับผลกระทบไม่ใช่สายเทคนิค เลยไม่เคยทราบสาเหตุรากจริง ๆ ในที่สุด