如何为多个域名创建自动更新 Nginx SSL 证书的 Shell 脚本
在管理多个域名时,自动化续订 SSL/TLS 证书是确保网站安全性和 HTTPS 正常运行的关键。本文介绍如何编写一个 Bash shell 脚本,使用 Certbot 自动续订多个域名的 Nginx SSL 证书,适用于 CentOS、Ubuntu 等 Linux 系统。本脚本支持动态处理多个域名,自动验证 Nginx 配置,并记录日志以便排查问题。
为什么需要自动续订 SSL 证书?
Let's Encrypt 提供的免费 SSL 证书有效期为 90 天,需定期续订。手动管理多个域名的证书续订费时且易出错。使用 shell 脚本结合 Certbot 和 Nginx,可以:
- 自动检查和续订即将到期的证书。
- 动态支持多个域名。
- 确保 Nginx 配置正确并重载服务。
- 记录操作日志,便于调试。
自动续订脚本
以下是一个为多个域名设计的 Bash 脚本,用于自动续订 Nginx 的 SSL 证书。
#!/bin/bash
# 检查是否以 root 权限运行
if [ "$EUID" -ne 0 ]; then
echo "请以 root 权限运行此脚本"
exit 1
fi
# 定义变量
CERTBOT=/usr/bin/certbot
NGINX=/usr/sbin/nginx
LOG_FILE=/var/log/cert_renew.log
EMAIL="your-email@example.com" # 替换为你的邮箱
DOMAINS_FILE="/etc/letsencrypt/domains.txt" # 域名配置文件路径(可选)
# 创建日志文件(如果不存在)
touch $LOG_FILE
chmod 644 $LOG_FILE
# 记录开始时间
echo "[$(date)] 开始证书更新检查" >> $LOG_FILE
# 检查 certbot 是否存在
if [ ! -f "$CERTBOT" ]; then
echo "[$(date)] 错误:未找到 certbot" >> $LOG_FILE
exit 1
fi
# 检查 nginx 是否存在
if [ ! -f "$NGINX" ]; then
echo "[$(date)] 错误:未找到 nginx" >> $LOG_FILE
exit 1
fi
# 检查域名配置文件(可选)
if [ -f "$DOMAINS_FILE" ]; then
echo "[$(date)] 找到域名配置文件:$DOMAINS_FILE" >> $LOG_FILE
DOMAINS=$(cat $DOMAINS_FILE | tr '\n' ' ')
else
echo "[$(date)] 警告:未找到域名配置文件,将续订所有证书" >> $LOG_FILE
DOMAINS=""
fi
# 执行证书续订(续订所有证书,忽略 DOMAINS_FILE)
$CERTBOT renew --quiet --nginx --agree-tos --email $EMAIL --no-eff-email \
--post-hook "$NGINX -s reload" >> $LOG_FILE 2>&1
# 检查续订结果
if [ $? -eq 0 ]; then
echo "[$(date)] 所有证书续订成功,Nginx 已重新加载" >> $LOG_FILE
else
echo "[$(date)] 证书续订失败,请检查日志 $LOG_FILE" >> $LOG_FILE
exit 1
fi
# 检查 Nginx 配置
$NGINX -t >> $LOG_FILE 2>&1
if [ $? -eq 0 ]; then
echo "[$(date)] Nginx 配置检查通过" >> $LOG_FILE
else
echo "[$(date)] Nginx 配置检查失败,请检查配置" >> $LOG_FILE
exit 1
fi
使用方法
1. 保存脚本
将上述脚本保存为 renew_nginx_cert.sh
,并添加执行权限:
chmod +x renew_nginx_cert.sh
2. 配置邮箱
修改脚本中的 EMAIL="your-email@example.com"
为你的实际邮箱地址,用于接收 Let's Encrypt 的通知。
3. (可选)创建域名配置文件
如果需要记录或动态管理域名列表,创建 /etc/letsencrypt/domains.txt
文件,每行一个域名。例如:
echo -e "example.com\nwww.example.com\nexample2.com\nwww.example2.com" | sudo tee /etc/letsencrypt/domains.txt
注意:脚本中的 certbot renew
命令会自动处理所有已配置的证书(/etc/letsencrypt/live/
),因此 domains.txt
主要用于文档化或初始申请。
4. 测试脚本
运行脚本以测试续订流程:
sudo ./renew_nginx_cert.sh
检查日志:
cat /var/log/cert_renew.log
预期输出:类似 [2025-05-26 18:56:00] 所有证书续订成功,Nginx 已重新加载
。
5. 设置定时任务
通过 cron 实现每天自动运行:
sudo crontab -e
添加以下内容(每天凌晨 3 点运行):
0 3 * * * /path/to/renew_nginx_cert.sh
首次申请多个域名的证书
如果尚未为域名申请证书,使用以下命令首次申请:
sudo certbot --nginx -d example.com -d www.example.com -d example2.com -d www.example2.com --email your-email@example.com --agree-tos --no-eff-email
-d
参数列出所有域名,多个域名用-d
分隔。- Certbot 会为域名分组生成证书(可能每个顶级域名一个证书目录,如
/etc/letsencrypt/live/example.com/
和/etc/letsencrypt/live/example2.com/
)。 - Nginx 配置会自动更新,添加 SSL 支持。
使用域名配置文件(可选):
DOMAINS=$(tr '\n' ' ' < /etc/letsencrypt/domains.txt)
sudo certbot --nginx $DOMAINS --email your-email@example.com --agree-tos --no-eff-email
脚本特点
- 支持多域名:
certbot renew
自动处理所有已配置的证书,无需为每个域名单独调用。
- 域名配置文件:
- 支持读取
/etc/letsencrypt/domains.txt
,便于管理域名列表(可选)。
- 支持读取
- 错误处理:
- 检查 root 权限、Certbot 和 Nginx 可用性。
- 验证 Nginx 配置(
nginx -t
)并记录日志。
- 日志记录:
- 所有操作记录在
/var/log/cert_renew.log
,便于排查问题。
- 所有操作记录在
注意事项
- CentOS 7 环境(基于你的系统信息):
- CentOS 7 已于 2024 年 6 月 30 日停止支持,推荐使用
certbot-auto
安装 Certbot 和 Nginx 插件:curl -O https://dl.eff.org/certbot-auto sudo mv certbot-auto /usr/local/bin/ sudo /usr/local/bin/certbot-auto --nginx
- 或者通过
pip
安装:sudo yum install python36 python36-pip scl enable rh-python36 bash sudo pip3 install certbot certbot-nginx
- CentOS 7 已于 2024 年 6 月 30 日停止支持,推荐使用
- 端口要求:
- 确保 80 端口开放(用于 HTTP-01 验证):
sudo firewall-cmd --add-port=80/tcp --permanent sudo firewall-cmd --reload
- 确保 80 端口开放(用于 HTTP-01 验证):
- DNS 配置:
- 确保所有域名解析到服务器 IP(用
dig example.com
检查)。
- 确保所有域名解析到服务器 IP(用
- Nginx 配置:
- 确保证书路径正确,例如:
server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ... } server { listen 443 ssl; server_name example2.com www.example2.com; ssl_certificate /etc/letsencrypt/live/example2.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example2.com/privkey.pem; ... }
- 确保证书路径正确,例如:
验证步骤
- 检查证书:
ls /etc/letsencrypt/live/ openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates
- 测试 HTTPS:
curl -I https://example.com curl -I https://example2.com
- 测试续订:
sudo certbot renew --dry-run
排查问题
- 插件问题:
- 确认 Nginx 插件已安装:
应看到certbot plugins
nginx
插件。
- 确认 Nginx 插件已安装:
- 日志检查:
- 查看
/var/log/letsencrypt/letsencrypt.log
和/var/log/cert_renew.log
获取错误详情。
- 查看
总结
通过上述 shell 脚本,你可以轻松实现多个域名的 Nginx SSL 证书自动续订。脚本简单高效,支持动态域名管理,并确保 Nginx 配置正确。
Comments