CA ของ Let’s Encrypt หมดอายุ
เนื่องจาก มันมี CA ที่ Let’s Encrypt ที่ใช้อยู่ มันหมดอายุในวันนี้ แล้วก็เหมือนจะสร้างปัญหา การเชื่อมต่อพอสมควร เลย เขียนวิธีแก้แบบชั่วคราวให้ก่อนที่เขาจะแก้กันจริงๆ
CA ที่หมดอายุ
มี CA Certificate ที่หมดอายุในวันที่ 30 กันยายนที่ผ่านมา ซึ่งชื่อว่า
/O=Digital Signature Trust Co./CN=DST Root CA X3
ซึ่ง CA ตัวนี้ใช้ในการ sign ตัว Certificate ของ Let’s Encrypt ในหลายๆตัว ซึ่งใช้มาตั้งแต่ประมาณปี 2014
ดังนั้น เมื่อครบการหมดอายุ ก็ทำให้ การพิสูจน์ความถูกต้องของ Certificate มีปัญหาไปด้วย
ใครที่สงสัยเรื่องการพิสูจน์กล่าวโดยคร่าวๆคือ การเชื่อถือ Certificate จะต้องพิสูจน์ว่ามันถูกออกโดย CA ที่เราเชื่อหรือไม่ เป็นปัจจัยหนึ่ง
ดังนั้นเมื่อ CA มันหมดอายุ มันก็ไม่น่าเชื่อถือ ก็ทำให้ Certificate ไม่น่าเชื่อถือ
Cross Signing Certificate
ปกติแล้วคนทั่วไปจะ Sign Certificate โดยการใช้ CA แค่เจ้าเดียว อย่างไรก็ตามวิธีนี้ทำให้เกิดปัญหา ขึ้นเช่นเมื่อ CA เจ้านั้นหมดอายุ หรือ Revoke ก็จะทำให้ Certificate นั้นปลิวไปด้วย
กระบวนการ Cross-Signing ในภาพรวมคือ ทำให้เกิด validation chain ขึ้นมามากกว่า 1 path เช่น สมมติว่า เรา มี Certificate C เราอาจจะ สามารถ validate ไปยัง CA A หรือ B เพื่อไปถึง Root ที่เป็น Z ได้
ในกรณีที่ CA A เกิดหมดอายุ ก็ยังสามารถวิ่งไปทาง CA B แทน ทำให้ในระหว่างที่ เขากำลังต่อ CA A อยู่นั้น ยังสามารถใช้งานได้อย่างต่อเนื่อง
ปัญหาที่เจอวันนี้
วันนี้มีน้องเจอปัญหาที่มีผลจากที่ Cert ของ DST X3 หมดอายุ ซึ่งเป็น MacOS Mojave (เก่าพอสมควร) ซึ่งก็ตามรายการก็น่าจะมีผล เพราะต้อง update certificate ใหม่
ปัญหาคือ น้องก็ update ไปแล้วแต่ก็ยังมีปัญหาอยู่
ทีนี้เมื่อเราไปลองเช็คผ่าน OpenSSL ดูเราจะเจอข้อมูลดังนี้
$openssl s_client -connect XXXXXXXXXXXX.XXX:443
CONNECTED(00000005)
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
---
Certificate chain
0 s:/CN=XXXXXXXXXXXX.XXX
i:/C=US/O=Let's Encrypt/CN=R3
1 s:/C=US/O=Let's Encrypt/CN=R3
i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
ตรงนี้เราจะเห็นว่า เราเจอ Certificate หรือ CA ที่เกี่ยวข้องอยู่ 4 ตัวคือ
- XXXX.XXX ของ server เราเอง
- R3 ของ Lets’ Encrypt
- ISRG Root X1 ของ Internet Security Research Group
- DST Root CA X3 ของ Digital Signature Trust Co.
ซึ่งถ้าไล่เป็นสายก็จะพบว่า เป็นตามรูปนี้
ปัญหาคือ ISRG Root X1 มันคือ Root Certificate ที่ Active ในตอนนี้ของ Let’s Encrypt ซึ่งสามารถใช้ได้ยาวๆ ไปถึงปี 2035 แต่ทำไมมันดันไปต่อกับ X3 ที่มันหมดอายุไป
ซึ่งถ้าเราเข้าไปดูในหน้า Chain of Trust ของ Let’s Encrypt ก็จะพบข้อมูลดังนี้ครับ
จะเห็นว่าเขา Provide ให้ทั้งตัว ISRG Root X1 ที่เป็น Self-signed และตัวที่โดน Signed โดย DST Root X3 ดังนั้นเจ้าตัว ISRG Root X1 นี่เป็น Cross-Signed แน่นอน
ทีนี้ทำไมต้องทำลักษณะนี้ ก็ต้องย้อนไปในรายละเอียดก่อน
DST Root X3 เปิดในใช้วันที่ 30 กันยายน เมื่อปี 2000 มาถึงตรงนี้ก็จะเป็นเวลา 21 ปี Certificate ตัวนี้อยู่ในระบบปฏิบัติการต่างๆ มาเนิ่นนาน
อย่างไรก็ตามในช่วงปี 2014 หรือ 6–7ปี ก่อนที่ X3 จะหมดอายุ ก็เริ่มมีการเตรียมการเปลี่ยนผ่านต่างๆ อย่าง Let’s Encrypt เองก็ได้มี ISRG Root X1 ซึ่งเกิดขึ้นใน ปี 2015 มีอายุใช้งานถึง 2035 (ประมาณ 20 ปี เช่นเดียวกัน)
แต่อย่างไรก็ตาม การที่จะนำเอาให้ Root CA ไปใส่ในระบบปฏิบัติการโดยอัตโนมัตินั้นเป็นเรื่องยาก เพราะถ้าใส่เข้าไปง่ายๆ ใครก็ไม่รู้อยู่ๆ ก็สามารถเอา CA เขาไปใส่ในเครื่องเราได้ ทำให้เกิดความไม่ปลอดภัย ดังนั้น Root CA ใหม่ๆ จะต้องได้รับการเห็นชอบ ก่อนที่จะมาลงในระบบปฏิบัติการ
และแน่นอนว่า มันก็เป็นไปได้ยากที่จะไปลงในระบบปฏิบัติการเก่าๆ เรื่องหนึ่งอาจจะเป็นเรื่องความยากในการ update อีกเรื่องก็เป็นเรื่องของเทคโนโลยีที่ ระบบปฏิบัติการเก่าๆ อาจจะไม่รองรับ เช่น การใช้ RSA Key ที่ 4096 หรือการใช้ Sha2 นั้นจะไม่สามารถใช้ได้ใน Windows XP
ดังนั้นเมื่อการลง Trust CA ใหม่ในระบบเก่าๆ เป็นไปได้ยาก
การใช้ Cross Signed CA จึงเป็นทางเลือกในช่วงเปลี่ยนผ่าน จนกว่า ระบบส่วนใหญ่จะได้รับการ update ให้เป็นรุ่นที่มี CA ใหม่แล้ว
ปัญหาของ acme.sh
acme.sh เป็น client สำหรับการขอ certificate ตาม protocol ACME แบบง่ายๆ
โดยปกติ เราทุกคนก็จะใช้ท่านี้แล้วก็ทำการเอา certificate ในไฟล์ fullchain มาใช้ใน service
อย่างไรก็ตามก็มีปัญหาเกิดขึ้นในวันนี้ตาม Issue 3724
เรื่องที่เกิดขึ้นคือ ตัว FullChain ดังไปเอา Root ที่ถูก Sign โดย X3 ที่ดันหมดอายุวันนี้มาใช้งานพอดี เป็น Default
ทำให้บางโปรแกรมที่กระบวนการ validate ไปเชื่อ Certificate ฝั่ง Server ทั้งยวง จะได้ CA สุดท้ายเป็น X3 ซึ่งหมดอายุ ทำให้การพิสูจน์ไม่ผ่านนั่นเอง
การแก้ไขเกี่ยวกับเรื่องนี้
ดังนั้นวิธีการแก้ไขในเบื้องต้นคือ การลบตัว CA Certificate ตัวสุดท้ายของ FullChain ทิ้ง เพื่อให้จะให้ กระบวนการพิสูจน์ในส่วนที่เหลือ มาเชื่อ Certificate ในเครื่องเราแทน
ซึ่งเครื่องพวกเราในปัจจุบันก็ควรที่จะมี CA ISRG X1 ที่เป็น Self-signed ที่ถูกต้องใน Trusted Certificate เรียบร้อยแล้ว
หรือถ้าใครเชี่ยวชาญคำสั่ง Command line สามารถใช้คำสั่ง acme.sh แล้วเพิ่มพารามิเตอร์ — prefered-chain
เพื่อที่จะเลือก Root ให้ถูกต้อง
~/.acme.sh/acme.sh -d XXXX.XXX --issue -w /tmp --preferred-chain "ISRG Root X1"
อย่างไรก็ตามเชื่อว่าน่าจะมีการแก้ไข Default command ให้ถูกต้องในไม่ช้า
ส่งท้าย
- CA Certificate แม้จะมีอายุยาว แต่ก็มีหมดอายุ
- Cross-Signed ใช้ช่วยให้การเปลี่ยนผ่าน Certificate ใหม่ สามารถใช้งานได้ใน สภาพแวดล้อมเดิม
- Bug เกิดขึ้นได้เสมอแม้กระทั่งทีมงานที่น่าจะมืออาชีพมากๆ บางทีมันก็คาดไม่ถึงแบบนี้แหละ
ขอขอบคุณ
- คุณ Sutee .C ที่ช่วยไปหา Tracking ของ ACME และ Command มาปรับพารามิเตอร์