Certbot SSL 证书管理 & Cloudflare API 验证 🔐

🌐 使用 Cloudflare DNS API 自动验证和续签 SSL 证书,无需开放服务器端口 - 安全、高效、自动化的证书管理解决方案
📋 目录
🎯 简介
Certbot 是由 EFF (Electronic Frontier Foundation) 开发的免费开源工具,用于自动化管理和部署 Let’s Encrypt SSL 证书。
🌟 Cloudflare API 验证的优势
- ✅ 无需开放端口:不需要开放 80/443 端口,增强服务器安全性
- ✅ 支持通配符:可以申请
*.example.com
通配符证书,保护所有子域名
- ✅ 完全自动化:支持无人值守自动续签,减少人工干预
- ✅ 安全可靠:使用 API Token 而非全局密钥,遵循最小权限原则
- ✅ DNS 验证:通过 DNS TXT 记录验证域名所有权,适用于各种服务器环境
- ✅ 多域名支持:单张证书可包含多个域名和通配符
🔗 相关链接
📦 安装配置
🐧 安装 Certbot 和 Cloudflare 插件
Ubuntu/Debian 系统
1 2 3 4 5 6 7 8 9
| sudo apt update
sudo apt install -y certbot python3-certbot-dns-cloudflare
certbot --version python3 -c "import certbot_dns_cloudflare; print('✅ Cloudflare plugin installed')"
|
CentOS/RHEL 系统
1 2 3 4 5 6 7 8 9 10 11
| sudo yum install -y epel-release
sudo dnf install -y epel-release
sudo yum install -y certbot python3-certbot-dns-cloudflare
sudo pip3 install certbot certbot-dns-cloudflare
|
使用 Snap 安装(推荐)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| sudo apt install -y snapd
sudo snap install core sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok sudo snap install certbot-dns-cloudflare
certbot --version
|
📁 创建配置目录
1 2 3 4 5 6 7
| sudo mkdir -p /etc/letsencrypt sudo chmod 700 /etc/letsencrypt
sudo mkdir -p /var/log/letsencrypt sudo chmod 755 /var/log/letsencrypt
|
🔑 Cloudflare API 设置
🎯 获取 Cloudflare API Token
- 登录 Cloudflare 控制台: https://dash.cloudflare.com/
- 进入 API Tokens: 点击右上角用户图标 → My Profile → API Tokens
- 创建 Token: 点击 “Create Token” → 使用 “Edit zone DNS” 模板
- 配置权限:
- 权限: Zone - DNS - Edit
- 资源: Include - All zones (或指定特定域名)
- 创建并保存 Token: 复制生成的 API Token

📝 创建配置文件
1 2 3 4 5 6 7 8 9 10 11 12
| sudo tee /etc/letsencrypt/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = YOUR_API_TOKEN_HERE EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini sudo chown root:root /etc/letsencrypt/cloudflare.ini
sudo cat /etc/letsencrypt/cloudflare.ini
|
⚠️ 重要:
- 使用 API Token 时只需配置
dns_cloudflare_api_token
,不需要 dns_cloudflare_api_key
和 dns_cloudflare_email
- 将
YOUR_API_TOKEN_HERE
替换为实际的 API Token
- 确保配置文件权限为 600,防止其他用户读取
📝 证书申请
🚀 申请通配符证书
1 2 3 4 5 6 7 8 9 10 11
| sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ --preferred-challenges dns-01 \ -d "example.com" \ -d "*.example.com" \ --register-unsafely-without-email \ --agree-tos \ --non-interactive
|
📋 参数说明
--dns-cloudflare
: 使用 Cloudflare DNS 验证
--dns-cloudflare-credentials
: 指定凭证文件路径
--dns-cloudflare-propagation-seconds 60
: 等待 DNS 传播的时间(秒)
--preferred-challenges dns-01
: 优先使用 DNS 挑战验证
-d
: 指定域名(支持多个域名)
--register-unsafely-without-email
: 不提供邮箱(可选)
--agree-tos
: 同意服务条款
--non-interactive
: 非交互模式,适合脚本运行
🎯 申请多域名证书
1 2 3 4 5 6 7 8 9 10
| sudo certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \ -d "example.com" \ -d "www.example.com" \ -d "api.example.com" \ -d "*.staging.example.com" \ --register-unsafely-without-email \ --agree-tos
|
✅ 验证申请结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo certbot certificates
sudo ls -la /etc/letsencrypt/live/example.com/
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -text -noout | head -20
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
sudo openssl verify -CAfile /etc/letsencrypt/live/example.com/chain.pem /etc/letsencrypt/live/example.com/cert.pem
|

⚡ 自动续签
🕐 计划任务配置
方法一:简单续签命令
1 2 3 4 5 6 7 8 9
| sudo crontab -e
30 2 * * * /usr/bin/certbot renew --quiet --renew-hook "systemctl reload nginx"
30 2 * * * /usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"
|
方法二:智能续签脚本
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| sudo tee /usr/local/bin/certbot-renew-smart.sh > /dev/null <<'EOF'
DOMAIN="example.com" LOG_FILE="/var/log/certbot-renew.log" CONFIG_FILE="/etc/letsencrypt/cloudflare.ini" NGINX_CONFIG="/etc/nginx/sites-available/default"
echo "$(date): 开始证书续签检查" >> $LOG_FILE
if [ ! -f "/etc/letsencrypt/live/$DOMAIN/cert.pem" ]; then echo "错误: 证书文件不存在" >> $LOG_FILE exit 1 fi
EXPIRY_DAYS=$(sudo certbot certificates | grep -A 3 "$DOMAIN" | grep "EXPIRY" | awk '{print $6}' | cut -d')' -f1) if [ -z "$EXPIRY_DAYS" ] || [ "$EXPIRY_DAYS" -le 10 ]; then echo "证书即将过期(剩余 ${EXPIRY_DAYS:-未知} 天),尝试续签..." >> $LOG_FILE if sudo certbot renew --dns-cloudflare --dns-cloudflare-credentials $CONFIG_FILE --force-renewal; then echo "证书续签成功" >> $LOG_FILE if sudo nginx -t; then sudo systemctl reload nginx echo "Nginx 配置已重载" >> $LOG_FILE else echo "错误: Nginx 配置测试失败" >> $LOG_FILE fi else echo "证书续签失败" >> $LOG_FILE exit 1 fi else echo "证书有效期剩余 ${EXPIRY_DAYS} 天,无需续签" >> $LOG_FILE fi
echo "$(date): 证书检查完成" >> $LOG_FILE EOF
sudo chmod +x /usr/local/bin/certbot-renew-smart.sh sudo chown root:root /usr/local/bin/certbot-renew-smart.sh
|
📅 添加计划任务
1 2 3 4 5 6 7 8
| sudo crontab -e
0 3 * * * /usr/local/bin/certbot-renew-smart.sh >> /var/log/certbot-renew.log 2>&1
0 2 1 * * find /var/log -name "certbot*.log" -mtime +30 -delete
|
🔔 续签通知配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| sudo tee -a /usr/local/bin/certbot-renew-smart.sh > /dev/null <<'EOF'
send_notification() { local subject="$1" local message="$2" echo "$message" | mail -s "$subject" admin@example.com }
if [ $? -eq 0 ]; then send_notification "证书续签成功" "域名 $DOMAIN 的 SSL 证书已成功续签。" else send_notification "证书续签失败" "域名 $DOMAIN 的 SSL 证书续签失败,请检查日志。" fi EOF
|
🔧 维护管理
📋 常用管理命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| sudo certbot certificates
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
sudo certbot renew --dry-run
sudo certbot renew --cert-name example.com --force-renewal
sudo tail -f /var/log/letsencrypt/letsencrypt.log
sudo certbot show --cert-name example.com
|
🔄 手动同步证书到 Web 服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| sudo cp -f /etc/letsencrypt/live/example.com/fullchain.pem /etc/nginx/ssl/example.com.crt sudo cp -f /etc/letsencrypt/live/example.com/privkey.pem /etc/nginx/ssl/example.com.key
sudo chmod 644 /etc/nginx/ssl/example.com.crt sudo chmod 600 /etc/nginx/ssl/example.com.key sudo chown www-data:www-data /etc/nginx/ssl/example.com.*
sudo nginx -t
sudo systemctl reload nginx
sudo cp -f /etc/letsencrypt/live/example.com/fullchain.pem /etc/ssl/certs/example.com.crt sudo cp -f /etc/letsencrypt/live/example.com/privkey.pem /etc/ssl/private/example.com.key sudo systemctl reload apache2
|
🗑️ 撤销和删除证书
1 2 3 4 5 6 7 8 9 10
| sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem --reason superseded
sudo certbot delete --cert-name example.com
sudo rm -rf /etc/letsencrypt/archive/example.com sudo rm -rf /etc/letsencrypt/live/example.com sudo rm -rf /etc/letsencrypt/renewal/example.com.conf
|
🔍 故障排除命令
1 2 3 4 5 6 7 8 9 10 11 12 13
| dig TXT _acme-challenge.example.com
sudo certbot --debug --verbose certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini -d example.com
curl -X GET "https://api.cloudflare.com/client/v4/zones" \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json"
curl "https://crt.sh/?q=example.com&output=json" | jq .
|
🗑️ 完全卸载
🔄 卸载 Certbot
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
| sudo systemctl stop certbot.timer sudo systemctl disable certbot.timer
sudo apt remove --purge -y certbot python3-certbot-dns-cloudflare
sudo snap remove certbot certbot-dns-cloudflare sudo rm -f /usr/bin/certbot
sudo rm -rf /etc/letsencrypt/ sudo rm -rf /var/lib/letsencrypt/ sudo rm -rf /var/log/letsencrypt/
sudo crontab -l | grep -v certbot | sudo crontab -
sudo rm -f /usr/local/bin/certbot-renew-smart.sh
sudo apt autoremove -y sudo apt clean
|
📊 验证卸载
1 2 3 4 5 6 7
| which certbot || echo "✅ Certbot 已卸载" ls /etc/letsencrypt 2>/dev/null || echo "✅ 配置目录已清理" ps aux | grep certbot | grep -v grep || echo "✅ 无 Certbot 进程"
python3 -c "import certbot_dns_cloudflare" 2>/dev/null && echo "❌ Cloudflare 插件仍在" || echo "✅ Cloudflare 插件已移除"
|
💡 最佳实践
🛡️ 安全建议
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
sudo chmod 600 /etc/letsencrypt/cloudflare.ini sudo chmod 700 /etc/letsencrypt/live/ sudo chmod 755 /etc/letsencrypt/archive/
sudo tar -czvf /backup/letsencrypt-backup-$(date +%Y%m%d).tar.gz /etc/letsencrypt/
sudo apt install -y auditd sudo auditctl -w /etc/letsencrypt/ -p wa -k letsencrypt
|
📊 监控和告警
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
DOMAIN="example.com" WARNING_DAYS=14 ADMIN_EMAIL="admin@example.com"
EXPIRY_DATE=$(sudo openssl x509 -in /etc/letsencrypt/live/$DOMAIN/cert.pem -enddate -noout | cut -d= -f2) EXPIRY_TS=$(date -d "$EXPIRY_DATE" +%s) CURRENT_TS=$(date +%s) DAYS_LEFT=$(( (EXPIRY_TS - CURRENT_TS) / 86400 ))
if [ $DAYS_LEFT -le $WARNING_DAYS ]; then SUBJECT="SSL 证书过期警告: $DOMAIN" MESSAGE="域名 $DOMAIN 的 SSL 证书将在 $DAYS_LEFT 天后过期($EXPIRY_DATE)。请及时续签。" echo "$MESSAGE" | mail -s "$SUBJECT" "$ADMIN_EMAIL" fi
|
🔧 高级故障排除技巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
sudo certbot certonly --test-cert --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \ -d example.com
curl -s "https://crt.sh/?q=example.com&output=json" | jq -r '.[] | select(.name_value | contains("example.com")) | .not_after' | head -1
sudo certbot certonly --manual --preferred-challenges dns -d example.com --dry-run
|
📝 更新和维护
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo apt update && sudo apt upgrade certbot python3-certbot-dns-cloudflare
sudo snap refresh certbot
python3 -c "import pkg_resources; print('Cloudflare plugin version:', pkg_resources.get_distribution('certbot-dns-cloudflare').version)"
sudo certbot renew --dry-run --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
sudo journalctl -u certbot | tail -50
|
🌐 多服务器证书同步
1 2 3 4 5 6 7 8 9 10 11 12 13
|
SERVERS=("server1.example.com" "server2.example.com") DOMAIN="example.com"
for SERVER in "${SERVERS[@]}"; do echo "同步证书到 $SERVER..." rsync -avz -e "ssh -p 22" \ /etc/letsencrypt/live/$DOMAIN/ \ user@$SERVER:/etc/letsencrypt/live/$DOMAIN/ ssh user@$SERVER "sudo systemctl reload nginx" done
|
🎯 提示: 建议在生产环境部署前,先在测试环境验证所有配置。定期检查日志和证书状态,确保自动化流程正常运行。
📚 扩展阅读:
🔧 紧急恢复:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo /usr/local/bin/certbot-renew-smart.sh
sudo nginx -t
sudo cp -rf /backup/letsencrypt-backup/live/example.com/ /etc/letsencrypt/live/ sudo systemctl reload nginx
sudo certbot certonly --dns-cloudflare \ --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \ -d example.com --force-renewal
|
💡 专业建议:
- 使用证书监控服务如 SSL Labs 定期检查证书配置
- 实施证书钉扎 (Certificate Pinning) 增强安全性
- 考虑使用双向 TLS (mTLS) 对于内部服务
- 定期进行安全审计和渗透测试
希望本指南能帮助您顺利使用 Certbot 和 Cloudflare API 管理 SSL 证书!🔐
Certbot SSL 证书管理 & Cloudflare API 验证 🔐