คู่มือฉบับสมบูรณ์สำหรับสร้างใบรับรอง SSL Wildcard พร้อม Bash Script อัตโนมัติ
Wildcard Certificate คือใบรับรอง SSL ที่ครอบคลุมโดเมนย่อยทั้งหมดของโดเมนหลัก
เช่น *.example.com
จะครอบคลุม www.example.com,
api.example.com,
mail.example.com
และทุกซับโดเมนอื่นๆ ทำให้ไม่ต้องสร้างใบรับรองแยกสำหรับแต่ละซับโดเมน
เพื่อใช้ DNS-01 challenge กับ Let's Encrypt ผ่านสคริปต์นี้ โดเมนของคุณ ต้อง ใช้ Cloudflare nameservers หากไม่ปฏิบัติ การสร้าง/ลบ TXT record อัตโนมัติจะไม่สำเร็จ
ns1.cloudflare.com, ns2.cloudflare.com)เข้าสู่ Cloudflare Dashboard
ไปที่ dash.cloudflare.com
ไปที่ API Tokens
คลิก My Profile → API Tokens
สร้าง Token ใหม่
คลิก Create Token → เลือก Template Edit zone DNS
กำหนด Permissions
สร้างและคัดลอก Token
⚠️ คัดลอก Token เก็บไว้ทันที จะไม่แสดงให้เห็นอีก!
#!/usr/bin/env bash
# -------------------------------------------------------------
# certbot-wildcard.sh - Create/renew Let's Encrypt Wildcard cert
# -------------------------------------------------------------
set -euo pipefail
# ⚙️ Configuration - แก้ไขค่าเหล่านี้
DOMAIN="example.com" # กำหนดโดเมนของคุณ
CF_API_TOKEN="YOUR_CF_TOKEN_HERE" # ใส่ Token จาก Cloudflare
# 📋 Logging Functions
log(){ echo -e "\e[32m[INFO]\e[0m $*"; }
error(){ echo -e "\e[31m[ERROR]\e[0m $*" >&2; exit 1; }
# 🔍 Prerequisites Check
if ! command -v certbot >/dev/null; then
error "กรุณาติดตั้ง certbot ก่อน (sudo apt install certbot)"
fi
if [[ "${1:-}" == "auth" ]]; then
# 📝 Create DNS TXT record for validation
VALIDATION="$CERTBOT_VALIDATION"
RECORD="_acme-challenge.$CERTBOT_DOMAIN"
# Get Zone ID
log "Getting Zone ID for $DOMAIN..."
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
# Create TXT record
log "Creating TXT record: $RECORD"
RESP=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"TXT\",\"name\":\"$RECORD\",\"content\":\"$VALIDATION\",\"ttl\":120}")
export CF_DNS_RECORD_ID=$(echo $RESP | jq -r '.result.id')
log "✓ TXT record created (ID=$CF_DNS_RECORD_ID)"
# Wait for DNS propagation
log "Waiting 30 seconds for DNS propagation..."
sleep 30
elif [[ "${1:-}" == "cleanup" ]]; then
# 🧹 Remove DNS TXT record after validation
if [[ -z "${CF_DNS_RECORD_ID:-}" ]]; then
error "DNS record ID not found"
fi
# Get Zone ID
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" | jq -r '.result[0].id')
# Delete TXT record
log "Removing TXT record..."
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$CF_DNS_RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN"
log "✓ TXT record removed"
else
# 🚀 Main function - Request certificate
log "Requesting wildcard certificate for *.$DOMAIN"
certbot certonly \
--manual \
--preferred-challenges dns \
--manual-auth-hook "$(realpath "$0") auth" \
--manual-cleanup-hook "$(realpath "$0") cleanup" \
-d "*.$DOMAIN" \
-d "$DOMAIN" \
--non-interactive \
--agree-tos \
--email admin@$DOMAIN
log "✓ Certificate created successfully!"
log "Certificate location: /etc/letsencrypt/live/$DOMAIN/"
fi
main, auth, cleanupauth ก่อน validation และ cleanup หลัง validationsudo mv certbot-wildcard.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/certbot-wildcard.sh
sudo nano /usr/local/bin/certbot-wildcard.sh
แก้ไขค่า DOMAIN และ CF_API_TOKEN ให้ถูกต้อง
sudo /usr/local/bin/certbot-wildcard.sh
ระบบจะทำการ:
/etc/letsencrypt/live/example.com/
ถ้าทุกอย่างถูกต้อง คุณจะเห็นข้อความ "Successfully received certificate"
พร้อมพาธของไฟล์ใบรับรอง
ใช้คำสั่งต่อไปนี้เพื่อตรวจสอบ:
# ใช้ nslookup nslookup -type=ns example.com # หรือใช้ dig dig NS example.com +short # หรือใช้ host host -t ns example.com
ผลลัพธ์ที่คาดหวัง:
ควรแสดง nameservers ของ Cloudflare เช่น:
ns1.cloudflare.com และ ns2.cloudflare.com
sudo crontab -e
# ต่ออายุ Wildcard Certificate ทุก 30 วัน เวลา 02:30 น. 30 2 */30 * * /usr/local/bin/certbot-wildcard.sh >> /var/log/certbot-wildcard.log 2>&1
อธิบาย Cron:
• 30 2 = เวลา 02:30 น.
• */30 = ทุก 30 วัน
• /var/log/certbot-wildcard.log = เก็บ log
DNS propagation อาจใช้เวลา 1-5 นาที ถ้า script fail ลองเพิ่มเวลานอนจาก 30 เป็น 60 วินาที หรือเพิ่ม retry logic ในสคริปต์
openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/cert.pem
ผลลัพธ์จะแสดงวันที่เริ่มต้น (notBefore)
และวันที่หมดอายุ (notAfter)
ของใบรับรอง
การตรวจสอบ DNS ไม่สำเร็จ
วิธีแก้: ตรวจสอบว่าโดเมนชี้ NS ไปยัง Cloudflare แล้ว (ดูหัวข้อ "ตรวจสอบสถานะ DNS") และรอให้ propagation เสร็จสิ้น
ข้อความ error เกี่ยวกับ token
วิธีแก้: ตรวจสอบค่า CF_API_TOKEN
ว่ามีสิทธิ Zone → DNS → Edit
และครอบคลุมโดเมนที่ถูกต้อง
Certbot timeout ขณะรอ DNS
วิธีแก้: เพิ่มเวลานอนจาก 30 เป็น 60 วินาทีในบรรทัด sleep
หรือลด TTL ของ DNS records ใน Cloudflare
ถูกบล็อกโดย Cloudflare
วิธีแก้: เพิ่ม delay ระหว่างการสร้างและลบ TXT record หรือใช้ API Token ที่ไม่มี rate-limit ข้อจำกัด
ด้วยสคริปต์ Bash นี้ คุณสามารถสร้างและต่ออายุ Wildcard SSL Certificate จาก Let's Encrypt อย่างอัตโนมัติบน Ubuntu/Debian โดยใช้ Cloudflare DNS API ทำให้ทุกซับโดเมนของคุณปลอดภัยโดยไม่มีค่าใช้จ่าย
รวดเร็ว
ต่ออายุอัตโนมัติ
ฟรี