เหตุใดผมจึงเลิกใช้ใบรับรองแบบดั้งเดิมบนเว็บไซต์ https ของตัวเอง
(rachelbythebay.com)- ผู้เขียนมีความรู้สึกต่อต้าน ACME protocol มาหลายปี เพราะ ความซับซ้อนและความเสี่ยงในการนำไปใช้งานจริง
- ACME client ที่มีอยู่เดิมจำนวนมากมี โค้ดที่เสี่ยงด้านความปลอดภัยหรือเข้าใจยาก จึงไม่อยากนำมารันด้วยตัวเอง
- แต่เมื่อคุณภาพของผู้ให้บริการจดโดเมน Gandi ลดลงและราคาสูงขึ้น จึงเริ่ม ลงมือทำเครื่องมือต่ออายุใบรับรองด้วยตัวเอง
- หลังจากลองผิดลองถูกอยู่นาน ในที่สุดก็สร้าง เครื่องมือที่ออกใบรับรองผ่าน Let's Encrypt ได้ด้วยตัวเอง สำเร็จ
- ช่วงท้ายของบทความอธิบายขั้นตอนการทำงานจริงของ ACME protocol และ รายละเอียดระดับล่างของการติดตั้งใช้งาน เช่น JSON, base64, ลายเซ็นดิจิทัล อย่างละเอียด
Why I no longer have an old-school cert on my https site
ที่มาและแรงจูงใจ
- เมื่อต้นปี 2023 ผู้เขียนเคยอธิบาย เหตุผลที่ยังคงใช้ใบรับรองแบบดั้งเดิมต่อไป แต่ในปี 2025 นี้ได้มาแบ่งปันว่า เหตุใดจึงเลิกใช้แนวทางนั้นแล้ว
- ความรู้สึกต่อต้าน ACME protocol มีมาตั้งแต่ปี 2018 โดย เทคโนโลยีเว็บที่ซับซ้อนและรูปแบบการเข้ารหัสที่เข้าใจยาก เป็นอุปสรรคสำคัญ
- ACME client ส่วนใหญ่เป็นโค้ดที่ยากจะเชื่อถือ และมองว่า อันตรายเกินกว่าจะให้ทำงานด้วยสิทธิ์ root
- หลัง Gandi ถูกซื้อกิจการโดยกองทุน private equity คุณภาพก็ตกลงและราคาสูงขึ้น ทำให้ ไม่เหลือเหตุผลที่จะใช้ใบรับรองแบบเดิมต่อไปอีก
จุดเริ่มต้นของการลงมือทำเอง
- แทนที่จะใช้เครื่องมือที่มีอยู่ ผู้เขียนค่อย ๆ ลงมือทำเองตั้งแต่ ฟังก์ชันยูทิลิตีเล็ก ๆ ทีละตัว
- เริ่มจากทำ wrapper เพื่อให้สามารถใช้ไลบรารี JSON สำหรับภาษา C ชื่อ jansson จาก C++ ได้
- มีการพิจารณาไลบรารีหลายตัวเพื่อสร้าง JWK (โครงสร้างคีย์) แต่ส่วนใหญ่ช่วยอะไรไม่ได้มาก จึง ตัดสินใจทำเองทั้งหมด
- ระหว่างทางมีทั้งหยุดและกลับมาเริ่มใหม่หลายครั้ง ก่อนจะค่อย ๆ นำองค์ประกอบย่อยเหล่านั้นมาต่อเข้าด้วยกันทีละส่วน
สภาพแวดล้อมทดสอบและการใช้งานจริง
-
เพื่อไม่ให้ไปรบกวนเซิร์ฟเวอร์จริงของ Let's Encrypt โดยตรง จึงใช้ ACME server สำหรับทดสอบชื่อ "pebble" ในสภาพแวดล้อมแยกต่างหาก
-
หลังจากล้มเหลวมาแล้วนับครั้งไม่ถ้วน ก็สร้าง เครื่องมือรุ่นแรกที่รับ CSR แล้วออกใบรับรองให้ได้ สำเร็จ โดย
- ทดสอบสำเร็จกับ Let's Encrypt staging server
- สำเร็จใน production environment เช่นกัน
- นำไปใช้กับเว็บไซต์จริงเรียบร้อยแล้ว
อธิบายรายละเอียดของ ACME protocol
- สร้าง RSA key และสร้าง CSR (Certificate Signing Request) โดยให้มีทั้ง CN และ SAN
- parse JSON จาก ACME directory URL เพื่อดึง endpoint อย่าง newNonce, newAccount, newOrder
- ดึง modulus และ public exponent จาก private key แล้วแปลงเป็น การเข้ารหัสแบบ base64url ที่เหมาะกับการใช้งานบนเว็บ
- หลังสร้าง JWK แล้ว ก็ลงลายเซ็นแบบ RSA SHA256 พร้อมกับ JSON payload
- รับ Nonce ผ่าน HTTP HEAD request แล้วส่ง signed request แบบ POST เพื่อสร้าง account
Locationheader ใน response ไม่ได้ใช้เพื่อ redirect จริง แต่ใช้เป็น URL ตัวระบุ account
ความซับซ้อนของ ACME protocol
- ทั้งที่เป็นเพียงการออกใบรับรองธรรมดา แต่ก็ยังมี
- แฮช SHA256, base64web, โครงสร้าง JSON ซ้อนใน JSON, ลายเซ็น RSA
- HEAD request, การใช้ Location header เพื่อระบุ account, ความจำเป็นของ Nonce แบบใช้ครั้งเดียว เป็นต้น
- ผู้เขียนยังบอกด้วยว่า ณ จุดนี้ยัง ไปไม่ถึงขั้นการสั่งออกใบรับรอง การพิสูจน์ความเป็นเจ้าของโดเมน (เช่น TXT record) หรือการทำ authorization ให้เสร็จสมบูรณ์
- ยังชี้ด้วยว่า client บางตัวแม้จะติดตั้งการเข้ารหัส publicExponent ผิด ก็ยังทำงานได้ ซึ่งสะท้อนถึง ความหย่อนของมาตรฐาน
บทสรุป
- ACME เป็นระบบที่ซับซ้อนมาก และ การทำเองต้องอาศัยการลองผิดลองถูกและความพยายามอย่างมหาศาล
- ถึงอย่างนั้น ผู้เขียนก็เลิกใช้ใบรับรองแบบดั้งเดิมและ เปลี่ยนผ่านสู่ระบบอัตโนมัติเต็มรูปแบบได้สำเร็จ
- พร้อมทิ้งมุกไว้ด้วยว่า ความซับซ้อนนี้อาจเป็นโครงสร้างที่มีไว้ เพื่อการันตีงานให้ใครบางคนหรือเปล่า
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ฉันเป็นหัวหน้าฝ่ายเทคนิคของทีม SRE/infra ของ Let’s Encrypt เลยเป็นคนที่คิดเรื่องปัญหาแบบนี้อยู่มาก
JSON Web Signature เป็นฟอร์แมตที่จุกจิกมากจริง ๆ และ ACME API ก็จริงจังกับความเป็น RESTful มากเป็นพิเศษ
ถ้าให้ฉันออกแบบเองก็คงไม่ทำแบบนี้
ฉันคิดว่าภูมิหลังที่ทำให้โครงสร้างแบบนี้เกิดขึ้นมาคือ IETF พยายามใช้มาตรฐานของ IETF ให้มาก และการออกแบบแบบคณะกรรมการก็มีส่วนไม่น้อย
ถ้ามีแค่ไลบรารีสำหรับ JSON, JWS, HTTP ไม่กี่ตัวมันก็ดีขึ้นมาก แต่ปัญหาคือโดยเฉพาะใน C แม้แต่ไลบรารีเหล่านั้นก็ยังใช้งานไม่ง่าย
ภาษาของ RFC เองก็ซับซ้อนและมักอ้างอิงเอกสารอื่นเยอะ เลยกำลังทำทั้งไคลเอนต์แบบอินเทอร์แอ็กทีฟและเอกสารเพิ่มเติมเพื่อช่วยเรื่องนี้อยู่
ฉันไม่ค่อยเข้าใจคำพูดที่ว่า JSON Web Signature เป็นฟอร์แมตที่จุกจิก
ฉันทำงานกับของซับซ้อนอย่าง ASN.1, Kerberos, PKI อยู่บ่อย ๆ เลยไม่คิดว่า JWS จะเป็นฟอร์แมตที่ยากขนาดนั้น
ต่อให้ต้องเขียนโค้ดเองก็ตาม ฉันก็ยังมองว่ามันง่ายกว่า S/MIME, CMS, Kerberos มาก
เลยอยากให้ช่วยอธิบายเพิ่มว่า JWS มัน ‘จุกจิก’ ตรงไหน
ถ้าจะพูดถึงปัญหาของ JWT ฉันกลับคิดว่าประเด็นสำคัญกว่าคือยังไม่ได้กำหนดไว้มาตรฐานชัดเจนว่า HTTP user agent ควรรับหรือร้องขอ JWT อย่างไร
มีคนหนึ่งบอกว่า “ถ้าจะออกใบรับรองเกิน 3 ใบต้องจ่ายเงิน” แต่ฉันใช้มาห้าปีแล้วไม่เคยโดนเรียกเก็บเงินเลย น่าจะเป็นความเข้าใจผิดหรือข้อมูลผิดมากกว่า
มีการอธิบายว่าทำไมถึงต้องใช้ “e=AQAB” แทน “e=65537” โดยชี้ว่าเป็นเพราะ JSON จัดการกับตัวเลขได้ไม่ดี
ถ้าโยนค่าตัวเลขใหญ่มากอย่าง 4723476276172647362476274672164762476438 ให้ JSON parser ส่วนใหญ่ก็จะตัดเงียบ ๆ ให้เหลือแค่จำนวนเต็ม 64 บิตหรือ float หรือถ้าโชคดีก็อาจจะ error ออกมา
ถ้าเป็นภาษาอย่าง Common Lisp ก็คงจัดการได้ดี แต่ในโลกจริงคนที่พัฒนาในสภาพแวดล้อมแบบนั้นมีไม่มาก
เพราะงั้นถ้าจะส่งตัวเลขขนาดใหญ่ใน JSON อย่างเสถียร การแปลงเป็นอาร์เรย์ไบต์แล้วส่งแบบ base64 ยังดูดีกว่า
ถึงมันจะดูเหมือนไม่มีปัญหาอะไร แต่เรื่องแบบนี้เป็นต้นตอของปัญหาความปลอดภัยหลายอย่าง เลยคิดว่าการจัดการตัวเลขทั้งหมดในโปรโตคอลแบบนี้ก็สมเหตุสมผล
ข้อเสียคือความอ่านง่ายแบบเป็นมิตรกับมนุษย์ของ JSON จะหายไป และส่วนตัวฉันคิดว่า S-Expression ที่ทำให้เป็นมาตรฐานน่าจะเป็นตัวเลือกที่ดีกว่ามาก
แต่โลกเลือก JSON
ถ้าไม่เข้าใจว่าทำไมโลกถึงเลือก JSON ฉันว่าก็คือจงใจมองข้ามมากกว่า
JSON ทำให้คนส่วนใหญ่เขียน/แก้/อ่านข้อมูลจำนวนมากได้ง่ายด้วยมือ
แต่ Canonical S-Expression ต้องใส่ข้อมูลความยาวนำหน้าทุกองค์ประกอบ ทำให้แก้ด้วยมือยุ่งยากมาก
ถ้าจะเขียน S-Expression ต้องมานั่งนับตัวอักษรและแก้ prefix ทีละจุด มันน่ารำคาญมาก
ตรงกันข้ามกับที่หลายคนคาดไว้ ความง่ายในการเขียนและแก้ด้วยมือนี่แหละคือเหตุผลที่ JSON อยู่รอด
และ FYI ตัว Ruby JSON parser ก็จัดการเลขใหญ่ได้ดี
ฉันเคยเจอบั๊กในแอป C# ที่ JSON serializer ส่ง BigInt ออกไปเป็นตัวเลข แล้วฝั่ง JS รับไปตีความผิดแบบเงียบ ๆ
ยังรู้สึกแปลกใจอยู่เลยที่ overflow เป็นพฤติกรรมมาตรฐานแทนที่จะเป็น error
หลังจากนั้นฉันเลยติดนิสัยว่าตัวเลขที่ใหญ่กว่า 32 บิตต้องจัดการเป็นสตริงเสมอ
การเปรียบเทียบระหว่าง {"e":"AQAB"} กับ {"e":65537} ก็พอมีเหตุผล แต่ถ้าเอาไปเทียบกับ {"e":"65537"} ผลที่ JSON parser ทุกตัวให้ก็เหมือนกันอยู่ดี
ไม่ว่าจะเป็นตัวเลขหรือสตริงก็แปลงได้ชัดเจน
แน่นอนว่าถ้าค่ามันใหญ่เกินกว่าจะใส่ใน double ได้ นั่นก็เป็นปัญหาของภาษาหรือ parser เอง แต่ฉันมองว่าเป็นอีกเรื่องหนึ่งจากวิธีการแทนค่า
ฉันคิดว่าปัญหาของ JSON ไม่ใช่ที่ฟอร์แมต แต่เป็นเพราะ parser ถูกสร้างมาเพื่อแมปกับชนิดข้อมูลของ JS เดิมที
ถึง parser บางตัวจะจัดการได้ดี แต่ถ้าทำแบบนั้น portability ของ JSON ก็หายไป
ต่อให้แปลงเป็น Base64 ก็เจอปัญหาเดียวกันได้เหมือนกัน (เพราะไม่เป็นไปตามมาตรฐาน)
จะใช้ replacer กับ reviver เพื่อ parse แบบคัสตอมก็ได้ แต่ไม่ได้การันตีว่าทุกสภาพแวดล้อมจะมีฟังก์ชันนี้
สุดท้ายสมมติฐานที่ว่าใช้ parser มาตรฐานมาอ่าน JSON ได้เลยนี่แหละคือต้นตอของข้อผิดพลาด
ถ้าเรียกมันว่าเป็นฟอร์แมตอื่นแทน JSON ปัญหาคงน้อยลง แต่คนก็ยังจะโยนมันเข้า parser ตรง ๆ อยู่ดีถ้ามันหน้าตาเหมือน JSON
ภาษา Go มี
json.Numberที่ช่วยถอดรหัสตัวเลขเป็นสตริงได้โดยไม่เสียข้อมูลขอแนะนำหนึ่งใน decimal แบบ arbitrary precision ที่ฉันชอบมากที่สุด https://github.com/ncruces/decimal?tab=readme-ov-file#decimal-arithmetic
พูดแบบกึ่งล้อเล่น ฉันยังไม่ค่อยเห็นเหตุผลว่าทำไมกรณีนี้ S-Expression จะดีกว่า
ในบรรดา LISP เองก็มีที่ไม่รองรับเลขคณิตแบบความแม่นยำไม่จำกัดเหมือนกัน
ฉันแปลกใจว่าทำไมผู้เขียนถึงมีท่าทีวิจารณ์ ACME และไคลเอนต์หลายตัวขนาดนั้น
ดูไม่น่าใช่แค่ปัญหาเรื่องความชำนาญในการใช้ เลยเดาว่าเขาน่าจะไม่ชอบตัวแนวคิด ACME เองหรือเครื่องมือรอบ ๆ มันโดยรวม
ฝั่งเราก็ใช้ LE กับบางไซต์มาตั้งแต่ปี 2019 และระหว่างนั้นก็ลอง ACME client มาหลายตัว
อย่างเช่น Crypt-LE ก็ใช้กับงานของเราได้ดี และตอนพยายามเชื่อมกับ Sectigo ACME พบว่า le64 ไม่พอ ก็เลยลองทั้ง certbot, lego, posh-acme และอีกหลายตัว
สุดท้ายเราแก้ปัญหา environment ของ GHA แล้วใช้ certbot ต่อ และ posh-acme ก็ดีเหมือนกัน
พอกลับไปอ่านอีกที น้ำเสียงแหลมคมของผู้เขียนไม่ได้พุ่งไปที่ ACME หรือไคลเอนต์ แต่ไปที่ตัวสเปกเอง
สรุปคือไอเดียของ ACME ดี แต่การติดตั้งและใช้งานจริงน่าผิดหวัง
ฉันคิดว่าตัวเองมีมุมมองคล้ายผู้เขียน
ขออ้างคำพูดของผู้เขียนว่า ‘ไคลเอนต์ที่มีอยู่จำนวนมากเป็นโค้ดอันตราย และฉันไม่ไว้ใจพอจะเอามันมารันด้วยสิทธิ์ root บนเซิร์ฟเวอร์ของฉัน’
สำหรับงานที่อ่อนไหวด้านความปลอดภัย ฉันคิดว่าความระมัดระวังแบบนี้สมเหตุสมผล
มีการแชร์ลิงก์โพสต์เก่าเพื่อให้บริบทกับคนที่อ่านแล้วไม่ค่อยเข้าใจน้ำเสียงของต้นฉบับ
มีคนจำนวนไม่น้อยที่ไม่ชอบการต้องรันอะไรบางอย่างบนเซิร์ฟเวอร์ทั้งที่ตัวเองไม่เข้าใจมัน และฉันก็เห็นด้วยกับความคิดนั้น
แต่โลกความปลอดภัยเป็นเกมแมวจับหนูโดยธรรมชาติ มันเลยต้องเปลี่ยนตลอด และสุดท้ายก็เลี่ยงไม่ได้ที่จะต้องตามให้ทัน
โชคดีที่ ACME เปิดโอกาสให้ฉันทำไคลเอนต์เองได้ตามใจ
ไม่จำเป็นต้องใช้ certbot เสมอไป และมันก็ไม่ใช่โครงสร้างแบบ TPM ที่มาปิดกั้นทรัพยากรของฉัน
ถ้าจะลงมือเขียน ACME client ใหม่ตั้งแต่ต้น มีคนแชร์ประสบการณ์ว่าอ่าน RFC ต่าง ๆ (รวมถึงเอกสาร JOSE ที่เกี่ยวข้อง) เองนั้นง่ายกว่าที่คิด
เขาเคยลงมือเขียนเอง และยังเขียนบทความสรุปเพื่ออธิบาย flow ของ ACME v2 ไว้ด้วย https://www.arnavion.dev/blog/2019-06-01-how-does-acme-v2-work/
ถึงจะใช้แทน RFC ทางการไม่ได้ แต่ใช้บทความนี้เป็นเหมือนแผนผังลำดับขั้นและดัชนีตามวิธีการต่าง ๆ ได้ดี
มีคนบอกว่าเคยทำ ACME client เองเป็นโปรเจ็กต์สุดท้ายของวิชาความปลอดภัยที่ MIT ด้วย https://css.csail.mit.edu/6.858/2023/labs/lab5.html
มีการเหน็บแนมความจริงชวนขำว่า แทนที่จะอ่านคู่มือทีละบรรทัด เอาเวลามาเขียนโพสต์อธิบายทุกขั้นตอนเป็นภาษาอังกฤษลง Hacker News กลับได้แต้มอินเทอร์เน็ตมากกว่า
มีคนขอบคุณผู้เขียนที่ชี้ให้เห็นว่าความซับซ้อนของโปรโตคอลโครงสร้างพื้นฐานเว็บเพิ่มสูงขึ้นเรื่อย ๆ
มาตรฐานพวกนี้ไม่ใช่แค่ภาระสำหรับนักพัฒนาที่ต้องพึ่งเครื่องมือหรือไคลเอนต์เท่านั้น แต่ยังทำหน้าที่เหมือน ‘กำแพงกฎระเบียบ’ ที่สุดท้ายเปิดทางให้เฉพาะบริษัทใหญ่เดิม ๆ เท่านั้นที่ทำตามข้อกำหนดในการให้บริการอินเทอร์เน็ตได้
ACME อย่างเดียวอาจยังไม่ใช่อุปสรรคการเข้าตลาดที่ข้ามไม่พ้น แต่เมื่อสะสมรวมกันแล้วมันก็กลายเป็นกำแพงขึ้นมาจริง ๆ
OpenBSD มี ACME client ที่เรียบง่ายและเบามากรวมอยู่ใน base OS
ได้ยินมาว่าทำขึ้นใหม่เพราะตัวเลือกเดิม ๆ หนักเกินไปและไม่สอดคล้องกับปรัชญา Unix
เลยน่าเสียดายที่ผู้เขียนดูเหมือนไม่ได้พิจารณาทางนี้
และคงพอร์ตไป OS อื่นได้ไม่ยากถ้าลงแรงอีกนิด
อีกมุมหนึ่งก็คิดว่า ACME client ของ OpenBSD สะท้อนให้เห็นว่าแนวคิดแบบ OpenBSD ยังไม่เข้าใจว่าทำไมความปลอดภัยถึงซับซ้อนขนาดนี้
ไคลเอนต์นี้ออกแบบให้ติดตั้งและใช้งานบนเครื่องนั้นโดยตรง และใช้การแยกส่วนเพื่อไม่ให้องค์ประกอบแต่ละชิ้นกระทบกัน
แต่ตัวโปรโตคอล ACME เองเปิดให้ทำสถาปัตยกรรมแบบแยกขาดเต็มรูปแบบ (air-gapping) ได้ โดยเว็บเซิร์ฟเวอร์ ตัวขอใบรับรอง และ DNS server จะอยู่คนละสภาพแวดล้อมกันก็ได้
ถ้าไม่ใช้ OpenBSD integrated client ทางเลือกนี้อาจซับซ้อนกว่า แต่ในเชิงหลักการออกแบบความปลอดภัยฉันมองว่าดีกว่า
การบอกว่า ‘แค่ติดตั้ง OpenBSD ก็จบ’ เป็นเพียงวิธีที่ง่ายกว่าเท่านั้น
มีการแนะนำ uacme (https://github.com/ndilieto/uacme) ด้วย
เป็นโค้ด C ขนาดเบา และหลังจากทนปัญหากับไคลเอนต์ Python ของ LE เรื่อง dependency อยู่พักใหญ่ ก็เปลี่ยนมาใช้ตัวนี้อย่างเสถียร
มีคนแชร์ว่าใช้ ACME client ของ OpenBSD อยู่โดยตรง และมันทำงานได้ดีมาก
คำแนะนำให้ “สร้าง RSA private key ขนาด 4096 บิต” กลับมีแต่จะทำให้ผู้เข้าชมเว็บช้าลง โดยความปลอดภัยที่ได้จริงก็แทบเท่า 2048 บิต
เขาเน้นว่าการใช้ใบรับรอง leaf แบบ 2048 บิตดีกว่า
มีคนถามกลับว่า 4096 บิตจะไม่ทนต่อการดักจับแบบพาสซีฟ/ถอดรหัสภายหลังได้ดีกว่าหรือ
และก็สงสัยด้วยว่าความปลอดภัยของ intermediate certificate ส่งผลต่อการโจมตีแบบไม่พร้อมกันตามเวลาหรือไม่
มีคนบอกว่าโฮสต์เว็บของตัวเองรองรับแต่ RSA key เลยตั้งใจใช้ RSA 4096 บิตเพื่อกดดันให้รีบรองรับ EC key
มีคนบอกว่าการลงมือทำงานแบบนี้เองช่วยให้เก่งขึ้นก็จริง แต่โทนของบทความผู้เขียนฟังดูเหมือนกำลังหงุดหงิดกับโปรโตคอลหรือกระบวนการติดตั้ง Let’s Encrypt มากกว่า
ทั้งที่ใช้ lightweight ACME library (https://github.com/jmccl/acme-lw เป็นต้น) ก็อัตโนมัติได้สบาย เลยสงสัยว่าทำไมต้องทำให้มันยากขนาดนี้
ปัญหาเรื่องแฟลกและบิตฟิลด์ทั้งหมดเป็นมรดกทางประวัติศาสตร์จาก ASN.1/X.509 ที่แบกความซับซ้อนเชิงคณิตศาสตร์ไว้อย่างหนัก และไลบรารีกับซอฟต์แวร์ทั้งหมดก็ยังถูกจำกัดด้วยขอบเขตเทคโนโลยีจากยุค 80
ตอน Let’s Encrypt เข้ามาหรือเมื่อตอน HTTP/2 ออกมา มันเคยเป็นโอกาสสุดท้ายที่จะจัดระเบียบความยุ่งเหยิงนี้ แต่ในโลกจริง ACME CA แค่ประกอบจากเชลล์สคริปต์, OpenSSL กับแอลกอฮอล์ก็พอทำงานได้แล้ว แถมยังมีปัญหา compatibility กับซอฟต์แวร์เดิม เลยไม่เกิดการกระโดดครั้งใหญ่
มีการเล่าประสบการณ์ว่าทุกวันนี้แรงกดดันให้ย้ายไปใช้ HTTPS เพิ่มขึ้นเรื่อย ๆ
ตัวอย่างเช่น ใน WhatsApp ตอนนี้ลิงก์ HTTP เปิดไม่ได้แล้ว
มีคนเสนอว่าใช้ proxy กับ caching จะช่วยลดภาระทราฟฟิกได้ และเหมาะกับเซิร์ฟเวอร์ขนาดเล็ก
มีคนย้ำว่าไม่ว่า ACME จะซับซ้อนแค่ไหน มันก็ยังดีกว่าไม่รองรับ TLS มาก
มีการสรุปว่าองค์ประกอบต่าง ๆ อย่าง “RSA key, SHA256 digest, RSA signature, สิ่งที่จริง ๆ แล้วไม่ใช่ base64 แต่เป็น base64, การต่อสตริง, JSON ซ้อนใน JSON, การใช้ Location header เป็นตัวระบุแทน 301 redirect, การใช้ HEAD request เพื่อค่าหัวข้อเดียว, การต้องมีคำขอแยกสำหรับ nonce ในทุก request ฯลฯ” ถูกซ้อนทับกันอยู่
“และยังเหลือขั้นตอนที่ซับซ้อนอีก เช่น การสร้าง certificate order, การจัดการ authorization/challenge, key thumbprint, การประกอบ TXT record ฯลฯ”
มันซับซ้อนจนน่าเหลือเชื่อจริง ๆ และเขาก็ส่งข้อความให้กำลังใจพร้อมขอบคุณที่สรุปเรื่องนี้มาแชร์