随机
Enter 搜索 ↑↓ 切换 Esc 清空

certbot-dns

命令

通过 DNS 验证方式申请和续签 SSL 证书

certbot-dns

通过 DNS 验证方式申请和续签 SSL 证书

补充说明

Certbot 是 EFF 开发的 Let's Encrypt SSL 证书管理工具。DNS 验证通过在域名 DNS 中添加 TXT 记录证明所有权,无需开放 80/443 端口,支持通配符证书,适用于服务器无公网端口或 HTTP 验证不便的场景。

安装

# Debian/Ubuntu
sudo apt update && sudo apt install -y certbot

# CentOS/RHEL
sudo yum install -y epel-release && sudo yum install -y certbot

# Fedora
sudo dnf install -y certbot

# Alpine
sudo apk add certbot

# 验证
certbot --version
certbot plugins

目录结构

/etc/letsencrypt/
├── live/        # 当前证书符号链接
├── archive/     # 历史证书存档
├── renewal/     # 续订配置
└── keys/        # 私钥文件

手动 DNS 验证

适用于无法安装自动化 DNS 插件的场景,需在域名控制面板手动添加 TXT 记录。

申请证书

sudo certbot certonly --manual --preferred-challenges dns \
  -d "example.com" \
  -d "*.example.com" \
  --register-unsafely-without-email \
  --agree-tos

操作流程

  1. 执行命令后 Certbot 提示添加 TXT 记录:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1. 登录域名 DNS 管理面板添加记录:
字段
记录类型 TXT
名称 _acme-challenge
Certbot 给出的随机字符串
TTL 300
  1. 验证记录生效:
dig -t TXT _acme-challenge.example.com
  1. 返回终端按 Enter 完成验证

自动 DNS 验证

通过 DNS 服务商 API 自动添加和删除 TXT 记录,实现全流程无人值守。Cloudflare API 自动化流程详见 certbot-api

Cloudflare

sudo apt install -y python3-certbot-dns-cloudflare
mkdir -p ~/.secrets
cat > ~/.secrets/cloudflare.ini <<EOF
dns_cloudflare_api_token = YOUR_API_TOKEN
EOF
chmod 600 ~/.secrets/cloudflare.ini

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com -d "*.example.com"

详细 Cloudflare API 自动化流程见 certbot-api

其他 DNS 服务商

服务商 插件包 凭据配置项
DNSPod python3-certbot-dns-dnspod dns_dnspod_email / dns_dnspod_api_key
阿里云 python3-certbot-dns-aliyun dns_aliyun_access_key / dns_aliyun_access_secret
华为云 python3-certbot-dns-huaweicloud dns_huaweicloud_username / dns_huaweicloud_password
AWS Route53 python3-certbot-dns-route53 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY(环境变量)
Google Cloud python3-certbot-dns-google-domains dns_google_domains_access_token

部署证书

# 创建续签钩子
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
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;
}

自动续签

# 每天凌晨 3 点检查续签(仅到期前 30 天内才实际续签)
echo "0 3 * * * certbot renew --quiet" | crontab -

管理命令

sudo certbot certificates              # 查看所有证书
sudo certbot renew --dry-run           # 测试续签
sudo certbot renew --force-renewal     # 强制续签
sudo certbot delete --cert-name example.com   # 删除证书
sudo tail -f /var/log/letsencrypt/letsencrypt.log  # 查看日志

故障排除

# 检查 DNS 记录是否生效
dig -t TXT _acme-challenge.example.com

# 检查证书有效期
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

# 验证证书链
openssl verify -CAfile /etc/letsencrypt/live/example.com/chain.pem \
  /etc/letsencrypt/live/example.com/cert.pem

# 查看错误日志
grep -iE "error|failed" /var/log/letsencrypt/letsencrypt.log

# 修复目录权限
sudo chown -R root:root /etc/letsencrypt

健康检查脚本

#!/bin/bash
DOMAIN="example.com"
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 ))

chain_ok=$(openssl verify -CAfile \
  /etc/letsencrypt/live/$DOMAIN/chain.pem \
  /etc/letsencrypt/live/$DOMAIN/cert.pem 2>&1)

if [ "$days_left" -le 30 ]; then
    echo "证书将在 $days_left 天后过期" | mail -s "SSL 警告: $DOMAIN" "$ADMIN_EMAIL"
fi
if [[ "$chain_ok" != *"OK"* ]]; then
    echo "证书链错误: $chain_ok" | mail -s "SSL 错误: $DOMAIN" "$ADMIN_EMAIL"
fi

echo "域名: $DOMAIN  有效期: ${days_left}天  证书链: $chain_ok"

参数说明

相关命令

参数说明

参数 说明
certonly 仅获取证书,不自动安装
--manual 手动交互模式
--preferred-challenges dns 使用 DNS-01 挑战
-d 域名,可重复使用
--dns-cloudflare 使用 Cloudflare DNS 插件
--dns-cloudflare-credentials 指定 Cloudflare 凭据文件路径
--force-renewal 强制重新申请
--dry-run 测试运行,不实际申请
--agree-tos 同意 Let's Encrypt 服务条款