Certbot SSL 证书管理 & DNS验证 🔐
🌐 自动化 SSL 证书管理,为你的网站提供免费 HTTPS 加密
目录
🔗 Certbot 简介
🌟 什么是 Certbot?
Certbot 是由 Electronic Frontier Foundation (EFF) 开发的开源工具,用于自动化管理和部署 SSL/TLS 证书。与 Let’s Encrypt 合作,提供免费的 SSL 证书服务。
🔗 重要链接
🎯 主要特性
- ✅ 免费 SSL 证书
- ✅ 自动续签
- ✅ 多域名支持
- ✅ 通配符证书
- ✅ 多种验证方式(HTTP、DNS、TLS-SNI)
- ✅ 支持多种Web服务器(Nginx、Apache等)
- ✅ 跨平台支持(Linux、Windows、macOS)
📦 安装与配置
🐧 系统安装命令
Debian/Ubuntu
1
|
sudo apt update && sudo apt install -y certbot python3-certbot-nginx
|
🔴 CentOS/RHEL
1
|
sudo yum update && sudo yum install -y certbot python3-certbot-nginx
|
🏔️ Alpine Linux
1
|
sudo apk update && sudo apk add certbot
|
🐧 Fedora
1
|
sudo dnf update && sudo dnf install -y certbot python3-certbot-nginx
|
🔍 验证安装
1
2
3
4
5
6
7
8
|
# 查看版本
certbot --version
# 查看帮助
certbot --help
# 检查插件
certbot plugins
|
📁 目录结构
1
2
3
4
5
|
/etc/letsencrypt/
├── live/ # 当前证书符号链接
├── archive/ # 历史证书存档
├── renewal/ # 续订配置
└── keys/ # 私钥文件
|
🔐 DNS 验证申请
🎯 DNS 验证的优势
- 🌍 支持通配符证书 (
*.example.com
)
- 🔧 无需开放服务器端口
- 🚀 适合国内网络环境
- 🔒 更安全,不需要暴露服务器到公网
- ⚡ 验证过程更快,无需等待HTTP请求
📝 申请通配符证书
1
2
3
4
5
6
|
# 申请通配符证书
sudo certbot certonly --manual --preferred-challenges dns \
-d "mobufan.eu.org" \
-d "*.mobufan.eu.org" \
--register-unsafely-without-email \
--agree-tos
|
🔧 DNS 记录配置步骤
-
获取 TXT 记录信息
1
2
3
4
5
|
# 执行命令后 Certbot 会显示:
# Please deploy a DNS TXT record under the name:
# _acme-challenge.mobufan.eu.org
# with the following value:
# psR23wa2k5tVJws7gUhfwpVI5MclBOfvOaOmKyn51w8
|
-
添加 DNS 记录
- 登录域名控制面板
- 添加 TXT 记录:
- 名称:
_acme-challenge
- 值:
psR23wa2k5tVJws7gUhfwpVI5MclBOfvOaOmKyn51w8
- TTL:
300
(5分钟)
-
等待 DNS 传播
1
2
3
|
# 验证 DNS 记录
dig TXT _acme-challenge.mobufan.eu.org
nslookup -type=TXT _acme-challenge.mobufan.eu.org
|
-
完成验证
- 等待 2-5 分钟让 DNS 生效
- 返回终端按回车继续
📊 证书文件位置
1
2
3
4
5
6
|
# 证书文件路径
/etc/letsencrypt/live/mobufan.eu.org/
├── fullchain.pem # 完整证书链
├── privkey.pem # 私钥文件
├── cert.pem # 证书文件
└── chain.pem # 中间证书
|
🔄 同步到 Nginx
1
2
3
4
5
6
7
8
9
10
11
|
# 创建 SSL 目录
sudo mkdir -p /etc/nginx/ssl
# 同步证书到 Nginx
sudo cp /etc/letsencrypt/live/mobufan.eu.org/fullchain.pem /etc/nginx/ssl/cert.pem
sudo cp /etc/letsencrypt/live/mobufan.eu.org/privkey.pem /etc/nginx/ssl/key.pem
# 设置正确权限
sudo chmod 644 /etc/nginx/ssl/cert.pem
sudo chmod 600 /etc/nginx/ssl/key.pem
sudo chown -R www-data:www-data /etc/nginx/ssl/
|
🔄 证书管理
📋 查看证书信息
1
2
3
4
5
6
7
8
9
10
11
|
# 查看所有证书
sudo certbot certificates
# 查看证书详情
sudo openssl x509 -in /etc/letsencrypt/live/mobufan.eu.org/cert.pem -text -noout
# 检查证书有效期
sudo certbot certificates | grep -E "Certificate Name|Expiry"
# 检查证书详细信息
sudo openssl x509 -in /etc/letsencrypt/live/mobufan.eu.org/cert.pem -noout -dates
|
🔄 手动续签证书
1
2
3
4
5
6
7
8
|
# 续签所有证书
sudo certbot renew
# 强制续签特定证书
sudo certbot renew --cert-name mobufan.eu.org --force-renewal
# 测试续签(不实际执行)
sudo certbot renew --dry-run
|
🗑️ 撤销证书
1
2
3
4
5
|
# 撤销证书
sudo certbot revoke --cert-path /etc/letsencrypt/live/mobufan.eu.org/cert.pem
# 撤销并删除
sudo certbot delete --cert-name mobufan.eu.org
|
📦 备份证书
1
2
3
4
5
6
7
8
|
# 备份证书文件
sudo tar -czvf ssl-backup-$(date +%Y%m%d).tar.gz /etc/letsencrypt/
# 导出证书和私钥
sudo cp -r /etc/letsencrypt/live/mobufan.eu.org/ ~/ssl-backup/
# 备份续订配置
sudo cp -r /etc/letsencrypt/renewal/ ~/ssl-backup/renewal-config/
|
⏰ 自动续签
🕐 计划任务配置
方法一:直接命令方式
1
2
3
4
5
6
7
8
9
10
|
# 编辑 crontab
sudo crontab -e
# 添加以下内容:
# 每天凌晨 1:05 自动续签
5 1 * * * /usr/bin/certbot renew --quiet --renew-hook "sudo systemctl reload nginx"
# 每天凌晨 1:35 同步证书
35 1 * * * /bin/cp /etc/letsencrypt/live/mobufan.eu.org/fullchain.pem /etc/nginx/ssl/cert.pem
36 1 * * * /bin/cp /etc/letsencrypt/live/mobufan.eu.org/privkey.pem /etc/nginx/ssl/key.pem
|
方法二:使用脚本方式
1
2
3
|
# 创建续签脚本
sudo mkdir -p /opt/scripts/ssl
sudo nano /opt/scripts/ssl/certbot-renew.sh
|
📝 智能续签脚本
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
|
#!/bin/bash
# 📍 /opt/scripts/ssl/certbot-renew.sh
LOG_FILE="/var/log/certbot-renew.log"
DOMAIN="mobufan.eu.org"
DAYS_BEFORE_EXPIRY=5
echo "$(date): 开始检查证书续签" >> $LOG_FILE
# 获取证书过期时间
EXPIRY_DATE=$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/$DOMAIN/cert.pem | cut -d= -f2)
EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
DAYS_UNTIL_EXPIRY=$(( ($EXPIRY_TIMESTAMP - $CURRENT_TIMESTAMP) / 86400 ))
echo "证书有效期剩余: $DAYS_UNTIL_EXPIRY 天" >> $LOG_FILE
if [ $DAYS_UNTIL_EXPIRY -le $DAYS_BEFORE_EXPIRY ]; then
echo "证书即将过期,开始续签..." >> $LOG_FILE
# 停止 Nginx 并暂时关闭防火墙
systemctl stop nginx
iptables -F
ip6tables -F
# 执行续签
if certbot renew --force-renewal; then
echo "证书续签成功" >> $LOG_FILE
# 同步到 Nginx
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/nginx/ssl/cert.pem
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem /etc/nginx/ssl/key.pem
# 重启 Nginx
systemctl restart nginx
echo "Nginx 重启完成" >> $LOG_FILE
else
echo "证书续签失败" >> $LOG_FILE
systemctl start nginx
fi
else
echo "证书仍在有效期内,无需续签" >> $LOG_FILE
fi
echo "$(date): 证书检查完成" >> $LOG_FILE
|
🔧 设置脚本权限
1
2
|
sudo chmod +x /opt/scripts/ssl/certbot-renew.sh
sudo chown root:root /opt/scripts/ssl/certbot-renew.sh
|
📅 添加计划任务
1
2
3
4
5
6
7
8
9
10
11
|
sudo crontab -e
# 添加以下内容:
# 每天凌晨 1:25 执行续签脚本
25 1 * * * /opt/scripts/ssl/certbot-renew.sh >> /var/log/certbot-renew.log 2>&1
# 每周清理旧日志
0 3 * * 0 find /var/log -name "certbot*.log" -mtime +30 -delete
# 每月检查证书状态
0 2 1 * * /usr/bin/certbot certificates >> /var/log/certbot-status.log
|
🔧 故障排除
🐛 常见问题解决
1. DNS 验证失败
1
2
3
4
5
6
7
8
9
|
# 检查 DNS 记录
dig TXT _acme-challenge.mobufan.eu.org
nslookup -type=TXT _acme-challenge.mobufan.eu.org
# 使用其他DNS服务器验证
dig @8.8.8.8 TXT _acme-challenge.mobufan.eu.org
# 手动验证
certbot certonly --manual --preferred-challenges dns --debug
|
2. 证书续签失败
1
2
3
4
5
6
7
8
9
10
11
|
# 查看详细错误
certbot renew --verbose
# 检查证书状态
certbot certificates
# 强制续签
certbot renew --force-renewal
# 检查日志文件
tail -f /var/log/letsencrypt/letsencrypt.log
|
3. 权限问题
1
2
3
4
5
6
7
8
|
# 修复证书文件权限
sudo chown -R root:root /etc/letsencrypt/
sudo chmod -R 755 /etc/letsencrypt/
sudo chmod 644 /etc/letsencrypt/live/*/fullchain.pem
sudo chmod 600 /etc/letsencrypt/live/*/privkey.pem
# 检查Nginx用户权限
sudo chown -R www-data:www-data /etc/nginx/ssl/
|
4. Nginx 配置问题
1
2
3
4
5
6
7
8
9
10
11
12
|
# 检查 Nginx 配置
sudo nginx -t
# 重新加载 Nginx
sudo systemctl reload nginx
# 查看 Nginx 错误日志
tail -f /var/log/nginx/error.log
# 检查防火墙设置
sudo ufw status
sudo iptables -L
|
📊 监控和日志
1
2
3
4
5
6
7
8
9
10
11
12
|
# 查看 Certbot 日志
tail -f /var/log/letsencrypt/letsencrypt.log
# 查看续签日志
tail -f /var/log/certbot-renew.log
# 监控证书有效期
echo "证书有效期:"
openssl x509 -in /etc/letsencrypt/live/mobufan.eu.org/cert.pem -dates -noout
# 设置日志轮转
sudo nano /etc/logrotate.d/certbot
|
💡 最佳实践
🎯 安全建议
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 使用强私钥
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
# 配置完美的前向保密
# 在 Nginx 配置中添加:
# ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# 启用HSTS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# 使用安全的SSL协议和密码套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
|
📦 备份策略
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#!/bin/bash
# 证书备份脚本
BACKUP_DIR="/backup/ssl/$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 备份证书文件
cp -r /etc/letsencrypt/live/ $BACKUP_DIR/
cp -r /etc/letsencrypt/renewal/ $BACKUP_DIR/
cp -r /etc/letsencrypt/archive/ $BACKUP_DIR/
# 备份 Nginx SSL 配置
cp -r /etc/nginx/ssl/ $BACKUP_DIR/nginx-ssl/
cp /etc/nginx/sites-available/* $BACKUP_DIR/nginx-config/
# 创建压缩备份包
tar -czf $BACKUP_DIR/ssl-backup-full.tar.gz $BACKUP_DIR
echo "备份完成: $BACKUP_DIR"
|
🔄 自动化部署
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
|
#!/bin/bash
# 完整的证书部署脚本
DOMAIN="mobufan.eu.org"
EMAIL="admin@mobufan.eu.org"
# 申请证书
certbot certonly --manual --preferred-challenges dns \
-d "$DOMAIN" -d "*.$DOMAIN" \
--email "$EMAIL" \
--agree-tos --no-eff-email
# 检查申请结果
if [ $? -eq 0 ]; then
# 创建SSL目录
mkdir -p /etc/nginx/ssl
# 部署到 Nginx
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/nginx/ssl/cert.pem
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem /etc/nginx/ssl/key.pem
# 设置权限
chmod 644 /etc/nginx/ssl/cert.pem
chmod 600 /etc/nginx/ssl/key.pem
chown -R www-data:www-data /etc/nginx/ssl/
# 重载 Nginx
systemctl reload nginx
echo "✅ 证书部署完成"
else
echo "❌ 证书申请失败"
exit 1
fi
|
📋 健康检查
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
|
#!/bin/bash
# SSL 健康检查脚本
DOMAIN="mobufan.eu.org"
EXPIRY_THRESHOLD=30
ADMIN_EMAIL="admin@example.com"
# 检查证书有效期
expiry_date=$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/$DOMAIN/cert.pem | cut -d= -f2)
expiry_timestamp=$(date -d "$expiry_date" +%s)
current_timestamp=$(date +%s)
days_until_expiry=$(( ($expiry_timestamp - $current_timestamp) / 86400 ))
# 检查证书链完整性
chain_check=$(openssl verify -CAfile /etc/letsencrypt/live/$DOMAIN/chain.pem /etc/letsencrypt/live/$DOMAIN/cert.pem)
if [ $days_until_expiry -le $EXPIRY_THRESHOLD ]; then
echo "警告: 证书将在 $days_until_expiry 天后过期" | mail -s "SSL 证书警告 - $DOMAIN" $ADMIN_EMAIL
fi
if [[ $chain_check != *"OK"* ]]; then
echo "错误: 证书链验证失败 - $chain_check" | mail -s "SSL 证书链错误 - $DOMAIN" $ADMIN_EMAIL
fi
# 输出状态信息
echo "域名: $DOMAIN"
echo "有效期剩余: $days_until_expiry 天"
echo "证书链检查: $chain_check"
|
🎯 提示:建议定期检查证书状态并测试续签流程。生产环境部署前,请在测试环境充分验证所有配置。
📚 扩展资源:
🔧 维护命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 查看证书状态
sudo certbot certificates
# 测试续签
sudo certbot renew --dry-run
# 清理旧证书
sudo certbot delete --cert-name example.com
# 更新 Certbot
sudo apt update && sudo apt upgrade certbot
# 检查系统定时任务状态
systemctl status cron
crontab -l
# 验证SSL配置
curl -Iv https://your-domain.com
openssl s_client -connect your-domain.com:443 -servername your-domain.com
|
📝 更新日志:
- 2024-01-01: 初始文档创建
- 2024-01-15: 增加DNS验证详细步骤
- 2024-02-01: 补充故障排除和最佳实践
👥 贡献者:
- 感谢 Certbot 开发团队
- 感谢 Let’s Encrypt 提供的免费证书服务
⚠️ 免责声明:
本文档仅供参考,请根据实际环境进行调整。使用SSL证书时请遵守相关法律法规和服务条款。