วิธีติดตั้ง Certbot บน Apache Ubuntu 24.04
ติดตั้ง Certbot 2.9.0 ผ่าน apt บน Ubuntu 24.04 เพื่อรับ Let's Encrypt ฟรี พร้อมวิธีแก้ปัญหา ServerName ที่ทำให้การออกใบรับรองล้มเหลวและวิธีตั้งค่า vhost
สิ่งที่คุณกำลังสร้าง
การสร้างเว็บไซต์บน Apache บน Ubuntu 24.04 ที่รองรับ HTTPS ด้วยใบรับรอง Let's Encrypt ซึ่งได้รับการรับรองโดยเบราว์เซอร์ โดยใบรับรองนี้ออกโดย Certbot และจะได้รับการต่ออายุโดยอัตโนมัติผ่าน systemd timer โดยที่คุณไม่ต้องดำเนินการใดๆ อีก คำสั่งที่ใช้ในการทำงานมีเพียงบรรทัดเดียว อย่างไรก็ตาม ปัญหาทั้งหมดมักเกิดขึ้น ก่อน ถึงขั้นตอนการใช้คำสั่งดังกล่าว เช่น การตั้งค่า vhost ที่ไม่มี ServerName, พอร์ต 80 ถูกปิดที่ firewall ของผู้ให้บริการ หรือ DNS ยังคงชี้ไปยังเซิร์ฟเวอร์เครื่องเดิม ดังนั้นคู่มือนี้จึงเน้นไปที่การเตรียมความพร้อมล่วงหน้า และระบุข้อความแสดงข้อผิดพลาด (error string) ที่เกิดขึ้นจากความผิดพลาดแต่ละจุด
หมายเหตุประกอบการใช้งาน สองประการ หากคุณใช้ nginx ขั้นตอนการทำงานจะมีลักษณะเดียวกัน แต่จะแตกต่างกันที่ plugin และการตั้งค่า ให้ใช้ คู่มือฉบับ nginx แทน และหากระบบที่คุณต้องการรักษาความปลอดภัยเป็นระบบภายในเท่านั้น เช่น แผงควบคุมผู้ดูแลระบบบน IP ส่วนตัว หรือเซิร์ฟเวอร์ staging ที่ไม่มีผู้อื่นเข้าถึง คุณไม่จำเป็นต้องใช้ Certificate Authority เลย การใช้ self-signed certificate จะมีความซับซ้อนน้อยกว่าและสามารถใช้งานแบบ offline ได้
สิ่งที่ต้องเตรียม และ 3 สาเหตุที่ทำให้เกิดข้อผิดพลาดก่อน Certbot เริ่มทำงาน
- Apache กำลังให้บริการเว็บไซต์ผ่าน HTTP ปกติอยู่แล้ว Apache plugin ของ Certbot จะทำการแก้ไขการตั้งค่าเว็บไซต์ที่มีอยู่เดิม แต่จะไม่สร้างเว็บไซต์ใหม่ หากคุณเริ่มใช้งานจาก VPS เปล่า ให้ติดตั้ง LAMP stack บน Ubuntu 24.04 ให้เรียบร้อยก่อน เนื่องจากคู่มือนี้เป็นเนื้อหาเรื่อง TLS ที่ต้องใช้ร่วมกัน
- โดเมนสาธารณะที่มี A record ชี้มายัง IP ของ VPS การตรวจสอบแบบ HTTP-01 ของ Let's Encrypt คือการที่เซิร์ฟเวอร์ตรวจสอบจะเชื่อมต่อมายังเครื่องของคุณผ่านอินเทอร์เน็ต ดังนั้นจึงไม่สามารถใช้ homelab ที่ผ่าน NAT โดยไม่มีการทำ port forward ได้ รวมถึงไม่สามารถใช้
.localหรือใช้เพียง IP ได้dig +short example.comจะต้องคืนค่าเป็นที่อยู่ของ VPS ของคุณ และหากคุณเพิ่งเปลี่ยนค่า DNS ในชั่วโมงที่ผ่านมา ให้รอจนกว่าค่า TTL ของระเบียนเดิมจะหมดอายุก่อนเริ่มดำเนินการ - หากมี AAAA record ต้องเป็นค่าที่ถูกต้อง Let's Encrypt จะเลือกใช้ IPv6 หากมีการประกาศ AAAA record ไว้ ดังนั้นหาก AAAA record เก่าค้างอยู่จะทำให้การตรวจสอบล้มเหลว แม้ว่าการ
curlจากแล็ปท็อปของคุณ (ซึ่งอาจใช้ IPv4) จะทำงานได้ปกติก็ตาม ให้ประกาศ AAAA record ที่ถูกต้อง หรือไม่ประกาศเลย
ต้องเปิดพอร์ต 80 และ 443 ทั้งใน ufw และใน network firewall ของผู้ให้บริการ เนื่องจากแผงควบคุมการโฮสติ้งส่วนใหญ่จะมีไฟร์วอลล์อีกชั้นที่ระบบปฏิบัติการมองไม่เห็น การตรวจสอบ HTTP-01 จะทำผ่านพอร์ต 80 โดยเฉพาะ คุณไม่สามารถรันกระบวนการนี้ผ่านพอร์ต 443 เพียงอย่างเดียวได้
sudo ufw allow "Apache Full"
sudo ufw statusหากเตรียมการตามนี้ทั้งหมดจะใช้เวลาเพียง 15 นาที โดย 10 นาทีคือการอ่านเนื้อหา
Snap หรือ apt Certbot? สำหรับ 24.04 การใช้ apt นั้นเพียงพอแล้ว
Certbot เปลี่ยนไปใช้การแจกจ่ายผ่าน snap เมื่อหลายปีก่อนด้วยเหตุผลสำคัญ คือแพ็กเกจของ distro ล้าสมัย Ubuntu 20.04 ใช้ Certbot 0.40 และไม่มีการอัปเดต ทำให้ทีมพัฒนาต้องเสียเวลาแก้ไข bug ที่ค้างมานานกว่า 5 ปี สำหรับ 24.04 ปัญหานี้หมดไปแล้ว เนื่องจากใน archive มี Certbot 2.9.0 ซึ่งเป็นเวอร์ชันปัจจุบัน และ unattended-upgrades จะคอยอัปเดต patch ให้เสมอ คำแนะนำสำหรับ OS นี้คือ: ให้ใช้ apt คุณไม่จำเป็นต้องใช้ snapd daemon, Apache plugin จะถูกติดตั้งพร้อมกันในการทำ transaction เดียวกัน และ renewal timer จะทำงานร่วมกับ systemd ตามมาตรฐานของ Debian
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionผลลัพธ์ที่ถูกต้องคือ: certbot 2.9.0 แพ็กเกจ python3-certbot-apache คือ plugin ที่ใช้สำหรับอ่านและแก้ไขไฟล์ config ของ Apache หากไม่มีแพ็กเกจนี้ certbot --apache จะล้มเหลวพร้อมข้อผิดพลาด The requested apache plugin does not appear to be installed
การใช้ snap ยังคงเหมาะสมใน 2 กรณี: เมื่อคุณต้องการใช้ Certbot เวอร์ชันใหม่ล่าสุดทันทีที่ปล่อยออกมา หรือเมื่อคุณต้องการ DNS plugin ที่แจกจ่ายผ่าน snap เท่านั้น (plugin ของผู้ให้บริการ certbot-dns-* หลายรายเป็นเช่นนั้น) หากคุณเลือกวิธีนี้:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotไม่ว่าคุณจะเลือกวิธีใด ห้ามติดตั้งทั้งสองแบบพร้อมกัน การติดตั้งสองระบบจะทำให้ตัวจัดการการต่ออายุ (renewal schedulers) เกิดการขัดแย้งกันที่ /etc/letsencrypt และ certbot ที่ shell ค้นหาใน PATH อาจไม่ใช่ตัวที่ใช้จัดการใบรับรองของคุณ บรรทัด apt remove ด้านบนไม่ใช่ข้อความตกแต่งแต่เป็นสิ่งที่จำเป็นต้องทำ
การตั้งค่า vhost สำหรับ Certbot ต้องเสร็จสมบูรณ์ — ServerName คือหัวใจสำคัญ
certbot --apache ทำงานโดยการค้นหา virtual host ที่ใช้ port-80 ซึ่งมี ServerName หรือ ServerAlias ตรงกับ -d domain ที่คุณระบุ เพื่อยืนยันความเป็นเจ้าของโดเมน จากนั้นจึงสร้างไฟล์ SSL ที่คู่กันสำหรับ vhost นั้น หากไม่พบ ServerName ที่ตรงกัน การทำงานจะล้มเหลว — และค่า 000-default.conf เริ่มต้นของ Ubuntu จะมีการใส่เครื่องหมาย comment ไว้ที่ ServerName การใส่ comment ในบรรทัดดังกล่าวเป็นสาเหตุหลักที่ทำให้คำสั่งหลักในคู่มือนี้ทำงานผิดพลาด
ดังนั้น ก่อนเริ่มใช้งาน Certbot คุณต้องตั้งค่า vhost แบบระบุชื่อ (name-based) ให้กับเว็บไซต์ก่อน โดยสร้าง /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>เปิดใช้งานและตรวจสอบว่า Apache สามารถอ่านค่าและส่งข้อมูลไปยัง vhost นั้นได้ถูกต้อง:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -Sconfigtest จะต้องแสดงผล Syntax OK หากมีการแสดงผล AH00558: apache2: Could not reliably determine the server's fully qualified domain name ด้วย นั่นคือคำเตือนเกี่ยวกับ global ServerName ไม่ใช่ vhost ของคุณ ซึ่งไม่มีผลเสียและสามารถข้ามได้ด้วย echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2
ผลลัพธ์จาก -S คือส่วนที่สำคัญที่สุด คุณต้องเห็นบรรทัดลักษณะ port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) พร้อมกับ alias www.example.com อยู่ด้านล่าง — Apache จะรายงานค่า symlink ของ sites-enabled ที่อ่านจริง ไม่ใช่ไฟล์ที่คุณแก้ไขใน sites-available หากไม่มี example.com ปรากฏใน port 80 Certbot จะไม่สามารถค้นหาโดเมนพบเช่นกัน
Issue the certificate: certbot --apache
sudo certbot --apache -d example.com -d www.example.comการรันครั้งแรกจะมีการถาม 3 อย่าง ได้แก่: ที่อยู่อีเมล (ใช้สำหรับบัญชี ACME และการแจ้งเตือนสำคัญจาก CA; เนื่องจาก Let's Encrypt ไม่ส่งคำเตือนวันหมดอายุแล้ว ผู้ใช้จึงต้องตรวจสอบการต่ออายุด้วยตนเอง), การยอมรับข้อกำหนดของ Let's Encrypt, และการยินยอมแบ่งปันอีเมลกับ EFF ปัจจุบันไม่มีคำถามเรื่องการทำ redirect แล้ว เนื่องจากตั้งแต่ Certbot 2.0 เป็นต้นมา ตัวติดตั้ง Apache จะทำการ redirect จาก HTTP ไปยัง HTTPS โดยค่าเริ่มต้น ซึ่งเป็นสิ่งที่ควรจะเป็น หากคุณจำเป็นต้องใช้ HTTP แบบปกติเพื่อให้บริการเนื้อหา ให้ใช้ flag --no-redirect
เมื่อดำเนินการสำเร็จจะมีลักษณะดังนี้ และคุณควรตรวจสอบรายละเอียดทั้งหมดแทนการอ่านผ่านๆ:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.
Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.comเบื้องหลังข้อความดังกล่าว Certbot ได้ดำเนินการ 4 อย่างดังนี้: เปิดใช้งาน module ssl ของ Apache หากยังไม่ได้เปิดใช้งาน, เขียนไฟล์ example.com-le-ssl.conf ซึ่งเป็นสำเนาของ vhost ของคุณที่ *:443 พร้อมกับ SSLEngine on และเส้นทางของ certificate, เปิดใช้งานไฟล์ดังกล่าว, และเพิ่ม block RewriteRule ลงใน vhost เดิมที่ port-80 เพื่อทำ 301 redirect ไปยัง HTTPS ไฟล์ vhost เดิมของคุณจะถูกแก้ไขแต่ไม่ได้ถูกแทนที่ และไฟล์ SSL twin จะถูกสร้างไว้ข้างกันเพื่อให้คุณสามารถตรวจสอบทุกบรรทัดที่ระบบเพิ่มเข้าไปได้
Where the certificate actually lives, and why you never copy it
Everything lands under /etc/letsencrypt/live/example.com/: fullchain.pem (the certificate plus intermediate chain — what servers should point at), privkey.pem (the private key, root-readable only), plus cert.pem and chain.pem for software that wants the pieces separately. These are symlinks into /etc/letsencrypt/archive/, and that indirection is the renewal mechanism: renewal writes new files into archive/ and repoints the symlinks. Point any other software at the live/ paths and it picks up renewals for free; copy the files somewhere and you have built yourself an outage 90 days out.
The other file worth knowing is /etc/letsencrypt/renewal/example.com.conf, which records how this certificate was issued — authenticator = apache, installer = apache, the domains — so renewal can repeat the process unattended, including reloading Apache afterward.
การต่ออายุถูกกำหนดตารางเวลาไว้แล้ว — ให้ตรวจสอบเท่านั้น ห้ามสั่ง build ใหม่
ใบรับรองของ Let's Encrypt มีอายุการใช้งาน 90 วันตามการออกแบบ และแพ็กเกจ apt ได้ติดตั้งระบบไว้ให้แล้ว นั่นคือ systemd timer ซึ่งจะรัน Certbot วันละ 2 ครั้งในช่วงเวลาที่สุ่มขึ้นมา เพื่อต่ออายุใบรับรองใดๆ ที่กำลังจะหมดอายุภายใน 30 วัน ห้ามเพิ่ม cron job เข้าไปอีก เพราะการมีตัวจัดการตารางเวลาซ้ำซ้อนจะทำให้เกิด log noise และเสี่ยงต่อการถูกจำกัดจำนวนครั้ง (rate-limit)
systemctl list-timers certbot.timer
sudo certbot renew --dry-runคำสั่งแรกจะแสดงสถานะ timer ที่กำลังทำงาน โดยจะมีเวลา NEXT อยู่ภายใน 24 ชั่วโมงข้างหน้า — ตารางเวลาคือวันละ 2 ครั้งโดยมีการหน่วงเวลาแบบสุ่ม ดังนั้นเวลาที่แน่นอนจึงไม่สามารถคาดเดาได้ (หากติดตั้งผ่าน snap timer จะเป็น snap.certbot.renew.timer แทน) การทำ dry run คือการจำลองการต่ออายุเต็มรูปแบบกับ staging environment ของ Let's Encrypt — ซึ่งเป็นการทดสอบ challenge จริง แต่ไม่มีการออกใบรับรองจริง และไม่เสียโควตา rate-limit ผลลัพธ์ที่ถูกต้องจะลงท้ายด้วย:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)หากการทำ dry run ล้มเหลว การต่ออายุจริงในอีกประมาณ 60 วันข้างหน้าจะล้มเหลวในลักษณะเดียวกัน — ให้แก้ไขทันทีในขณะที่ใบรับรองปัจจุบันยังใช้งานได้ตามปกติ สาเหตุที่พบบ่อยคือการเพิ่มกฎ firewall หลังจากออกใบรับรองเสร็จ ซึ่งทำให้ port 80 ถูกปิดอีกครั้ง
ตรวจสอบด้วย curl และข้อมูลที่ควรแสดงบนสัญลักษณ์รูปกุญแจ
curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -datesรายการแรกควรส่งคืน HTTP/1.1 301 Moved Permanently พร้อมกับ header Location: https://example.com/ ซึ่งเป็นการ redirect ที่ Certbot ติดตั้งไว้ รายการที่สองควรส่งคืน HTTP/1.1 200 OK โดยที่ curl ต้องไม่แจ้งข้อผิดพลาดเกี่ยวกับ TLS รายการที่สามจะแสดงข้อมูลผู้ออกใบรับรอง (issuer) ซึ่งเป็นบรรทัด O = Let's Encrypt ที่มีค่า CN สั้นๆ เช่น R12 หรือ E7 และมีอายุการใช้งาน notAfter ประมาณ 90 วัน หากใช้งานผ่าน browser คุณจะเห็นสัญลักษณ์รูปกุญแจ และเมื่อคลิกที่สัญลักษณ์นั้นจะแสดงข้อมูลผู้ออกใบรับรองแบบเดียวกัน หาก curl ใช้งานได้ปกติแต่ browser แจ้งเตือน แสดงว่าคุณกำลังดูหน้าเว็บที่ถูกแคชไว้หรือใช้ hostname ผิด ไม่ใช่ปัญหาที่ใบรับรอง (certificate)
Multiple sites: ใช้ SAN certificate ใบเดียว หรือแยกหนึ่งใบต่อหนึ่ง site
ทั้งสองวิธีสามารถใช้งานได้ และมีขั้นตอนการต่ออายุเหมือนกัน หากเป็น site ที่ไม่เกี่ยวข้องกันบนเครื่องเดียวกัน ให้รันคำสั่ง issue หนึ่งครั้งต่อหนึ่ง site โดยแต่ละ site จะมี directory ของตนเองภายใต้ live/ และมีไฟล์ config สำหรับการต่ออายุแยกกัน หากโดเมนหนึ่งมีปัญหา จะไม่ส่งผลกระทบต่อการต่ออายุของโดเมนอื่น นี่คือวิธีที่ผมแนะนำเป็นค่าเริ่มต้น
สำหรับ site เดียวที่มีหลายชื่อ ให้รวมชื่อเหล่านั้นไว้ใน SAN certificate ใบเดียว โดย certificate หนึ่งใบสามารถรองรับได้สูงสุด 100 ชื่อ ดังที่คุณได้ทำไปแล้วด้านบนด้วย example.com และ www.example.com หากต้องการเพิ่มชื่อลงใน certificate เดิมในภายหลัง ให้ทำการ reissue โดยระบุชื่อ certificate และรายชื่อโดเมนใหม่แบบ ครบถ้วน ดังนี้:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comCertbot จะตรวจพบชุดโดเมนที่เปลี่ยนแปลงไป และจะถามเพื่อยืนยันการขยายขอบเขต (expansion) จากนั้นจะทำการแทนที่ certificate เดิมในตำแหน่งเดิม ซึ่งก็คือ path live/ ทำให้ไม่ต้องแก้ไขส่วนอื่น โปรดทราบว่าการระบุรายชื่อใหม่จะเป็นการแทนที่รายชื่อเดิม ไม่ใช่การเพิ่มต่อท้าย หากคุณละเว้น www จากคำสั่งดังกล่าว ชื่อโดเมนเดิมจะถูกลบออกจาก certificate ใหม่โดยอัตโนมัติ
Wildcards ต้องใช้ DNS-01 และโดยปกติแล้วคุณไม่จำเป็นต้องใช้ wildcard
HTTP-01 ไม่สามารถออกใบรับรองแบบ *.example.com ได้ เนื่องจากการวางไฟล์บน web server เป็นการยืนยันความเป็นเจ้าของเพียง hostname เดียว ไม่ใช่ทั้ง namespace การใช้ wildcard จำเป็นต้องใช้ DNS-01 challenge โดย Certbot จะตั้งค่า TXT record ที่ _acme-challenge.example.com ซึ่งในทางปฏิบัติหมายถึงการใช้ certbot-dns-* plugin ร่วมกับ API credentials ของ DNS provider ของคุณ หรือต้องแก้ไข TXT records ด้วยตนเองทุกครั้งที่มีการต่ออายุด้วย --manual (ซึ่งยุ่งยากมาก และไม่แนะนำให้ใช้วิธีนี้) รายละเอียดขั้นตอนทั้งหมด ตั้งแต่กลไกของ TXT record ไปจนถึงการใช้ plugin เพื่อต่ออายุแบบอัตโนมัติ สามารถอ่านได้ใน wildcard certificates with Certbot over DNS-01 คำแนะนำ: หากคุณมี subdomain ที่ทราบค่าแน่นอนเพียง 4 ชื่อ การใช้ SAN certificate ที่ระบุชื่อทั้ง 4 ชื่อนั้นง่ายกว่าการใช้ wildcard และไม่จำเป็นต้องเก็บ DNS API keys ไว้บน server
Failure modes, with the strings you will see
Certbot refuses to start because Apache's config is broken.
The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')Plugin จะรัน configtest ก่อนเริ่มดำเนินการใดๆ และจะหยุดทำงานหาก Apache มีข้อผิดพลาด — ข้อความ \n คือข้อความจริงที่ปรากฏ เนื่องจาก Certbot พิมพ์ค่า repr ของ exception ออกมา ให้ลองรัน sudo apache2ctl configtest ด้วยตนเอง เพราะคำสั่งนี้จะระบุชื่อไฟล์และบรรทัดที่ผิดพลาด ซึ่งมักเกิดจากการพิมพ์ผิดจากการแก้ไขไฟล์ด้วยตนเอง, SSLCertificateFile ที่ชี้ไปยัง path ที่ไม่มีอยู่จริง หรือมีการเรียกใช้ module ที่ไม่ได้เปิดใช้งาน แก้ไขจนกว่าจะปรากฏข้อความ Syntax OK แล้วจึงรัน Certbot อีกครั้ง
No vhost matches the domain.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.นี่คือความผิดพลาดจากการขาด ServerName ที่พบในช่วงการออกใบรับรอง Certbot ได้ค้นหา ServerName/ServerAlias ที่ตรงกับ -d ในทุกๆ enabled port-80 vhost แล้วแต่ไม่พบอะไรเลย sudo apache2ctl -S จะแสดงสิ่งที่ Apache กำหนดเส้นทาง (route) ไว้จริง ให้เพิ่มบรรทัด ServerName ลงใน vhost ที่ถูกต้อง จากนั้น reload และลองใหม่ ปัญหาที่คล้ายกันคือการตรวจสอบ (validation) ส่งไปผิด vhost — challenge response ส่งกลับมาเป็น Invalid response ... 404 เนื่องจากมีอีกเว็บไซต์รับ request ไป วิธีวินิจฉัยและเครื่องมือที่ใช้เหมือนกันคือ: apache2ctl -S
Validation times out.
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let's Encrypt ไม่สามารถเปิด TCP connection ไปยัง port 80 ตามที่ DNS ระบุไว้ สาเหตุที่เป็นไปได้เรียงตามลำดับความถี่: network firewall ของผู้ให้บริการ (ซึ่งแยกจาก ufw และตั้งค่าใน hosting panel), ชุดกฎ ufw ที่อนุญาตเฉพาะ port 443 หรือ SSH เท่านั้น, DNS ยังชี้ไปยังเซิร์ฟเวอร์เครื่องเดิม หรือปัญหา stale-AAAA — เซิร์ฟเวอร์ของ Let's Encrypt พยายามเชื่อมต่อผ่าน IPv6 แต่เซิร์ฟเวอร์ของคุณตอบรับเฉพาะ IPv4 เท่านั้น ให้ทดสอบจาก ภายนอก VPS: การรัน curl -I http://example.com จาก laptop จะแสดงผลลัพธ์แบบเดียวกับที่ validator ของ Let's Encrypt เห็น
You retried your way into a rate limit.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let's Encrypt อนุญาตให้มีการ validation ล้มเหลวได้ 5 ครั้ง ต่อหนึ่ง hostname ต่อหนึ่ง account ต่อชั่วโมง — ตั้งแต่การปรับปรุง rate-limit ในปี 2025 ระบบจะใช้รูปแบบ refilling bucket ซึ่งจะคืนโควตาให้ประมาณหนึ่งครั้งในทุกๆ 12 นาที — การพยายามรันซ้ำอย่างต่อเนื่องในขณะที่ firewall ยังมีปัญหาจะทำให้โควตาหมดลงอย่างรวดเร็ว การรอเป็นวิธีหนึ่ง แต่การแก้ไขที่ถูกต้องคือการเปลี่ยนพฤติกรรม: หลังจากเกิดความล้มเหลว ให้ debug ด้วย staging environment จนกว่าจะสำเร็จ
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comโปรดสังเกต certonly: --dry-run จะถูกยอมรับโดยเฉพาะใน subcommand certonly และ renew เท่านั้น ส่วนการใช้รูปแบบ certbot --apache --dry-run เฉยๆ จะไม่สามารถรันได้และจะแจ้งข้อความ --dry-run currently only works with the 'certonly' or 'renew' subcommands การใช้ dry run จะเป็นการตรวจสอบกับ staging ซึ่งมี limit ที่ผ่อนปรนกว่าและไม่ออกใบรับรองจริง คุณจึงสามารถทดสอบจนล้มเหลวซ้ำๆ ได้ตลอดทั้งบ่าย ให้รันคำสั่งจริงก็ต่อเมื่อ staging ผ่านการทดสอบแล้วเท่านั้น สำหรับ limit อื่นๆ เช่น 50 certificates ต่อหนึ่ง registered domain ต่อสัปดาห์ หรือ 5 duplicates ของชื่อเดิมต่อสัปดาห์ คุณจะพบปัญหานี้ก็ต่อเมื่อมี script ทำการออกใบรับรองซ้ำซ้อนในลักษณะ loop เท่านั้น
เมื่อ HTTPS ใช้งานได้แล้ว โปรดจำไว้ว่าใบรับรองช่วยรักษาความปลอดภัยเฉพาะส่วน transport เท่านั้น ไม่ใช่ตัวเซิร์ฟเวอร์: port 22 ยังคงถูกสแกนเพื่อเดารหัสผ่านอยู่ตลอดเวลา การติดตั้ง Fail2ban on Ubuntu 24.04 ควบคู่กันไปคือขั้นตอนถัดไปที่ควรทำทันที
FAQ
ควรติดตั้ง Certbot ด้วย snap หรือ apt สำหรับ Apache บน Ubuntu 24.04?
ควรใช้ apt เนื่องจาก Ubuntu 24.04 มาพร้อมกับ Certbot 2.9.0 ซึ่งมีความใหม่เพียงพอสำหรับเนื้อหาในคู่มือนี้ ได้รับการอัปเดตความปลอดภัยผ่าน unattended-upgrades และไม่จำเป็นต้องใช้ snapd ให้เลือกใช้ snap เฉพาะเมื่อต้องการเวอร์ชันล่าสุดทันที หรือต้องการ DNS plugin ที่แจกจ่ายผ่าน snap เท่านั้น — และหากต้องการเปลี่ยนมาใช้ snap ให้ลบ apt remove certbot python3-certbot-apache ก่อน เพื่อไม่ให้มีตัวจัดการการต่ออายุ (renewal scheduler) ทำงานซ้ำซ้อนกัน
ทำไม Certbot ถึงแจ้งข้อความ "Unable to find a virtual host listening on port 80"?
สาเหตุเกิดจากไม่มี vhost ที่เปิดใช้งานบน port 80 ที่มี ServerName หรือ ServerAlias ตรงกับโดเมนที่คุณระบุผ่าน -d — โดยปกติ vhost เริ่มต้นของ Ubuntu จะมีการคอมเมนต์ ServerName ไว้ ให้รันคำสั่ง sudo apache2ctl -S เพื่อค้นหา (หรือสร้าง) vhost ที่ใช้ชื่อโดเมนนั้น จากนั้นเพิ่ม ServerName example.com แล้ว reload Apache และรัน Certbot อีกครั้ง
วิธีแก้ไขปัญหา "Timeout during connect (likely firewall problem)" ทำอย่างไร?
Let's Encrypt ไม่สามารถเชื่อมต่อกับ port 80 ตามที่ DNS ระบุไว้ได้ ให้ตรวจสอบ network firewall ในระดับ panel ของผู้ให้บริการ รวมถึง ufw ตรวจสอบว่า dig +short example.com คืนค่าเป็น IP ของ VPS นี้ และลบหรือแก้ไข AAAA record ที่ล้าสมัย เนื่องจากระบบการตรวจสอบจะเลือกใช้ IPv6 หากมีข้อมูลอยู่ ให้ตรวจสอบการแก้ไขจากภายนอกเซิร์ฟเวอร์ด้วย curl -I http://example.com และทดสอบด้วย sudo certbot certonly --apache --dry-run -d example.com ก่อนทำการออกใบรับรองจริง
Certbot จะต่ออายุใบรับรองโดยอัตโนมัติบน Ubuntu 24.04 หรือไม่?
ใช่ แพ็กเกจ apt จะติดตั้ง certbot.timer ซึ่งเป็น systemd timer ที่ทำงานวันละสองครั้ง และจะต่ออายุใบรับรองใดๆ ที่กำลังจะหมดอายุภายใน 30 วัน พร้อมกับ reload Apache หลังจากนั้น ส่วนเวอร์ชัน snap จะใช้ snap.certbot.renew.timer สำหรับงานเดียวกัน ตรวจสอบสถานะด้วย systemctl list-timers certbot.timer และทดสอบด้วย sudo certbot renew --dry-run — ไม่ควรตั้ง cron job ของตนเองเพิ่มเติม
วิธีขอ wildcard certificate ด้วย Certbot และ Apache ทำอย่างไร?
Wildcard จำเป็นต้องใช้ DNS-01 challenge โดย Certbot จะต้องสร้าง TXT record ที่ _acme-challenge.example.com ซึ่งต้องใช้ certbot-dns-* plugin พร้อมกับ API credentials ของผู้ให้บริการ DNS (หากใช้ทางเลือก --manual จะต้องแก้ไข TXT records ด้วยตนเองทุกครั้งที่มีการต่ออายุ) หากคุณมีเพียงไม่กี่ subdomain ที่ทราบค่าแน่นอน การใช้ SAN certificate ที่ระบุชื่อ subdomain ทั้งหมดโดยตรงจะง่ายกว่า และช่วยให้ไม่ต้องเก็บ DNS API keys ไว้บนเซิร์ฟเวอร์