Wildcard 憑證概述
Wildcard 憑證(萬用憑證)是一種特殊的 SSL/TLS 憑證,可以保護一個網域及其所有的子網域。例如,一張 *.example.com 的萬用憑證可以同時保護 www.example.com、api.example.com、blog.example.com 等所有子網域。
萬用憑證的優點
- 成本效益:只需要一張憑證即可保護多個子網域
- 管理簡便:不需要為每個子網域單獨申請和管理憑證
- 彈性擴展:新增子網域時無需重新申請憑證
萬用憑證的限制
- 只能保護一層子網域(
*.example.com 無法保護 sub.api.example.com) - 必須使用 DNS-01 驗證方式
DNS-01 驗證方式說明
Let’s Encrypt 提供多種驗證方式來確認您對網域的所有權,但申請萬用憑證時,只能使用 DNS-01 驗證。
DNS-01 驗證的運作方式:
- Let’s Encrypt 會提供一個隨機的驗證 Token
- 您需要在網域的 DNS 設定中新增一筆
_acme-challenge 的 TXT 記錄 - Let’s Encrypt 查詢此 DNS 記錄來驗證您的網域所有權
安裝 Certbot
Certbot 是 Let’s Encrypt 官方推薦的用戶端工具,支援多種作業系統。
Ubuntu/Debian
1
2
3
4
5
6
7
8
| # 更新套件列表
sudo apt update
# 安裝 Certbot
sudo apt install certbot -y
# 驗證安裝
certbot --version
|
CentOS/RHEL
1
2
3
4
5
| # 啟用 EPEL 儲存庫
sudo yum install epel-release -y
# 安裝 Certbot
sudo yum install certbot -y
|
macOS(使用 Homebrew)
手動申請 Wildcard 憑證
使用手動模式申請萬用憑證,需要手動新增 DNS TXT 記錄。
1
2
3
| # 申請萬用憑證
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"
|
執行後,Certbot 會顯示需要新增的 DNS TXT 記錄:
1
2
3
4
5
6
| Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
AbCdEfGhIjKlMnOpQrStUvWxYz1234567890
Press Enter to Continue
|
請依照指示到您的 DNS 服務商後台新增 TXT 記錄,等待 DNS 傳播後再按 Enter 繼續。
驗證 DNS 記錄
在按 Enter 之前,建議先驗證 DNS 記錄是否已正確傳播:
1
2
3
4
5
| # 使用 dig 查詢 TXT 記錄
dig -t TXT _acme-challenge.example.com +short
# 或使用 nslookup
nslookup -type=TXT _acme-challenge.example.com
|
使用 DNS 外掛自動驗證(以 Cloudflare 為例)
手動驗證在憑證續約時非常不便,建議使用 DNS 外掛來自動化整個流程。
安裝 Cloudflare DNS 外掛
1
2
3
4
5
| # Ubuntu/Debian
sudo apt install python3-certbot-dns-cloudflare -y
# 使用 pip 安裝
sudo pip install certbot-dns-cloudflare
|
建立 Cloudflare API 憑證檔案
首先,到 Cloudflare 後台取得 API Token,建議使用 API Token 而非 Global API Key。
建立憑證設定檔:
1
2
3
4
5
| # 建立設定目錄
sudo mkdir -p /etc/letsencrypt/cloudflare
# 建立憑證檔案
sudo nano /etc/letsencrypt/cloudflare/credentials.ini
|
檔案內容:
1
2
3
4
5
6
| # Cloudflare API Token(推薦方式)
dns_cloudflare_api_token = YOUR_API_TOKEN_HERE
# 或使用舊版 API Key(不推薦)
# dns_cloudflare_email = your-email@example.com
# dns_cloudflare_api_key = YOUR_GLOBAL_API_KEY
|
設定檔案權限:
1
| sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
|
使用 Cloudflare 外掛申請憑證
1
2
3
| sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
-d "*.example.com" -d "example.com"
|
設定自動續約
Let’s Encrypt 憑證有效期為 90 天,建議設定自動續約。
測試續約
1
2
| # 測試續約流程(不會真正續約)
sudo certbot renew --dry-run
|
設定 Cron 排程
1
2
3
4
5
| # 編輯 crontab
sudo crontab -e
# 新增以下排程(每天凌晨 3 點檢查並續約)
0 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"
|
使用 Systemd Timer(推薦)
現代 Linux 發行版通常已內建 Certbot 的 systemd timer:
1
2
3
4
5
6
7
8
9
| # 檢查 timer 狀態
sudo systemctl status certbot.timer
# 啟用 timer
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
# 查看排程
sudo systemctl list-timers
|
Nginx 設定使用萬用憑證
憑證申請成功後,檔案位置通常在 /etc/letsencrypt/live/example.com/。
基本設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| server {
listen 443 ssl http2;
server_name *.example.com;
# SSL 憑證設定
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 安全設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS 設定
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/html;
index index.html;
}
# HTTP 導向 HTTPS
server {
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
|
測試並重新載入 Nginx
1
2
3
4
5
| # 測試設定檔語法
sudo nginx -t
# 重新載入設定
sudo systemctl reload nginx
|
多網域與萬用憑證組合
您可以在同一張憑證中包含多個網域和萬用憑證:
1
2
3
4
5
6
| sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
-d "example.com" \
-d "*.example.com" \
-d "example.org" \
-d "*.example.org"
|
注意事項
- 每張憑證最多可包含 100 個網域名稱
- 每個註冊網域每週最多可申請 50 張憑證
- 重複申請相同網域組合的憑證有頻率限制
常見問題排解
問題 1:DNS 驗證失敗
1
2
3
4
5
| IMPORTANT NOTES:
- The following errors were reported by the server:
Domain: example.com
Type: dns
Detail: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com
|
解決方案:
- 確認 DNS TXT 記錄已正確新增
- 等待 DNS 傳播(可能需要數分鐘到數小時)
- 使用
dig 或 nslookup 確認記錄已生效
問題 2:達到頻率限制
1
| Error: urn:ietf:params:acme:error:rateLimited
|
解決方案:
- 等待一週後重試
- 開發測試時使用 staging 環境:
--staging
問題 3:Cloudflare API 權限不足
確認 API Token 具有以下權限:
- Zone - DNS - Edit
- Zone - Zone - Read
問題 4:憑證續約失敗
1
2
3
4
5
| # 檢查 Certbot 日誌
sudo cat /var/log/letsencrypt/letsencrypt.log
# 手動測試續約
sudo certbot renew --dry-run --verbose
|
參考資料