SSL证书管理手册

📋 概述

本手册介绍如何使用 acme.sh 和阿里云 DNS API 为 Husky 系统申请和管理 Let’s Encrypt 免费SSL证书。

🎯 特性

  • ✅ 免费SSL证书(Let’s Encrypt)
  • ✅ 自动DNS验证(阿里云DNS API)
  • ✅ 自动证书续期(90天自动续期)
  • ✅ 支持通配符域名(如 *.example.com
  • ✅ 统一证书管理
  • ✅ 邮箱通知:@i-husky.com"">Husky001@i-husky.com

🚀 快速开始

1. 准备工作

获取阿里云 API 密钥

  1. 登录阿里云控制台
  2. 访问 RAM 访问控制: https://ram.console.aliyun.com/manage/ak
  3. 创建 AccessKey(需要有DNS管理权限)
  4. 记录 Access Key IDAccess Key Secret

确保域名在阿里云

  • 域名必须在阿里云DNS管理
  • 或使用阿里云DNS服务解析

2. 配置系统

编辑配置文件

编辑 etc/config_default.xml

<nginx>
    <!-- SSL证书模式: self-signed(自签名) 或 acme(Let's Encrypt) -->
    <ssl_mode>acme</ssl_mode>

    <!-- SSL证书域名(支持通配符)-->
    <ssl_domain>www.example.com</ssl_domain>

    <!-- SSL证书邮箱 -->
    <ssl_email>Husky001@i-husky.com</ssl_email>
</nginx>

3. 申请证书

方式1:使用管理脚本(推荐)

# 1. 设置阿里云API密钥
./sbin/acme_ssl_manager.sh set-aliyun-key

# 2. 安装acme.sh
./sbin/acme_ssl_manager.sh install

# 3. 申请证书(单域名)
./sbin/acme_ssl_manager.sh issue www.example.com

# 4. 申请通配符证书
./sbin/acme_ssl_manager.sh issue "*.example.com"

# 5. 安装证书到Nginx
./sbin/acme_ssl_manager.sh install-cert www.example.com

方式2:使用Python部署脚本

# 1. 部署Nginx(会提示配置ACME)
python sbin/deploy.py nginx install

# 2. 按提示设置API密钥和申请证书
./sbin/acme_ssl_manager.sh set-aliyun-key
./sbin/acme_ssl_manager.sh issue www.example.com

# 3. 使用Python接口申请证书
python sbin/deploy.py nginx issue_acme_cert

# 4. 安装证书
python sbin/deploy.py nginx install_acme_cert

📖 详细使用说明

acme_ssl_manager.sh 命令参考

安装和配置

# 安装acme.sh
./sbin/acme_ssl_manager.sh install

# 设置阿里云API密钥(交互式)
./sbin/acme_ssl_manager.sh set-aliyun-key

# 检查环境变量
./sbin/acme_ssl_manager.sh check-env

证书申请

# 申请单域名证书
./sbin/acme_ssl_manager.sh issue www.example.com

# 申请通配符证书
./sbin/acme_ssl_manager.sh issue "*.example.com"

# 申请多域名证书
./sbin/acme_ssl_manager.sh issue "example.com *.example.com"

证书管理

# 列出所有证书
./sbin/acme_ssl_manager.sh list

# 查看证书详情
./sbin/acme_ssl_manager.sh info www.example.com

# 手动续期证书
./sbin/acme_ssl_manager.sh renew www.example.com

# 续期所有证书
./sbin/acme_ssl_manager.sh renew-all

# 删除证书
./sbin/acme_ssl_manager.sh remove www.example.com

证书安装

# 安装证书到Nginx
./sbin/acme_ssl_manager.sh install-cert www.example.com

# 证书会安装到:
# - share/nginx/common_nginx/conf/security/server.crt
# - share/nginx/common_nginx/conf/security/server.key
# - share/nginx/common_nginx/conf/security/fullchain.crt

Python 部署接口

# 申请ACME证书
python sbin/deploy.py nginx issue_acme_cert

# 安装ACME证书
python sbin/deploy.py nginx install_acme_cert

# 续期ACME证书
python sbin/deploy.py nginx renew_acme_cert

# 列出ACME证书
python sbin/deploy.py nginx list_acme_certs

# 重新加载Nginx
python sbin/deploy.py nginx reload

🔄 自动续期配置

acme.sh 自动续期

acme.sh 安装后会自动添加 cron 任务,每天检查并续期即将过期的证书:

# 查看cron任务
crontab -l | grep acme

# 手动触发续期检查
~/.acme.sh/acme.sh --cron

使用提供的续期脚本

# 手动执行续期脚本
./sbin/acme_auto_renew.sh

# 添加到crontab(每天凌晨3点执行)
crontab -e

# 添加以下行
0 3 * * * /home/husky/sbin/acme_auto_renew.sh >> /home/husky/logs/acme_renew.log 2>&1

续期日志

续期日志位置:

  • acme.sh日志:~/.acme.sh/logs/renew_YYYYMMDD.log
  • cron日志:~/logs/acme_renew.log

📁 文件和目录结构

acme.sh 文件

~/.acme.sh/
├── acme.sh                    # acme.sh主程序
├── account.conf               # API密钥配置
├── ca/                        # CA证书
├── www.example.com/           # 域名证书目录
│   ├── www.example.com.cer   # 证书文件
│   ├── www.example.com.key   # 私钥文件
│   ├── ca.cer                # CA证书
│   └── fullchain.cer         # 完整证书链
└── logs/                      # 续期日志
    └── renew_YYYYMMDD.log

Nginx 证书目录

share/nginx/common_nginx/conf/security/
├── server.crt       # Nginx使用的证书
├── server.key       # Nginx使用的私钥
└── fullchain.crt    # 完整证书链

🔧 配置说明

阿里云 API 密钥配置

方式1:环境变量(推荐)

# 添加到 ~/.bashrc 或 ~/.profile
export Ali_Key="your_access_key_id"
export Ali_Secret="your_access_key_secret"

# 使配置生效
source ~/.bashrc

方式2:配置文件

# 自动保存到 ~/.acme.sh/account.conf
./sbin/acme_ssl_manager.sh set-aliyun-key

Nginx SSL 配置

编辑 etc/nginx_https_default.conf

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate #crtFile#;           # server.crt
    ssl_certificate_key #keyFile#;       # server.key
    ssl_session_timeout 5m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
    ssl_prefer_server_ciphers on;

    # 其他配置...
}

🔍 故障排查

证书申请失败

1. 检查DNS解析

# 检查域名解析
nslookup www.example.com

# 检查TXT记录(DNS验证时)
nslookup -type=TXT _acme-challenge.www.example.com

2. 检查阿里云API密钥

# 检查环境变量
./sbin/acme_ssl_manager.sh check-env

# 测试API密钥
aliyun alidns DescribeDomains

3. 查看详细日志

# 查看acme.sh日志
tail -f ~/.acme.sh/acme.sh.log

# 启用调试模式
~/.acme.sh/acme.sh --issue --dns dns_ali -d www.example.com --debug 2

常见错误

错误1:API密钥未配置

错误: 阿里云API密钥未设置

解决方法:

./sbin/acme_ssl_manager.sh set-aliyun-key

错误2:域名DNS未在阿里云

错误: The domain 'example.com' does not exist in your account

解决方法:

  • 确保域名在阿里云DNS管理
  • 或迁移域名DNS到阿里云

错误3:TXT记录验证失败

错误: Verification failed

解决方法:

  • 等待DNS记录生效(最多10分钟)
  • 检查防火墙设置
  • 使用 --debug 2 查看详细信息

错误4:证书已存在

错误: Domain 'www.example.com' already has a cert

解决方法:

# 强制重新申请
~/.acme.sh/acme.sh --issue --dns dns_ali -d www.example.com --force

证书续期失败

# 查看续期日志
tail -f ~/.acme.sh/logs/renew_$(date +%Y%m%d).log

# 手动触发续期
~/.acme.sh/acme.sh --renew -d www.example.com --force

# 重新安装证书
./sbin/acme_ssl_manager.sh install-cert www.example.com

Nginx加载证书失败

# 检查证书文件权限
ls -l share/nginx/common_nginx/conf/security/

# 检查证书有效性
openssl x509 -in share/nginx/common_nginx/conf/security/server.crt -noout -text

# 测试Nginx配置
sudo nginx -t

# 重新加载Nginx
sudo systemctl reload nginx

💡 最佳实践

1. 使用通配符证书

# 申请通配符证书(覆盖所有子域名)
./sbin/acme_ssl_manager.sh issue "*.example.com"

# 同时支持根域名和通配符
./sbin/acme_ssl_manager.sh issue "example.com *.example.com"

优点:

  • 一个证书覆盖所有子域名
  • 减少证书管理复杂度
  • 节省续期时间

2. 定期检查证书状态

# 列出所有证书及过期时间
./sbin/acme_ssl_manager.sh list

# 查看特定证书信息
./sbin/acme_ssl_manager.sh info www.example.com

3. 备份证书

# 备份acme.sh目录
tar czf acme_backup_$(date +%Y%m%d).tar.gz ~/.acme.sh

# 备份Nginx证书
tar czf nginx_cert_backup_$(date +%Y%m%d).tar.gz share/nginx/common_nginx/conf/security/

4. 监控续期

# 添加续期监控脚本
cat > ~/check_cert_expiry.sh << 'EOF'
#!/bin/bash
CERT_FILE="/home/husky/share/nginx/common_nginx/conf/security/server.crt"
DAYS_WARNING=30

if [ -f "$CERT_FILE" ]; then
    EXPIRY_DATE=$(openssl x509 -in "$CERT_FILE" -noout -enddate | cut -d= -f2)
    EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
    NOW_EPOCH=$(date +%s)
    DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

    if [ $DAYS_LEFT -lt $DAYS_WARNING ]; then
        echo "警告: SSL证书将在 $DAYS_LEFT 天后过期!"
        echo "证书: $CERT_FILE"
        echo "过期时间: $EXPIRY_DATE"
    fi
fi
EOF

chmod +x ~/check_cert_expiry.sh

# 添加到crontab(每天检查)
0 9 * * * ~/check_cert_expiry.sh | mail -s "SSL证书过期提醒" Husky001@i-husky.com

5. 多环境管理

# 开发环境使用自签名证书
# etc/config_default.xml
<ssl_mode>self-signed</ssl_mode>

# 生产环境使用ACME证书
<ssl_mode>acme</ssl_mode>
<ssl_domain>www.production.com</ssl_domain>

🔐 安全建议

1. 保护API密钥

# 设置配置文件权限
chmod 600 ~/.acme.sh/account.conf

# 不要将API密钥提交到Git
echo ".acme.sh/" >> .gitignore

2. 使用强加密

在 Nginx 配置中使用:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

3. 启用 HSTS

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

4. 定期审计

# 检查证书强度
testssl.sh www.example.com

# 使用SSL Labs测试
# https://www.ssllabs.com/ssltest/

📊 证书信息

Let’s Encrypt 限制

  • 每周每个域名最多申请 50 个证书
  • 每个证书最多包含 100 个域名
  • 证书有效期 90 天
  • 自动续期在到期前 30 天开始

通配符证书

  • 必须使用DNS验证
  • 支持 *.example.com 格式
  • 不包含根域名(需单独添加)

📞 技术支持

相关资源

遇到问题?

  1. 查看日志:~/.acme.sh/acme.sh.log
  2. 查看续期日志:~/.acme.sh/logs/
  3. 启用调试模式:--debug 2
  4. 联系开发团队

📚 相关文档

作者:聂盼盼  创建时间:2025-10-28 20:39
最后编辑:聂盼盼  更新时间:2025-10-28 20:39