Nginx 泛域名 SSL 证书申请全攻略:从 DNS 验证到自动续期

Nginx 泛域名 SSL 证书申请全攻略:从 DNS 验证到自动续期

在当今互联网环境中,HTTPS 已成为网站安全的标准配置。对于拥有多个子域名的开发者来说,泛域名 SSL 证书(Wildcard SSL Certificate)无疑是最经济高效的解决方案。本文将深入探讨如何使用 acme.sh 工具为 Nginx 服务器申请泛域名 SSL 证书,并实现自动化续期管理。

1. 准备工作与环境配置

在开始申请 SSL 证书之前,我们需要确保服务器环境满足基本要求。以下是最佳实践建议:

系统要求

  • Linux 服务器(推荐 CentOS 7+/Ubuntu 18.04+)
  • 已安装 Nginx 并正常运行
  • 拥有域名及其 DNS 管理权限
  • 开放 80/443 端口(如使用 HTTP 验证方式)

依赖安装

# 对于基于RPM的系统(如CentOS) sudo yum install -y curl socat # 对于基于Debian的系统(如Ubuntu) sudo apt-get install -y curl socat

acme.sh 安装: 这个轻量级的 ACME 协议客户端是我们申请证书的核心工具:

curl https://get.acme.sh | sh source ~/.bashrc

提示:安装完成后,acme.sh 会自动创建每日定时任务(位于 crontab),用于检查证书是否需要续期。

2. DNS 验证方式申请泛域名证书

泛域名证书的申请必须使用 DNS 验证方式,这是与其他单域名证书申请的主要区别。我们以阿里云 DNS 为例,演示完整流程。

2.1 获取 DNS API 凭证

首先需要在 DNS 服务商处获取 API 密钥:

  1. 登录阿里云控制台
  2. 进入 RAM 访问控制
  3. 创建子账号并授予AliyunDNSFullAccess权限
  4. 获取 AccessKey ID 和 Secret

2.2 配置 DNS API 环境变量

将获取的凭证设置为环境变量:

export Ali_Key="your_access_key_id" export Ali_Secret="your_access_key_secret"

2.3 申请泛域名证书

执行以下命令申请证书(将 example.com 替换为你的域名):

acme.sh --issue --dns dns_ali -d "*.example.com" -d example.com \ --keylength ec-256 \ --dnssleep 60

参数说明

  • --dns dns_ali:指定使用阿里云 DNS 验证
  • -d "*.example.com":申请泛域名证书
  • -d example.com:同时包含根域名
  • --keylength ec-256:使用更安全的 ECC 椭圆曲线加密
  • --dnssleep 60:等待 DNS 记录生效的时间(秒)

2.4 验证 DNS 记录

acme.sh 会自动添加 TXT 记录进行验证。你可以通过以下命令检查 DNS 记录是否生效:

dig -t txt _acme-challenge.example.com @8.8.8.8

3. Nginx 证书部署与配置

成功获取证书后,我们需要将其部署到 Nginx 服务器上。

3.1 证书文件说明

acme.sh 生成的证书位于~/.acme.sh/目录,包含以下关键文件:

  • fullchain.cer:完整证书链
  • example.com.key:私钥文件
  • example.com.conf:证书配置信息

3.2 安装证书到指定目录

建议将证书复制到集中管理的位置:

acme.sh --install-cert -d example.com \ --key-file /etc/nginx/ssl/example.com.key \ --fullchain-file /etc/nginx/ssl/fullchain.cer \ --reloadcmd "systemctl reload nginx"

3.3 Nginx SSL 配置示例

以下是支持 HTTP/2 的安全配置模板:

server { listen 443 ssl http2; server_name example.com *.example.com; ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/example.com.key; # SSL 优化配置 ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305'; ssl_stapling on; ssl_stapling_verify on; # 其他配置... } server { listen 80; server_name example.com *.example.com; return 301 https://$host$request_uri; }

4. 自动化续期与问题排查

4.1 自动续期机制

acme.sh 安装时已自动创建定时任务,可通过以下命令查看:

crontab -l | grep acme.sh

典型输出:

0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

4.2 手动测试续期

可以模拟续期过程检查配置是否正确:

acme.sh --renew -d example.com --force --debug

4.3 常见问题解决

问题1:DNS验证超时

  • 检查 API 密钥是否正确
  • 增加--dnssleep参数值(默认60秒可能不足)
  • 手动验证 DNS 记录是否生效

问题2:证书续期失败

  • 检查证书有效期:acme.sh --list
  • 查看详细日志:tail -f ~/.acme.sh/acme.sh.log
  • 强制更新:acme.sh --renew -d example.com --force

问题3:Nginx 配置错误

  • 测试配置:nginx -t
  • 检查错误日志:tail -f /var/log/nginx/error.log

5. 高级配置与优化

5.1 多域名管理

对于拥有多个泛域名的情况,可以创建批处理脚本:

#!/bin/bash DOMAINS=("domain1.com" "domain2.net" "domain3.org") for domain in "${DOMAINS[@]}"; do acme.sh --issue --dns dns_ali -d "*.$domain" -d "$domain" \ --keylength ec-256 \ --dnssleep 120 done

5.2 OCSP Stapling 优化

在 Nginx 配置中添加以下内容提升 SSL 握手效率:

ssl_trusted_certificate /etc/nginx/ssl/ca.cer; ssl_stapling on; ssl_stapling_verify on;

生成 ca.cer 文件:

curl -s https://letsencrypt.org/certs/trustid-x3-root.pem > /etc/nginx/ssl/ca.cer

5.3 证书监控

添加监控脚本定期检查证书状态:

#!/bin/bash DOMAIN="example.com" DAYS_REMAINING=$(openssl x509 -checkend 86400 -noout -in /etc/nginx/ssl/fullchain.cer | grep -q 'Certificate will expire' && echo "1" || echo "0") if [ "$DAYS_REMAINING" -eq "1" ]; then echo "证书即将过期" | mail -s "证书过期警告" admin@example.com fi

6. 安全最佳实践

  1. 私钥保护

    • 设置严格的文件权限:chmod 600 /etc/nginx/ssl/*.key
    • 定期轮换密钥(每年至少一次)
  2. 加密算法选择

    • 优先使用 ECC 证书(更安全且性能更好)
    • 禁用不安全的协议(SSLv3, TLSv1.0, TLSv1.1)
  3. 证书透明度

    • 启用 Expect-CT 头:add_header Expect-CT "enforce, max-age=86400";
    • 配置 Certificate Transparency:add_header Expect-CT "max-age=86400, enforce, report-uri='https://example.com/report'"
  4. HSTS 增强安全

    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";

通过本文的详细指导,你应该已经掌握了从申请泛域名 SSL 证书到自动化续期的完整流程。实际部署中,建议先在测试环境验证所有步骤,再应用到生产环境。随着技术的不断演进,定期回顾和更新你的 SSL/TLS 配置也是确保网站长期安全运行的关键。