ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

ขอ SSL แบบ Wildcard ด้วย Certbot และ DNS-01 Challenge
Home ขอ SSL แบบ Wildcard ด้วย Certbot และ DNS-01 Challenge

ขอ SSL แบบ Wildcard ด้วย Certbot และ DNS-01 Challenge

ใบรับรองแบบ Wildcard ครอบคลุมทุกซับโดเมนในระดับเดียว เช่น *.example.com ใช้ได้กับ www, api, app และซับโดเมนใหม่ที่จะสร้างในอนาคต โดยไม่ต้องขอใบรับรองใหม่ทุกครั้ง

ข้อแตกต่างสำคัญคือ Let's Encrypt บังคับให้ยืนยันความเป็นเจ้าของผ่าน DNS เท่านั้นสำหรับ Wildcard วิธียืนยันผ่านไฟล์บนเว็บแบบที่ใช้กับโดเมนธรรมดาใช้ไม่ได้ คู่มือนี้ทำทั้งแบบใส่ TXT ด้วยมือและแบบอัตโนมัติ

สิ่งที่ต้องเตรียม

  • โดเมนที่คุณควบคุม DNS ได้
  • เซิร์ฟเวอร์ Linux และสิทธิ์ sudo
  • หากต้องการต่ออายุอัตโนมัติ ต้องมี API Token ของผู้ให้บริการ DNS
# Ubuntu / Debian
sudo apt install -y certbot

# AlmaLinux / Rocky Linux
sudo dnf install -y certbot

ขั้นตอนที่ 1: ทดลองขอแบบใส่ TXT ด้วยมือ

เหมาะสำหรับทดลองครั้งแรกหรือกรณีที่ผู้ให้บริการ DNS ไม่มี API

sudo certbot certonly --manual \
  --preferred-challenges dns \
  -d 'example.com' -d '*.example.com' \
  --agree-tos -m [email protected]

Certbot จะหยุดและแสดงค่าที่ต้องนำไปสร้าง TXT Record

Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
abcdEFGH1234...

อย่ากด Enter ทันที ให้ไปสร้าง TXT Record ที่ผู้ให้บริการ DNS ก่อน แล้วรอจนกว่าจะเผยแพร่จริง ตรวจจากอีก Terminal หนึ่ง

dig +short TXT _acme-challenge.example.com
dig +short TXT _acme-challenge.example.com @8.8.8.8

เมื่อเห็นค่าตรงกับที่ Certbot แจ้งแล้วจึงกด Enter หากกดเร็วเกินไปจะล้มเหลวและต้องเริ่มใหม่ทั้งหมด

ข้อควรรู้ การขอทั้ง example.com และ *.example.com พร้อมกันจะมี TXT สองค่าใต้ชื่อเดียวกัน ต้องใส่ทั้งสองค่า ไม่ใช่แทนที่ค่าเดิม

ขั้นตอนที่ 2: ตั้งค่าแบบอัตโนมัติด้วย Cloudflare

วิธีนี้ทำให้ต่ออายุอัตโนมัติได้ ซึ่งจำเป็นเพราะใบรับรองมีอายุ 90 วัน

sudo apt install -y python3-certbot-dns-cloudflare

สร้าง API Token ที่ Cloudflare โดยให้สิทธิ์เฉพาะ Zone DNS Edit ของโดเมนนั้น อย่าใช้ Global API Key เพราะมีสิทธิ์ทุกอย่างในบัญชี

sudo mkdir -p /root/.secrets
sudo nano /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your-scoped-token-here
sudo chmod 600 /root/.secrets/cloudflare.ini

ขอใบรับรอง

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 30 \
  -d 'example.com' -d '*.example.com' \
  --agree-tos -m [email protected] --non-interactive

ไฟล์ที่ได้จะอยู่ที่ /etc/letsencrypt/live/example.com/

ขั้นตอนที่ 3: ผู้ให้บริการ DNS อื่น

Certbot มีปลั๊กอินสำหรับผู้ให้บริการหลายราย ติดตั้งตัวที่ตรงกับของคุณ

sudo apt install -y python3-certbot-dns-route53      # AWS Route 53
sudo apt install -y python3-certbot-dns-digitalocean # DigitalOcean
sudo apt install -y python3-certbot-dns-google       # Google Cloud DNS
sudo apt install -y python3-certbot-dns-rfc2136      # BIND ที่รองรับ dynamic update

หากผู้ให้บริการของคุณไม่มีปลั๊กอิน ทางออกที่ใช้กันคือมอบหมาย _acme-challenge ไปยัง DNS ที่มี API ด้วย CNAME ครั้งเดียว

_acme-challenge.example.com. CNAME _acme-challenge.example.com.acme-delegated.net.

ขั้นตอนที่ 4: นำใบรับรองไปใช้กับ Nginx

sudo nano /etc/nginx/sites-available/example.com
server {
    listen 443 ssl;
    http2 on;
    server_name example.com *.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;

    root /var/www/example.com;
}
sudo nginx -t && sudo systemctl reload nginx

ขั้นตอนที่ 5: ตั้งต่ออายุอัตโนมัติ

Certbot ติดตั้ง Timer มาให้อยู่แล้ว ตรวจว่าทำงาน

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

คำสั่งที่สองคือการซ้อมต่ออายุจริงโดยไม่กระทบใบรับรองปัจจุบัน ถ้าผ่านแปลว่าตอนถึงเวลาจริงจะสำเร็จ

ตั้งให้โหลด Nginx ใหม่หลังต่ออายุสำเร็จ

sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

สคริปต์ในโฟลเดอร์ deploy จะทำงานเฉพาะเมื่อมีการต่ออายุจริงเท่านั้น ไม่ใช่ทุกครั้งที่ Timer ตรวจสอบ

ขั้นตอนที่ 6: ตรวจสอบผล

sudo certbot certificates
echo | openssl s_client -connect app.example.com:443 -servername app.example.com 2>/dev/null | openssl x509 -noout -dates -subject
curl -sI https://anything.example.com | head -1

ทดสอบกับซับโดเมนที่ยังไม่เคยสร้างมาก่อนเพื่อยืนยันว่า Wildcard ทำงานจริง

ปัญหาที่พบบ่อย

ล้มเหลวพร้อมข้อความ Incorrect TXT record

ค่า TXT ยังไม่เผยแพร่ตอนที่กด Enter หรือมีค่าเก่าค้างอยู่ ลบ TXT เดิมออกให้หมดก่อน แล้วเพิ่มค่าใหม่ ตรวจด้วย dig +short TXT _acme-challenge.example.com @1.1.1.1 จากหลาย Resolver

Wildcard ไม่ครอบคลุมซับโดเมนสองชั้น

*.example.com ครอบคลุม api.example.com แต่ไม่ครอบคลุม v1.api.example.com ต้องขอเพิ่ม *.api.example.com ในใบรับรองเดียวกัน

ถูกจำกัดจำนวนครั้ง (rate limit)

Let's Encrypt จำกัดจำนวนใบรับรองต่อโดเมนต่อสัปดาห์ ระหว่างทดลองให้ใช้เซิร์ฟเวอร์ทดสอบด้วย --dry-run หรือ --test-cert ซึ่งไม่นับโควตา

ต่ออายุอัตโนมัติล้มเหลวเงียบ ๆ

ตรวจ Log ด้วย sudo journalctl -u certbot.timer และ sudo cat /var/log/letsencrypt/letsencrypt.log สาเหตุที่พบบ่อยคือ API Token หมดอายุหรือถูกเพิกถอน ตั้งการแจ้งเตือนวันหมดอายุไว้ด้วยเสมอ

หากต้องการให้ทีมงานช่วยวางระบบใบรับรองให้ทั้งองค์กร ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security