05月27, 2025

如何为多个域名创建自动更新 Nginx SSL 证书的 Shell 脚本

如何为多个域名创建自动更新 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

脚本特点

  1. 支持多域名
    • certbot renew 自动处理所有已配置的证书,无需为每个域名单独调用。
  2. 域名配置文件
    • 支持读取 /etc/letsencrypt/domains.txt,便于管理域名列表(可选)。
  3. 错误处理
    • 检查 root 权限、Certbot 和 Nginx 可用性。
    • 验证 Nginx 配置(nginx -t)并记录日志。
  4. 日志记录
    • 所有操作记录在 /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
  • 端口要求
    • 确保 80 端口开放(用于 HTTP-01 验证):
      sudo firewall-cmd --add-port=80/tcp --permanent
      sudo firewall-cmd --reload
  • DNS 配置
    • 确保所有域名解析到服务器 IP(用 dig example.com 检查)。
  • 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;
          ...
      }

验证步骤

  1. 检查证书
    ls /etc/letsencrypt/live/
    openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates
  2. 测试 HTTPS
    curl -I https://example.com
    curl -I https://example2.com
  3. 测试续订
    sudo certbot renew --dry-run

排查问题

  • 插件问题
    • 确认 Nginx 插件已安装:
      certbot plugins
      应看到 nginx 插件。
  • 日志检查
    • 查看 /var/log/letsencrypt/letsencrypt.log/var/log/cert_renew.log 获取错误详情。

总结

通过上述 shell 脚本,你可以轻松实现多个域名的 Nginx SSL 证书自动续订。脚本简单高效,支持动态域名管理,并确保 Nginx 配置正确。

本文链接:https://587v5.com/post/ru-he-wei-duo-ge-yu-ming-chuang-jian-zi-dong-geng-xin- Nginx SSL zheng-shu-de- Shell jiao-ben.html

Comments