วิธีติดตั้ง Certbot บน Ubuntu 24.04 สำหรับ Apache
ติดตั้ง Let's Encrypt บน Ubuntu 24.04 ด้วย Certbot 2.9.0 ผ่าน apt โดยไม่ต้องใช้ snap พร้อมวิธีแก้ไขปัญหา ServerName ที่มักทำให้การออกใบรับรองล้มเหลวในขั้นตอนแรก
สิ่งที่คุณกำลังสร้าง
เว็บไซต์ Apache บน Ubuntu 24.04 ที่ตอบสนองผ่าน HTTPS ด้วยใบรับรอง Let's Encrypt ที่เชื่อถือได้โดยเบราว์เซอร์ ออกโดย Certbot และต่ออายุโดยอัตโนมัติผ่าน systemd timer ซึ่งคุณไม่จำเป็นต้องกังวลอีกต่อไป คำสั่งที่ใช้ดำเนินการมีเพียงบรรทัดเดียว ทุกสิ่งที่ผิดพลาดมักเกิดขึ้น ก่อน บรรทัดนั้น เช่น vhost ที่ไม่มี ServerName, พอร์ต 80 ที่ถูกปิดไว้ที่ไฟร์วอลล์ของผู้ให้บริการ หรือ DNS ที่ยังชี้ไปยังเซิร์ฟเวอร์เก่า ดังนั้นคู่มือนี้จึงเน้นไปที่เงื่อนไขเบื้องต้นเป็นหลัก และระบุข้อความแสดงข้อผิดพลาดที่ชัดเจนสำหรับแต่ละปัญหา
หมายเหตุเกี่ยวกับขอบเขต: หากเว็บเซิร์ฟเวอร์ของคุณคือ nginx ขั้นตอนจะมีลักษณะเดียวกันแต่ปลั๊กอินและไฟล์คอนฟิกจะแตกต่างกัน ให้ใช้ คู่มือเวอร์ชันสำหรับ nginx แทน และหากสิ่งที่คุณกำลังรักษาความปลอดภัยเป็นบริการภายในเท่านั้น เช่น แผงควบคุมผู้ดูแลระบบบนที่อยู่ส่วนตัว หรือเซิร์ฟเวอร์ทดสอบที่ไม่มีบุคคลภายนอกเข้าถึง คุณไม่จำเป็นต้องใช้หน่วยงานออกใบรับรอง (Certificate Authority) เลย การใช้ ใบรับรองที่ลงนามด้วยตนเอง (self-signed certificate) จะลดความซับซ้อนของระบบและสามารถใช้งานแบบออฟไลน์ได้
ข้อกำหนดเบื้องต้นและสาเหตุ 3 ประการที่ทำให้การทำงานล้มเหลวก่อนที่ Certbot จะเริ่มทำงาน
- Apache ให้บริการเว็บไซต์ผ่าน HTTP ปกติอยู่แล้ว ปลั๊กอิน Apache ของ Certbot จะแก้ไขเว็บไซต์ที่มีอยู่เดิมเท่านั้น ไม่ได้สร้างเว็บไซต์ขึ้นมาใหม่ หากคุณเริ่มต้นจาก VPS เปล่า ให้ติดตั้ง LAMP stack บน Ubuntu 24.04 ให้เรียบร้อยก่อนแล้วค่อยกลับมา คู่มือนี้คือบท TLS ที่ขาดหายไปของขั้นตอนดังกล่าว
- โดเมนสาธารณะที่มี A record ชี้ไปยังที่อยู่ VPS ของคุณ การตรวจสอบแบบ HTTP-01 ของ Let’s Encrypt หมายความว่าเซิร์ฟเวอร์ตรวจสอบของพวกเขาจะเชื่อมต่อเข้ามายังเครื่องของคุณจากอินเทอร์เน็ต ดังนั้นจึงไม่รองรับ homelab ที่อยู่หลัง NAT โดยไม่มีการทำ port forward, ไม่รองรับชื่อ
.localและไม่รองรับการใช้ IP โดยตรงdig +short example.comจะต้องส่งค่ากลับเป็นที่อยู่ VPS ของคุณ และหากคุณเพิ่งเปลี่ยนค่า DNS ในช่วงหนึ่งชั่วโมงที่ผ่านมา ให้รอจนกว่า TTL ของ record เดิมจะหมดอายุก่อนเริ่มออกใบรับรอง - หากมี AAAA record อยู่ จะต้องถูกต้อง Let’s Encrypt จะให้ความสำคัญกับ IPv6 หากมีการประกาศ AAAA record ไว้ ดังนั้น AAAA record ที่ล้าสมัยจะทำให้การตรวจสอบล้มเหลว แม้ว่าการ
curlจากแล็ปท็อปของคุณ (ซึ่งมักใช้ IPv4) จะทำงานได้ตามปกติก็ตาม ให้ประกาศค่า AAAA ที่ถูกต้องหรือลบออกไปเลย
พอร์ต 80 และ 443 จะต้องเปิดใช้งานใน ufw และ ในไฟร์วอลล์เครือข่ายของผู้ให้บริการของคุณ โดยโฮสติ้งส่วนใหญ่จะมีไฟร์วอลล์ชั้นที่สองที่ระบบปฏิบัติการมองไม่เห็น การตรวจสอบแบบ HTTP-01 จะใช้พอร์ต 80 โดยเฉพาะ คุณไม่สามารถรันขั้นตอนนี้โดยใช้เพียงพอร์ต 443 ได้
sudo ufw allow "Apache Full"
sudo ufw statusหากเตรียมการทั้งหมดนี้แล้ว งานทั้งหมดจะใช้เวลาเพียง 15 นาที โดย 10 นาทีนั้นคือเวลาสำหรับการอ่านทำความเข้าใจ
จะใช้ Certbot ผ่าน Snap หรือ apt ดี? บน 24.04 การใช้ apt ถือว่าใช้งานได้ดีแล้ว
Certbot ย้ายไปใช้การแจกจ่ายผ่าน snap เมื่อหลายปีก่อนด้วยเหตุผลที่สมเหตุสมผล นั่นคือแพ็กเกจของ distro มักจะล้าสมัย Ubuntu 20.04 มาพร้อมกับ Certbot 0.40 และไม่มีการอัปเดตเวอร์ชันอีกเลย ทำให้ทีมพัฒนาต้องคอยแก้ไขบั๊กที่มีอายุถึง 5 ปี แต่บน 24.04 เหตุผลดังกล่าวหมดไปแล้ว เนื่องจากคลังซอฟต์แวร์มี Certbot 2.9.0 ซึ่งเป็นเวอร์ชันปัจจุบัน และ unattended-upgrades คอยดูแลเรื่องการแพตช์ให้ คำแนะนำของผมสำหรับ OS นี้คือ: ให้ใช้ apt คุณจะสามารถเลี่ยงการใช้ snapd daemon ได้, ปลั๊กอินสำหรับ Apache จะถูกติดตั้งไปพร้อมกันในการทำรายการเดียว และตัวตั้งเวลาต่ออายุ (renewal timer) จะทำงานร่วมกับ systemd ตามมาตรฐานของ Debian
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionผลลัพธ์ที่ถูกต้องคือ: certbot 2.9.0 แพ็กเกจ python3-certbot-apache คือปลั๊กอินที่ทำหน้าที่อ่านและแก้ไขไฟล์ config ของ Apache หากไม่มีปลั๊กอินนี้ certbot --apache จะล้มเหลวพร้อมข้อความ The requested apache plugin does not appear to be installed
การใช้ snap ยังคงเป็นทางเลือกที่เหมาะสมใน 2 กรณี คือเมื่อคุณต้องการใช้ Certbot เวอร์ชันใหม่ล่าสุดทันทีที่ปล่อยออกมา หรือเมื่อคุณจำเป็นต้องใช้ DNS plugin ที่มีแจกจ่ายเฉพาะในรูปแบบ snap เท่านั้น (ปลั๊กอินของผู้ให้บริการ certbot-dns-* หลายตัวเป็นเช่นนั้น) หากคุณเลือกทางนั้น:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotไม่ว่าคุณจะเลือกวิธีใด ห้ามติดตั้งทั้งสองแบบพร้อมกัน การติดตั้งสองชุดหมายถึงตัวกำหนดเวลาต่ออายุสองตัวจะแย่งกันทำงานกับ /etc/letsencrypt และ certbot ที่ shell ของคุณพบใน PATH อาจไม่ใช่ตัวที่จัดการ certificate ของคุณอยู่ บรรทัด apt remove ด้านบนไม่ใช่สิ่งที่ใส่ไว้เพื่อความสวยงาม แต่เป็นสิ่งที่จำเป็นต้องทำ
vhost ที่ Certbot จะแก้ไขต้องมีอยู่จริง และ ServerName คือหัวใจสำคัญ
certbot --apache ทำงานโดยการค้นหา virtual host บนพอร์ต 80 ที่มี ServerName หรือ ServerAlias ตรงกับ -d โดเมนที่คุณระบุ เพื่อพิสูจน์สิทธิ์การควบคุมโดเมนผ่าน vhost นั้น จากนั้นจึงสร้าง vhost เวอร์ชัน SSL ขึ้นมาคู่กัน หากไม่มี ServerName ที่ตรงกัน ก็จะไม่พบ vhost เป้าหมาย และไฟล์ 000-default.conf เริ่มต้นของ Ubuntu ก็มักจะใส่เครื่องหมายคอมเมนต์ไว้ที่ ServerName บรรทัดที่ถูกคอมเมนต์ไว้นั้นคือสาเหตุที่พบบ่อยที่สุดที่ทำให้คำสั่งหลักในคู่มือนี้ทำงานล้มเหลว
ดังนั้น ก่อนจะเริ่มใช้งาน Certbot ให้กำหนดชื่อ vhost ให้ถูกต้องเสียก่อน โดยสร้างไฟล์ /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>เปิดใช้งาน vhost ดังกล่าวและตรวจสอบว่า Apache สามารถอ่านค่าและกำหนดเส้นทางไปยังชื่อโดเมนนั้นได้จริง:
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 ด้วย นั่นเป็นเพียงคำเตือนเกี่ยวกับ echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2 ในระดับ global ซึ่งไม่มีผลกระทบใดๆ ในที่นี้
ผลลัพธ์จาก -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 ไม่ปรากฏขึ้นมาคู่กับพอร์ต 80 Certbot ก็จะไม่สามารถค้นพบ vhost นั้นได้เช่นกัน
ออกใบรับรอง: 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 โดยอัตโนมัติซึ่งเป็นค่าเริ่มต้นที่เหมาะสมอยู่แล้ว ให้ใช้แฟล็ก --no-redirect หากคุณจำเป็นต้องให้บริการเนื้อหาผ่าน HTTP ธรรมดาจริงๆ
เมื่อสำเร็จจะแสดงข้อความดังนี้ ซึ่งคุณควรอ่านให้ละเอียดแทนการกวาดสายตาผ่าน:
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 อย่าง: เปิดใช้งานโมดูล ssl ของ Apache หากยังไม่ได้เปิด, เขียนไฟล์ example.com-le-ssl.conf ซึ่งเป็นสำเนาของ vhost ของคุณที่ *:443 พร้อมด้วย SSLEngine on และพาธของใบรับรอง, เปิดใช้งานไฟล์ดังกล่าว และเพิ่มบล็อก RewriteRule เข้าไปใน vhost พอร์ต 80 เดิมเพื่อทำ 301 redirect ทุกคำขอไปยัง HTTPS ไฟล์ vhost เดิมของคุณจะถูกแก้ไข ไม่ใช่ถูกแทนที่ และไฟล์ SSL คู่ขนานจะถูกสร้างขึ้นข้างๆ กัน ซึ่งคุณสามารถตรวจสอบทุกบรรทัดที่ถูกเพิ่มเข้าไปได้
ตำแหน่งที่จัดเก็บใบรับรองจริง และเหตุผลที่คุณไม่ควรคัดลอกไฟล์เหล่านั้น
ไฟล์ทั้งหมดจะถูกจัดเก็บไว้ภายใต้ /etc/letsencrypt/live/example.com/ ได้แก่ fullchain.pem (ใบรับรองรวมถึง intermediate chain ซึ่งเป็นสิ่งที่เซิร์ฟเวอร์ควรชี้ไปหา), privkey.pem (private key ซึ่งควรเข้าถึงได้โดย root เท่านั้น) รวมถึง cert.pem และ chain.pem สำหรับซอฟต์แวร์ที่ต้องการไฟล์แยกส่วนกัน ไฟล์เหล่านี้เป็น symlink ที่ชี้ไปยัง /etc/letsencrypt/archive/ ซึ่งการอ้างอิงผ่านทางอ้อมนี้คือกลไกการต่ออายุใบรับรอง โดยกระบวนการต่ออายุจะเขียนไฟล์ชุดใหม่ลงใน archive/ แล้วปรับ symlink ให้ชี้ไปยังไฟล์ชุดใหม่นั้น หากคุณกำหนดค่าซอฟต์แวร์อื่นให้ชี้ไปยังเส้นทาง live/ ซอฟต์แวร์เหล่านั้นจะได้รับใบรับรองที่ต่ออายุโดยอัตโนมัติ แต่หากคุณคัดลอกไฟล์ไปไว้ที่อื่น คุณจะประสบปัญหาบริการหยุดทำงานเมื่อครบกำหนด 90 วัน
ไฟล์อื่นที่ควรทราบคือ /etc/letsencrypt/renewal/example.com.conf ซึ่งบันทึกวิธีการออกใบรับรองนี้ รวมถึง authenticator = apache, installer = apache และชื่อโดเมน เพื่อให้กระบวนการต่ออายุสามารถทำซ้ำได้โดยไม่ต้องมีผู้ดูแล รวมถึงการสั่ง reload Apache หลังจากเสร็จสิ้นกระบวนการ
การต่ออายุถูกกำหนดไว้แล้ว ให้ตรวจสอบสถานะ ไม่ต้องสร้างใหม่
ใบรับรอง Let’s Encrypt มีอายุการใช้งาน 90 วันตามการออกแบบ และแพ็กเกจ apt ได้ติดตั้งกลไกการทำงานไว้เรียบร้อยแล้ว นั่นคือ systemd timer ที่จะรัน Certbot วันละ 2 ครั้งในเวลาที่สุ่มขึ้นมา เพื่อต่ออายุใบรับรองใดก็ตามที่เหลืออายุการใช้งานน้อยกว่า 30 วัน อย่าเพิ่ม cron job ซ้อนเข้าไป เพราะตัวจัดตารางเวลาตัวที่สองไม่ได้ช่วยอะไรนอกจากทำให้เกิด log ที่ไม่จำเป็นและเสี่ยงต่อการติด 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 ของ Let’s Encrypt ซึ่งเป็นการทดสอบ challenge จริง แต่จะไม่มีการออกใบรับรองและไม่เสียโควตา rate-limit ผลลัพธ์ที่ถูกต้องจะลงท้ายด้วย:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)หากการทำ dry run ล้มเหลว การต่ออายุจริงในอีกประมาณ 60 วันข้างหน้าก็จะล้มเหลวในลักษณะเดียวกัน ให้แก้ไขปัญหาทันทีในขณะที่ใบรับรองปัจจุบันยังมีอายุการใช้งานเหลืออยู่ สาเหตุที่พบบ่อยคือการเพิ่มกฎ firewall หลังจากออกใบรับรองไปแล้ว ซึ่งไปปิดพอร์ต 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 พร้อมส่วนหัว Location: https://example.com/ ซึ่งเป็นการเปลี่ยนเส้นทาง (redirect) ที่ Certbot ติดตั้งไว้ คำสั่งที่สองควรส่งค่ากลับเป็น HTTP/1.1 200 OK โดยไม่มีการแจ้งเตือนปัญหา TLS จาก curl คำสั่งที่สามจะแสดงผู้ออกใบรับรอง (issuer) ซึ่งเป็นบรรทัด O = Let's Encrypt ที่มีค่า CN สั้นๆ เช่น R12 หรือ E7 และมีค่า notAfter ที่มีอายุเหลือประมาณ 90 วัน ในเบราว์เซอร์คุณจะเห็นไอคอนรูปแม่กุญแจ และเมื่อคลิกดูจะพบผู้ออกใบรับรองเดียวกัน หาก curl ทำงานได้ปกติแต่เบราว์เซอร์แจ้งเตือน แสดงว่าคุณกำลังดูหน้าเว็บที่ถูกแคชไว้หรือใช้ชื่อโฮสต์ผิด ไม่ใช่ปัญหาที่ตัวใบรับรองเอง
หลายเว็บไซต์: ใบรับรอง SAN ใบเดียว หรือใบรับรองแยกต่อเว็บไซต์
ทั้งสองวิธีใช้งานได้และมีวิธีการต่ออายุเหมือนกัน สำหรับเว็บไซต์ที่ไม่เกี่ยวข้องกันบนเซิร์ฟเวอร์เดียวกัน ให้รันคำสั่งออกใบรับรองแยกกันต่อเว็บไซต์ แต่ละเว็บไซต์จะมีไดเรกทอรีของตนเองภายใต้ live/ และมีไฟล์กำหนดค่าการต่ออายุแยกกัน ทำให้ปัญหาของโดเมนหนึ่งไม่ส่งผลกระทบต่อการต่ออายุของโดเมนอื่น นี่เป็นวิธีที่ผมใช้เป็นค่าเริ่มต้น
สำหรับเว็บไซต์เดียวที่มีหลายชื่อ ให้รวมไว้ในใบรับรอง SAN ใบเดียว โดยใบรับรองหนึ่งใบสามารถรองรับชื่อได้สูงสุด 100 ชื่อ ซึ่งคุณได้ดำเนินการไปแล้วข้างต้นด้วย example.com และ www.example.com หากต้องการเพิ่มชื่อลงในใบรับรองที่มีอยู่ภายหลัง ให้ทำการออกใบรับรองใหม่โดยระบุชื่อใบรับรองและรายการชื่อใหม่ทั้งหมด:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comCertbot จะตรวจพบชุดโดเมนที่เปลี่ยนแปลงไป และขอให้คุณยืนยันการขยายใบรับรอง จากนั้นจะแทนที่ใบรับรองเดิมในตำแหน่งเดิมที่ live/ ทำให้ไม่ต้องแก้ไขส่วนอื่นเพิ่มเติม โปรดทราบว่ารายการที่ระบุคือการแทนที่รายการเดิม ไม่ใช่การเพิ่มต่อท้าย: หากคุณละ www ออกจากคำสั่งดังกล่าว ใบรับรองใหม่จะตัดชื่อนั้นออกโดยไม่มีการแจ้งเตือน
Wildcard ต้องใช้ DNS-01 และโดยปกติแล้วคุณไม่จำเป็นต้องใช้ Wildcard
HTTP-01 ไม่สามารถออก *.example.com ได้ การวางไฟล์บนเว็บเซิร์ฟเวอร์เป็นการพิสูจน์การควบคุมเพียงหนึ่ง hostname ไม่ใช่ทั้ง namespace การใช้ Wildcard จำเป็นต้องผ่านการตรวจสอบแบบ DNS-01: Certbot จะตั้งค่า TXT record ที่ _acme-challenge.example.com ซึ่งในทางปฏิบัติหมายถึงการใช้ปลั๊กอิน certbot-dns-* ร่วมกับ API credentials ของผู้ให้บริการ DNS ของคุณ หรือการแก้ไข TXT record ด้วยตนเองทุกครั้งที่มีการต่ออายุผ่าน --manual (ซึ่งเป็นวิธีที่ลำบากและไม่ควรนำมาวางแผนใช้งาน) คำแนะนำโดยละเอียดตั้งแต่กลไกของ TXT record ไปจนถึงการใช้ปลั๊กอินเพื่อต่ออายุโดยอัตโนมัติอยู่ใน ใบรับรอง Wildcard ด้วย Certbot ผ่าน DNS-01 คำแนะนำจากประสบการณ์จริงคือ หากคุณมี subdomain ที่ระบุได้ชัดเจน 4 รายการ การใช้ SAN certificate ที่ระบุชื่อทั้ง 4 รายการนั้นจะจัดการได้ง่ายกว่าการใช้ Wildcard และไม่จำเป็นต้องเก็บ DNS API keys ไว้บนเซิร์ฟเวอร์
รูปแบบความล้มเหลวและข้อความที่คุณจะพบ
Certbot ไม่ยอมเริ่มทำงานเนื่องจากไฟล์คอนฟิกของ Apache มีข้อผิดพลาด
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')ปลั๊กอินจะรัน configtest ก่อนดำเนินการใดๆ และจะหยุดทำงานทันทีหาก Apache มีปัญหา ข้อความ \n ที่ปรากฏเป็นข้อความตามตัวอักษรเนื่องจาก Certbot แสดงผลลัพธ์จาก exception โดยตรง ให้คุณรัน sudo apache2ctl configtest ด้วยตัวเอง คำสั่งนี้จะระบุชื่อไฟล์และบรรทัดที่มีปัญหา ซึ่งมักเกิดจากการพิมพ์ผิดขณะแก้ไขไฟล์ด้วยมือ, SSLCertificateFile ที่ชี้ไปยังพาธที่ไม่มีอยู่จริง หรือการอ้างอิงโมดูลที่ยังไม่ได้เปิดใช้งาน ให้แก้ไขจนกว่าคำสั่งจะแสดงผล Syntax OK แล้วจึงรัน Certbot อีกครั้ง
ไม่มี vhost ใดตรงกับโดเมน
Unable to find a virtual host listening on port 80 which is currently the only challenge port.นี่คือความล้มเหลวจากกรณีที่ไม่มี ServerName ตามที่กล่าวไปก่อนหน้านี้ ซึ่งจะถูกตรวจพบในขั้นตอนการออกใบรับรอง Certbot จะค้นหา vhost พอร์ต 80 ทุกตัวที่เปิดใช้งานอยู่เพื่อหา ServerName/ServerAlias ที่ตรงกับ -d ของคุณแต่ไม่พบ sudo apache2ctl -S จะแสดงให้เห็นว่า Apache กำลังส่งคำขอไปที่ใดจริง ให้เพิ่มบรรทัด ServerName ลงใน vhost ที่ถูกต้อง โหลดคอนฟิกใหม่ แล้วลองอีกครั้ง ปัญหาที่คล้ายกันคือการตรวจสอบไปถึง vhost ที่ ผิด ทำให้การตอบสนองต่อ challenge กลายเป็น Invalid response ... 404 เนื่องจากเว็บไซต์อื่นรับคำขอไปแทน ให้ใช้วิธีวินิจฉัยและเครื่องมือเดียวกันคือ apache2ctl -S
การตรวจสอบหมดเวลา (Validation times out)
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let's Encrypt ไม่สามารถเปิดการเชื่อมต่อ TCP ไปยังพอร์ต 80 ที่หมายเลข IP ซึ่ง DNS ของคุณประกาศไว้ได้ โดยเรียงลำดับความเป็นไปได้ดังนี้: ไฟร์วอลล์เครือข่ายของผู้ให้บริการ (แยกจาก ufw ซึ่งตั้งค่าผ่านแผงควบคุมโฮสติ้ง), กฎของ ufw ที่อนุญาตเฉพาะพอร์ต 443 หรือ SSH เท่านั้น, DNS ยังชี้ไปยังเซิร์ฟเวอร์เก่า หรือปัญหา IPv6 ค้าง (stale-AAAA) ที่เซิร์ฟเวอร์ของเขาพยายามเชื่อมต่อผ่าน IPv6 แต่เซิร์ฟเวอร์ของคุณตอบสนองเฉพาะ IPv4 ให้ทดสอบจาก ภายนอก VPS: การใช้ curl -I http://example.com จากแล็ปท็อปของคุณจะจำลองสิ่งที่ตัวตรวจสอบของเขาเห็น
คุณลองซ้ำจนติดข้อจำกัดอัตราการใช้งาน (Rate limit)
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let's Encrypt อนุญาตให้ตรวจสอบล้มเหลวได้ 5 ครั้งต่อชื่อโฮสต์ ต่อบัญชี ต่อชั่วโมง นับตั้งแต่การปรับปรุง rate-limit ในปี 2025 ระบบจะใช้รูปแบบถังเก็บที่ค่อยๆ เติมกลับมา โดยจะได้สิทธิ์ลองใหม่คืนมาประมาณ 1 ครั้งทุกๆ 12 นาที การกดลองซ้ำๆ ในขณะที่ไฟร์วอลล์ยังมีปัญหาจะทำให้สิทธิ์หมดลงอย่างรวดเร็ว การรอช่วยได้ แต่การแก้ไขที่แท้จริงคือการปรับเปลี่ยนพฤติกรรม: หลังจากเกิดความล้มเหลว ให้ดีบั๊กด้วยสภาพแวดล้อม staging จนกว่าจะผ่าน
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comโปรดสังเกต certonly: --dry-run จะยอมรับเฉพาะคำสั่งย่อย certonly และ renew เท่านั้น ส่วนคำสั่ง certbot --apache --dry-run แบบปกติจะไม่ยอมทำงานและแจ้งเตือนคุณว่า --dry-run currently only works with the 'certonly' or 'renew' subcommands การทำ dry run จะตรวจสอบกับสภาพแวดล้อม staging ซึ่งมีข้อจำกัดที่ยืดหยุ่นกว่าและไม่ออกใบรับรองจริง คุณจึงสามารถทดสอบจนกว่าจะสำเร็จได้ตลอดทั้งวัน ให้รันคำสั่งจริงอีกครั้งก็ต่อเมื่อผ่านการทดสอบใน staging แล้วเท่านั้น สำหรับข้อจำกัดอื่นๆ เช่น 50 ใบรับรองต่อโดเมนที่ลงทะเบียนต่อสัปดาห์ หรือ 5 ใบรับรองที่ซ้ำกันต่อสัปดาห์ คุณจะพบปัญหานี้ก็ต่อเมื่อมีสคริปต์ที่พยายามออกใบรับรองซ้ำในลูปเท่านั้น
เมื่อ HTTPS ใช้งานได้แล้ว โปรดจำไว้ว่าใบรับรองช่วยรักษาความปลอดภัยให้กับการ รับส่งข้อมูล ไม่ใช่ตัวเซิร์ฟเวอร์: พอร์ต 22 ยังคงถูกสุ่มเดารหัสผ่านอยู่ตลอดเวลา การจับคู่สิ่งนี้เข้ากับ Fail2ban บน Ubuntu 24.04 คือขั้นตอนถัดไปที่ควรทำภายใน 30 นาทีหลังจากนี้
FAQ
ฉันควรติดตั้ง Certbot ด้วย snap หรือ apt สำหรับ Apache บน Ubuntu 24.04?
ให้ใช้ apt เนื่องจาก Ubuntu 24.04 มาพร้อมกับ Certbot 2.9.0 ซึ่งทันสมัยเพียงพอสำหรับทุกขั้นตอนในคู่มือนี้ ได้รับแพตช์ความปลอดภัยผ่าน unattended-upgrades และไม่จำเป็นต้องใช้ snapd ให้เลือกใช้ snap เฉพาะในกรณีที่คุณต้องการ release ล่าสุดทันที หรือต้องการ DNS plugin ที่แจกจ่ายผ่าน snap เท่านั้น และหากคุณเปลี่ยนไปใช้ snap ให้ apt remove certbot python3-certbot-apache ก่อน เพื่อป้องกันไม่ให้ตัวกำหนดเวลาการต่ออายุ (renewal scheduler) ทำงานซ้อนทับกัน
ทำไม Certbot ถึงแจ้งว่า "Unable to find a virtual host listening on port 80"?
เนื่องจากไม่มี vhost ที่เปิดใช้งานอยู่บนพอร์ต 80 ที่มี ServerName หรือ ServerAlias ตรงกับโดเมนที่คุณระบุด้วย -d โดยค่าเริ่มต้น vhost ของ Ubuntu จะคอมเมนต์ ServerName ไว้ ให้รัน sudo apache2ctl -S ค้นหา (หรือสร้าง) vhost ที่ควรจะเป็นเจ้าของชื่อโดเมนนั้น เพิ่ม ServerName example.com เข้าไป โหลด Apache ใหม่ แล้วรัน Certbot อีกครั้ง
ฉันจะแก้ไขข้อผิดพลาด "Timeout during connect (likely firewall problem)" ได้อย่างไร?
Let's Encrypt ไม่สามารถเข้าถึงพอร์ต 80 ที่ที่อยู่ซึ่ง DNS ของคุณประกาศไว้ได้ ให้ตรวจสอบ firewall ระดับเครือข่ายในแผงควบคุมของผู้ให้บริการของคุณรวมถึง ufw ยืนยันว่า dig +short example.com ส่งค่ากลับมาเป็น 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 วัน และโหลด Apache ใหม่หลังจากนั้น ส่วน snap จะใช้ snap.certbot.renew.timer สำหรับงานเดียวกัน ให้ตรวจสอบด้วย systemctl list-timers certbot.timer และทดสอบด้วย sudo certbot renew --dry-run ห้ามเพิ่ม cron job ของคุณเองซ้อนทับลงไป
ฉันจะขอใบรับรองแบบ wildcard ด้วย Certbot และ Apache ได้อย่างไร?
ใบรับรองแบบ wildcard ต้องใช้การตรวจสอบแบบ DNS-01: Certbot ต้องวาง TXT record ไว้ที่ _acme-challenge.example.com ซึ่งหมายความว่าต้องใช้ปลั๊กอิน certbot-dns-* พร้อมข้อมูลรับรอง API สำหรับผู้ให้บริการ DNS ของคุณ (ทางเลือกแบบ --manual จำเป็นต้องแก้ไข TXT record ด้วยตนเองทุกครั้งที่มีการต่ออายุ) หากคุณมีโดเมนย่อยเพียงไม่กี่ชื่อ การใช้ใบรับรองแบบ SAN ที่ระบุชื่อโดเมนเหล่านั้นไว้อย่างชัดเจนจะง่ายกว่าและช่วยให้ไม่ต้องเก็บ API key ของ DNS ไว้บนเซิร์ฟเวอร์