certbot-api
使用 API 验证方式申请和续签 SSL 证书
补充说明
Certbot 是 EFF 开发的开源工具,用于自动化管理和部署 Let's Encrypt SSL 证书。结合 Cloudflare DNS API 可通过 DNS-01 挑战验证域名所有权,无需开放 80/443 端口,支持通配符证书和多域名证书的无人值守续签。
安装
# Debian/Ubuntu
sudo apt update && sudo apt install -y certbot python3-certbot-dns-cloudflare
# CentOS/RHEL
sudo yum install -y epel-release && sudo yum install -y certbot python3-certbot-dns-cloudflare
# Snap(推荐)
sudo snap install --classic certbot && sudo snap install certbot-dns-cloudflare
sudo snap set certbot trust-plugin-with-root=ok
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
# 验证
certbot --version
配置 Cloudflare API
在 Cloudflare API Tokens 创建 Token,权限设为 Zone - DNS - Edit,资源指定目标域名。手动 DNS 验证流程见 certbot-dns。
sudo mkdir -p /etc/letsencrypt
sudo tee /etc/letsencrypt/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = YOUR_API_TOKEN
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
申请证书
# 通配符证书
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d "example.com" \
-d "*.example.com" \
--agree-tos \
--non-interactive
# 多域名证书
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" \
--agree-tos
# 测试环境(避免频率限制)
sudo certbot certonly --test-cert \
--dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d example.com
验证证书
sudo certbot certificates
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates
Web 服务器配置
server {
listen 443 ssl;
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_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
自动续签
Certbot 续签后自动重载 Web 服务:
# 创建续签钩子
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload.sh > /dev/null <<'EOF'
#!/bin/bash
systemctl reload nginx 2>/dev/null || systemctl reload apache2 2>/dev/null
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload.sh
# 每天凌晨检查续签(certbot 仅会在证书距到期不足 30 天时实际续签)
echo "0 3 * * * certbot renew --quiet" | sudo crontab -
管理命令
sudo certbot certificates # 列出所有证书
sudo certbot renew --dry-run # 测试续签(不实际执行)
sudo certbot renew --force-renewal # 强制续签
sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem # 撤销
sudo certbot delete --cert-name example.com # 删除证书
sudo tail -f /var/log/letsencrypt/letsencrypt.log # 查看日志
故障排除
# 检查 DNS TXT 记录
dig TXT _acme-challenge.example.com
# 测试 Cloudflare API 连通性
curl -s -X GET "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
# 调试模式运行
sudo certbot --debug -v certonly \
--dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d example.com
完全卸载
sudo systemctl stop certbot.timer 2>/dev/null
sudo apt remove --purge -y certbot python3-certbot-dns-cloudflare 2>/dev/null
sudo snap remove certbot certbot-dns-cloudflare 2>/dev/null
sudo rm -f /usr/bin/certbot
sudo rm -rf /etc/letsencrypt /var/lib/letsencrypt /var/log/letsencrypt
crontab -l 2>/dev/null | grep -v certbot | crontab -
证书过期监控
#!/bin/bash
DOMAIN="example.com"
WARNING_DAYS=14
ADMIN_EMAIL="admin@example.com"
EXPIRY_DATE=$(openssl x509 -enddate -noout \
-in /etc/letsencrypt/live/$DOMAIN/cert.pem | cut -d= -f2)
DAYS_LEFT=$(( ($(date -d "$EXPIRY_DATE" +%s) - $(date +%s)) / 86400 ))
if [ "$DAYS_LEFT" -le "$WARNING_DAYS" ]; then
echo "SSL 证书将在 $DAYS_LEFT 天后过期($EXPIRY_DATE)" |
mail -s "SSL 过期警告: $DOMAIN" "$ADMIN_EMAIL"
fi
相关命令
- certbot-api 👈 当前所在位置
- certbot-dns — 手动及多服务商 DNS 验证
参数说明
| 参数 | 说明 |
|---|---|
--dns-cloudflare |
使用 Cloudflare DNS 插件 |
--dns-cloudflare-credentials |
API Token 凭证文件路径 |
--dns-cloudflare-propagation-seconds |
DNS 传播等待时间(默认 60) |
-d |
域名,可重复使用 |
--test-cert |
使用暂存环境测试 |
--force-renewal |
强制续签 |
--dry-run |
测试运行 |
--non-interactive |
非交互模式 |