ออก Let's Encrypt Wildcard SSL ด้วย Certbot DNS Challenge

Wildcard SSL ออกให้ *.example.com ครอบคลุม subdomain ทุกตัว (blog.example.com, shop.example.com) ในใบเดียว — แต่ Let's Encrypt ออก Wildcard ผ่าน HTTP Challenge ไม่ได้ ต้องใช้ DNS-01 Challenge เท่านั้น

บทความนี้พาออก Let's Encrypt Wildcard SSL ฟรีด้วย Certbot + DNS Challenge แบบ Manual และ Automatic (ใช้ Cloudflare DNS API) บน VPS Ubuntu พร้อม Renew อัตโนมัติทุก 60 วัน

ต้องเตรียม: โดเมนที่คุณ control DNS ได้ (ไม่จำเป็นต้องอยู่บน server เดียวกัน), VPS Ubuntu, sudo access — ถ้าใช้ Cloudflare ต้องสร้าง API Token (Zone:DNS Edit)

HTTP-01 vs DNS-01 Challenge ต่างกันอย่างไร

หัวข้อHTTP-01DNS-01
วิธียืนยันวางไฟล์ใน .well-known/acme-challenge/เพิ่ม TXT record ใน DNS
Wildcard❌ ไม่รองรับ✅ รองรับ
ต้องการ Web Serverต้องเปิด Port 80ไม่จำเป็น
Auto Renewง่าย — Certbot ทำเองต้องใช้ DNS API
เหมาะกับSSL ใบเดียว 1 โดเมนWildcard, internal services

เข้าใจกลไก Let's Encrypt และ ACME Protocol

Let's Encrypt ใช้ ACME (Automatic Certificate Management Environment) Protocol ซึ่งเป็นมาตรฐานเปิด (RFC 8555) ในการพิสูจน์ว่าผู้ขอใบเซอร์เป็นเจ้าของโดเมนจริง กระบวนการโดยย่อมีดังนี้:

  1. Certbot สร้าง Key Pair สำหรับ Account และ Domain
  2. Certbot ส่ง Certificate Signing Request (CSR) ไปยัง ACME Server ของ Let's Encrypt
  3. ACME Server ส่ง Challenge กลับมา — ในกรณี DNS-01 คือค่า Token สำหรับสร้าง TXT Record
  4. Certbot (หรือ Cloudflare Plugin) เพิ่ม TXT Record ชื่อ _acme-challenge.yourdomain.com ด้วยค่านั้น
  5. ACME Server ตรวจสอบ TXT Record ผ่าน DNS — ถ้าผ่านจะออกใบเซอร์ให้
  6. Certbot ดาวน์โหลดใบเซอร์มาเก็บใน /etc/letsencrypt/live/

ทั้งหมดนี้ใช้เวลาไม่เกิน 2-3 นาทีหากตั้งค่าถูกต้อง DNS propagation เป็นปัจจัยหลักที่ทำให้ช้า ซึ่ง --dns-cloudflare-propagation-seconds 30 เป็น buffer ที่เพียงพอสำหรับ Cloudflare ซึ่งมีการ propagate เร็วมาก

ใบเซอร์ที่ได้จะประกอบด้วยไฟล์สำคัญ 4 ไฟล์ใน /etc/letsencrypt/live/example.com/:

สำหรับ Nginx ทั่วไปใช้แค่ fullchain.pem และ privkey.pem ก็เพียงพอ

ทำไม Wildcard SSL จึงเหมาะกับ VPS ที่มีหลาย Subdomain

ถ้าเว็บไซต์ของคุณมีหลาย Subdomain เช่น shop.example.com, blog.example.com, api.example.com, admin.example.com การออก SSL แยกทีละใบใช้เวลาและเพิ่มงาน Renew หลายรอบ Wildcard SSL แก้ปัญหานี้ด้วยใบเดียวที่ครอบคุมทุกตัว ข้อได้เปรียบหลักของ Wildcard บน VPS:

ข้อจำกัดที่ต้องรู้คือ Wildcard ครอบเฉพาะ Level เดียว — *.example.com ครอบ a.example.com แต่ไม่ครอบ b.a.example.com ถ้าต้องการ Sub-subdomain ต้องออกใบ Wildcard แยกหรือใช้ Multi-SAN

วิธีที่ 1 — Manual DNS Challenge (ครั้งเดียว)

เหมาะถ้าทำครั้งเดียวและ DNS ไม่มี API — แต่ ต้องวาง TXT record เองทุก 90 วัน ตอนจะ renew

ขั้นที่ 1.1 — ติดตั้ง Certbot

sudo apt update
sudo apt install -y certbot

ขั้นที่ 1.2 — ขอใบ Wildcard ด้วย Manual Mode

sudo certbot certonly --manual --preferred-challenges=dns \
  --email [email protected] --agree-tos --no-eff-email \
  -d example.com -d "*.example.com"

Certbot จะแสดง TXT record ที่ต้องเพิ่มในระบบ DNS ของโดเมน ตัวอย่างผลลัพธ์ที่จะเห็นบนหน้าจอ:

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

with the following value:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

เปิด DNS panel (Cloudflare / Route 53 / DirectAdmin DNS) แล้วเพิ่ม TXT record ตามที่ Certbot แจ้ง ชื่อ record คือ _acme-challenge.example.com ประเภท TXT ค่าคือ Token ที่โปรแกรมแสดง จากนั้น รอ 1-2 นาที ให้ DNS propagate แล้วกด Enter — Certbot จะตรวจและออกใบให้

ใบ Cert จะอยู่ที่ /etc/letsencrypt/live/example.com/ ครอบคลุมทั้ง root domain และทุก subdomain ในรูปแบบ Wildcard พร้อมใช้งานทันที

วิธีที่ 2 — Automatic ด้วย Cloudflare DNS Plugin

ถ้าโดเมนใช้ Cloudflare DNS — ทำให้ Certbot ขอ + renew อัตโนมัติได้

ขั้นที่ 2.1 — ติดตั้ง Cloudflare Plugin

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

ขั้นที่ 2.2 — สร้าง API Token บน Cloudflare

ไปที่ My Profile → API Tokens → Create Token → Edit zone DNS เลือก zone ที่ต้องการ บันทึก token ไว้

ขั้นที่ 2.3 — เก็บ Token ในไฟล์ (สำคัญ: ตั้ง permission 600)

sudo mkdir -p /etc/letsencrypt/cloudflare
sudo nano /etc/letsencrypt/cloudflare/credentials.ini

ใส่เนื้อหา:

dns_cloudflare_api_token = YOUR_CLOUDFLARE_TOKEN_HERE
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

⚠️ ต้องตั้ง permission 600 เพราะถ้า user อื่นอ่านได้ Certbot จะปฏิเสธไม่ใช้ token ด้วยเหตุผลความปลอดภัย

ขั้นที่ 2.4 — ขอใบ Wildcard

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --dns-cloudflare-propagation-seconds 30 \
  --email [email protected] --agree-tos --no-eff-email \
  -d example.com -d "*.example.com"

Certbot จะคุยกับ Cloudflare API เพิ่ม TXT record ให้, ตรวจ, แล้วลบทิ้งให้อัตโนมัติ ใบ Cert จะอยู่ที่ /etc/letsencrypt/live/example.com/

ความปลอดภัยของ Private Key และการสำรองข้อมูล

Private Key ที่อยู่ใน /etc/letsencrypt/live/example.com/privkey.pem คือสิ่งสำคัญที่สุดของระบบ SSL ถ้า Private Key หลุดไปในมือผู้ไม่หวังดี ทุกการสื่อสาร HTTPS ของโดเมนนั้นสามารถถูก Decrypt ได้ทันที ต้องปฏิบัติตามแนวทางเหล่านี้เสมอ:

นอกจากนี้ควร Monitor อายุใบเซอร์ด้วยเครื่องมือ Monitoring เช่น Uptime Kuma หรือ AsiaGB VPS ที่มี SSL alert ให้ในตัว เพื่อรับแจ้งเตือนล่วงหน้าก่อนใบจะหมดอายุ แม้ว่า Auto-Renew จะทำงานได้ แต่การ Monitor ซ้ำไว้ไม่เป็นผลเสีย

ขั้นที่ 3 — ใช้ใบ Cert กับ Nginx

เพิ่มในไฟล์ Nginx config:

server {
    listen 443 ssl http2;
    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;
    index index.html;
}

ทดสอบ config และ reload:

sudo nginx -t
sudo systemctl reload nginx

ขั้นที่ 4 — Auto-Renew ทุก 60 วัน

Certbot ติดตั้ง systemd timer มาให้แล้ว ตรวจสอบ:

sudo systemctl list-timers | grep certbot

ทดสอบ renew แบบ dry-run (ไม่ขอใบจริง):

sudo certbot renew --dry-run

ถ้าใช้ Nginx ให้ Certbot reload อัตโนมัติหลัง renew:

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

เปรียบเทียบ Let's Encrypt Wildcard กับ Wildcard SSL ที่ซื้อ

หลายคนยังลังเลว่าควรใช้ Let's Encrypt ฟรีหรือซื้อ Wildcard SSL จาก CA ที่มีชื่อเสียง เช่น RapidSSL หรือ GeoTrust คำตอบขึ้นอยู่กับ Use Case ของคุณ ดูตารางเปรียบเทียบ:

หัวข้อLet's Encrypt WildcardWildcard ที่ซื้อ (เช่น RapidSSL)
ราคาฟรี 100%เริ่มต้นหลักพันบาท/ปี
อายุใบ90 วัน (Renew อัตโนมัติ)1-3 ปี (ไม่ต้อง Renew บ่อย)
ValidationDV เท่านั้น (Domain Validation)DV, OV, EV ได้ตามต้องการ
Warrantyไม่มีมี (หลักพัน-แสนดอลลาร์)
เหมาะกับส่วนตัว, Startup, Dev/Testองค์กร, E-Commerce ขนาดกลางใหญ่
Auto-Renew✅ Certbot + systemdต้องทำเอง (หรือใช้ API ของ CA)

สำหรับ VPS ที่ใช้ภายในองค์กร เว็บ Portfolio ส่วนตัว หรือโปรเจกต์ Startup ที่ต้องการประหยัดค่าใช้จ่าย Let's Encrypt Wildcard เป็นตัวเลือกที่ดีเยี่ยม ส่วนธุรกิจที่ต้องการ OV หรือ EV Validation เพื่อแสดงชื่อบริษัทบน Browser ควรเลือกซื้อ Wildcard จาก CA ที่ผ่านการ Audit

AsiaGB มีบริการ Wildcard SSL ที่ได้รับการ Audit จาก CA ที่น่าเชื่อถือและมีใบรับประกัน — ดูรายละเอียดได้ที่ หน้า SSL Certificate ของเรา

ตั้งค่า Nginx Virtual Host สำหรับหลาย Subdomain ด้วยใบ Wildcard เดียว

เมื่อได้ใบ Wildcard แล้วสามารถใช้ไฟล์ Cert ชุดเดียวกับทุก Virtual Host ได้เลย ตัวอย่างการตั้งค่า 3 Subdomain ในไฟล์ config แยกกัน:

# /etc/nginx/sites-available/shop.conf
server {
    listen 443 ssl http2;
    server_name shop.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;
    root /var/www/shop;
    index index.html index.php;
}

# /etc/nginx/sites-available/blog.conf
server {
    listen 443 ssl http2;
    server_name blog.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;
    root /var/www/blog;
    index index.html index.php;
}

ไฟล์ Cert ชุดเดิม ใช้ได้ทั้งสอง Virtual Host — เมื่อ Certbot Renew ใบใหม่ทุก 60 วัน renewal hook จะ reload Nginx ให้อัตโนมัติ ไม่ต้องแตะ config ของแต่ละ Subdomain

ตรวจสอบว่า Nginx โหลด config ทุกไฟล์ใน sites-enabled:

ls -la /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

แก้ปัญหาที่พบบ่อยเมื่อออก Wildcard SSL

ปัญหาที่ผู้ใช้ Certbot DNS-01 Challenge พบบ่อยและวิธีแก้ไข:

ปัญหา สาเหตุ วิธีแก้
DNS propagation timeout TXT record กระจายไม่ทันก่อน Certbot ตรวจ เพิ่ม --dns-cloudflare-propagation-seconds 60
credentials.ini permission error ไฟล์ไม่ได้ตั้ง permission 600 sudo chmod 600 credentials.ini
Rate limit exceeded ขอใบซ้ำเกิน 5 ครั้ง/สัปดาห์ต่อโดเมน รอ 7 วัน หรือใช้ --staging ตอนทดสอบ
Nginx ไม่ reload หลัง renew ไม่มี renewal hook หรือ hook ไม่มีสิทธิ์ ตรวจ chmod +x reload-nginx.sh

ก่อนออกใบจริงแนะนำทดสอบด้วย --staging ก่อนเสมอ เพื่อหลีกเลี่ยง Rate Limit ที่จะทำให้รอถึง 7 วัน:

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --staging \
  -d example.com -d "*.example.com"

วิธีตรวจวันหมดอายุ

sudo certbot certificates
# หรือ
sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates

Checklist Wildcard SSL ปลอดภัย

  1. เก็บ credentials.ini ที่ permission 600 เสมอ
  2. ใช้ Cloudflare API Token (Zone:DNS Edit) — ห้ามใช้ Global API Key
  3. เปิด ssl_protocols TLSv1.2 TLSv1.3 เท่านั้น — ปิด TLS 1.0/1.1
  4. ตั้ง Auto-Renew + Renewal Hook reload Nginx
  5. Monitor ด้วย Lighthouse หรือ SSL Server Test ของ AsiaGB เป็นระยะ
  6. Wildcard ครอบคลุมแค่ level เดียว*.example.com ครอบ a.example.com ได้ แต่ไม่ครอบ b.a.example.com

ต้องการ VPS สำหรับ Web + Wildcard SSL?

AsiaGB VPS เริ่มต้น 500 บาท/เดือน Full Root Access พร้อมเปิด Port อิสระสำหรับ Let's Encrypt และ Nginx เลือกทำเลไทย / สิงคโปร์

ดูแพ็กเกจ VPS