在 CentOS 服务器上自动申请和更新多域名 SSL 证书

本文将介绍如何使用 Shell 脚本自动化管理多个域名的 SSL 证书,包括申请、安装和自动更新。

背景

在运维工作中,经常需要为多个域名申请和更新 SSL 证书。手动操作不仅繁琐,还容易出错。通过脚本自动化这个过程,可以大大提高工作效率。

实现方案

我们使用 Let’s Encrypt 提供的免费证书服务,结合 certbot 工具来实现证书的申请和更新。脚本支持同时处理多个域名,并设置自动更新任务。

1. 完整脚本

#!/bin/bash

# 基础配置
EMAIL="your-email@example.com"    # 替换为您的邮箱
CERT_PATH="/etc/nginx/cert"  # nginx证书固定目录
WEBROOT_PATH="/usr/share/nginx/html"  # nginx默认网站目录
LOG_FILE="/var/log/cert-renewal.log"

# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a $LOG_FILE
}

# 检查参数
if [ $# -eq 0 ]; then
    echo "使用方法: $0 domain1.com [domain2.com ...]"
    echo "示例: $0 api.example.com2 api.example.com"
    exit 1
fi

# 检查是否以 root 权限运行
if [ "$EUID" -ne 0 ]; then 
    log "请使用 root 权限运行此脚本"
    exit 1
fi

# 确保目录存在
mkdir -p $CERT_PATH
mkdir -p $WEBROOT_PATH

# 安装必要的软件包
log "检查并安装必要的软件包..."
yum install -y epel-release
yum install -y certbot python3-certbot-nginx

# 处理每个域名
for DOMAIN in "$@"; do
    log "开始处理域名: $DOMAIN"
    
    # 申请证书
    log "开始申请 Let's Encrypt 证书..."
    certbot certonly --webroot \
        --webroot-path $WEBROOT_PATH \
        --agree-tos \
        --email $EMAIL \
        -d $DOMAIN
    
    # 检查证书是否申请成功
    if [ $? -eq 0 ]; then
        log "证书申请成功: $DOMAIN"
        
        # 复制证书到nginx证书目录
        cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $CERT_PATH/$DOMAIN.pem
        cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $CERT_PATH/$DOMAIN.key
        
        # 设置正确的权限
        chown -R nginx:nginx $CERT_PATH
        chmod 600 $CERT_PATH/$DOMAIN.key
        chmod 644 $CERT_PATH/$DOMAIN.pem
        
        log "证书已复制到Nginx目录:$CERT_PATH/$DOMAIN.pem"
    else
        log "证书申请失败: $DOMAIN"
        continue
    fi
done

# 创建统一的证书更新脚本
cat > /usr/local/bin/renew-cert.sh << 'EOF'
#!/bin/bash
CERT_PATH="/etc/nginx/cert"
WEBROOT_PATH="/usr/share/nginx/html"

# 更新所有证书
certbot renew --webroot --webroot-path $WEBROOT_PATH --quiet

# 更新成功后,复制所有证书到nginx目录
for CERT_DIR in /etc/letsencrypt/live/*; do
    if [ -d "$CERT_DIR" ]; then
        DOMAIN=$(basename "$CERT_DIR")
        cp "$CERT_DIR/fullchain.pem" "$CERT_PATH/$DOMAIN.pem"
        cp "$CERT_DIR/privkey.pem" "$CERT_PATH/$DOMAIN.key"
        chown nginx:nginx "$CERT_PATH/$DOMAIN.pem" "$CERT_PATH/$DOMAIN.key"
        chmod 600 "$CERT_PATH/$DOMAIN.key"
        chmod 644 "$CERT_PATH/$DOMAIN.pem"
    fi
done

# 重新加载nginx配置
nginx -s reload
EOF

# 设置更新脚本权限
chmod +x /usr/local/bin/renew-cert.sh

# 添加定时任务
(crontab -l 2>/dev/null | grep -v renew-cert.sh; echo "0 2 1 * * /usr/local/bin/renew-cert.sh") | crontab -

log "证书自动更新任务已设置"
log "所有证书位于: $CERT_PATH/"
log "下次更新时间: 下月1号凌晨2点"

# 重新加载nginx配置
nginx -s reload

2. 主要功能

  • 支持同时处理多个域名的证书申请
  • 自动安装必要的软件包
  • 统一管理证书存储位置
  • 自动设置证书更新任务
  • 详细的操作日志记录
  • 适当的错误处理机制

3. 使用方法

# 处理单个域名
./ssl-cert.sh domain.com

# 处理多个域名
./ssl-cert.sh domain1.com domain2.com domain3.com

常见问题及解决方案

1. 换行符问题

https.sh: line 2: $'\r': command not found

这是因为脚本在 Windows 系统编辑后传到 Linux 服务器导致的换行符问题。

解决方法:

# 方法一:安装并使用 dos2unix
yum install -y dos2unix
dos2unix ssl-cert.sh

# 方法二:使用 sed 命令
sed -i 's/\r//' ssl-cert.sh

2. 证书验证失败

错误信息:

Challenge failed for domain domain.com
Type: unauthorized
Detail: Invalid response from http://domain.com/.well-known/acme-challenge/

解决步骤:

  1. 配置 Nginx
server {
    listen 80;
    server_name domain.com;
    
    # 添加证书验证路径
    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;
    }
}
  1. 检查目录权限
mkdir -p /usr/share/nginx/html/.well-known/acme-challenge
chown -R nginx:nginx /usr/share/nginx/html
chmod -R 755 /usr/share/nginx/html
  1. 验证配置
# 测试 nginx 配置
nginx -t
nginx -s reload

# 测试验证路径
echo "test" > /usr/share/nginx/html/.well-known/acme-challenge/test.txt
curl http://domain.com/.well-known/acme-challenge/test.txt

3. 防火墙设置

确保服务器的 80 端口对外开放:

firewall-cmd --permanent --add-service=http
firewall-cmd --reload

注意事项

  1. 运行脚本前确保域名已正确解析到服务器
  2. 确保服务器的 80 端口可以正常访问
  3. 证书文件统一存放在 /etc/nginx/cert 目录下
  4. 自动更新任务默认在每月 1 号凌晨 2 点执行

维护建议

  1. 定期检查证书状态
certbot certificates
  1. 检查自动更新任务
crontab -l | grep renew-cert
  1. 查看更新日志
tail -f /var/log/cert-renewal.log

总结

通过这个自动化脚本,我们可以轻松管理多个域名的 SSL 证书,大大减少了手动操作的工作量和出错风险。脚本的模块化设计也使得维护和故障排查变得更加容易。

对于那些管理多个网站和域名的运维人员来说,这个脚本可以显著提高工作效率。通过及时处理常见错误,我们可以确保证书申请和更新过程的顺利进行。

希望这个工具和相关经验分享对大家有所帮助。如果有任何问题或建议,欢迎在评论区讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周小码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值