Certbot + Let's Encrypt + 腾讯云 DNS 验证自动续期证书
本文介绍如何在 Ubuntu 环境下使用 Certbot 配合 certbot-dns-tencentcloud 插件,通过腾讯云 DNS 验证申请 Let's Encrypt 泛域名(Wildcard)证书,并实现自动续期。
注意:旧版 DNSPod API (
https://dnsapi.cn) 使用login_token的方式已不再可靠(会返回 401 错误)。本文使用的certbot-dns-tencentcloud插件基于腾讯云新版 DNSPod API,无需手写签名脚本。
1. 安装
sudo apt-get update
sudo apt-get install certbot python3-pip安装腾讯云 DNS 插件:
sudo pip3 install certbot-dns-tencentcloud验证插件是否安装成功:
sudo certbot plugins输出中应包含 dns-tencentcloud。
2. 配置腾讯云 API 凭证
2.1 获取 SecretId 和 SecretKey
安全建议:不要使用主账号密钥。应创建一个子用户,仅授予
QcloudDNSPodFullAccess(DNSPod 全读写)权限,并限制来源 IP 为服务器地址。
2.2 创建凭证文件
凭证文件推荐存放路径:~/.secrets/certbot/tencentcloud.ini
sudo mkdir -p ~/.secrets/certbot
sudo tee ~/.secrets/certbot/tencentcloud.ini > /dev/null << 'EOF'
dns_tencentcloud_secret_id = YOUR_SECRET_ID
dns_tencentcloud_secret_key = YOUR_SECRET_KEY
EOF设置严格权限(Certbot 会检查权限,如果其他用户可读会发出警告):
sudo chmod 600 ~/.secrets/certbot/tencentcloud.ini也可以通过环境变量提供凭证(适用于 CI/CD 等场景):
export TENCENTCLOUD_SECRET_ID=<your_secret_id>
export TENCENTCLOUD_SECRET_KEY=<your_secret_key>3. 申请证书
sudo certbot certonly \
-a dns-tencentcloud \
--dns-tencentcloud-credentials ~/.secrets/certbot/tencentcloud.ini \
-d example.com -d "*.example.com" \
--email your_email@example.com \
--agree-tos参数说明:
| 参数 | 说明 |
|---|---|
certonly | 仅获取证书,不自动修改 Web 服务器配置 |
-a dns-tencentcloud | 使用腾讯云 DNS 插件进行验证(等同于 --authenticator) |
--dns-tencentcloud-credentials | 凭证文件路径 |
--dns-tencentcloud-propagation-seconds | DNS 记录生效等待时间(默认 10 秒,可选参数) |
-d | 指定域名,可多次使用 |
--email | 接收证书到期通知的邮箱 |
--agree-tos | 同意 Let's Encrypt 服务条款 |
提示:Certbot 现在默认使用 ACME v2 服务器,无需显式指定
--server参数。
同时申请
*.example.com和example.com时,由于 DNSPod 的 TXT 记录 TTL 最低为 60 秒,Let's Encrypt 可能会读到缓存的旧记录导致验证失败。建议添加--dns-tencentcloud-propagation-seconds 70来延长等待时间。
申请成功后,证书保存在 /etc/letsencrypt/live/example.com/:
ls /etc/letsencrypt/live/example.com/
# cert.pem chain.pem fullchain.pem privkey.pem| 文件 | 用途 |
|---|---|
fullchain.pem | 完整证书链,Nginx 的 ssl_certificate 使用此文件 |
privkey.pem | 私钥,Nginx 的 ssl_certificate_key 使用此文件 |
4. 配置部署钩子
证书更新后需要重载 Web 服务器。将脚本放入 Certbot 的标准部署钩子目录,无需在命令中指定 --deploy-hook,Certbot 会在任何域名证书成功续期后自动执行:
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh > /dev/null << 'EOF'
#!/bin/bash
# 证书更新后自动重载 Nginx
if systemctl is-active --quiet nginx; then
systemctl reload nginx
echo "Nginx reloaded successfully."
fi
EOF
sudo chmod 700 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh5. 自动续期
Let's Encrypt 证书有效期为 90 天。Certbot 安装后会自动配置 Systemd Timer 或 Cron 定时任务(默认每天检查两次),在证书到期前 30 天自动续期。
5.1 测试自动续期
sudo certbot renew --dry-run如果输出无报错,说明自动续期配置正常。
5.2 确认定时任务
# Systemd Timer
systemctl list-timers | grep certbot
# 或 Cron
cat /etc/cron.d/certbot5.3 查看续期配置
首次申请成功后,Certbot 会自动生成配置文件,后续续期自动读取,无需人工干预:
cat /etc/letsencrypt/renewal/example.com.conf6. 常见问题
6.1 同时申请主域名和泛域名时验证失败
同时申请 example.com 和 *.example.com 时,两者共用同一条 _acme-challenge TXT 记录。由于 DNSPod 的 TTL 最低 60 秒,Let's Encrypt 可能缓存旧记录导致第二次验证失败。
解决方案:设置等待时间大于 60 秒:
--dns-tencentcloud-propagation-seconds 706.2 开启调试模式
遇到问题时可以开启插件调试输出:
--dns-tencentcloud-debug true6.3 API 权限策略
插件使用新版 DNSPod API,子用户需要授予 QcloudDNSPodFullAccess 策略(因为需要添加/删除记录,必须写权限)。
附录:为什么不用手写脚本调用 DNSPod API?
腾讯云 DNS API 已升级为 云 API v3,认证方式从简单的 login_token 变为 TC3-HMAC-SHA256 签名。用 bash 实现完整签名流程大约需要 200+ 行代码(参考 acme.sh 的 dns_tencent 插件)。
certbot-dns-tencentcloud 插件封装了完整的 API v3 调用逻辑,是目前最简洁可靠的方案。
参考来源: