Files
2026-07-21 14:53:24 +08:00

6.6 KiB
Raw Permalink Blame History

acme.sh SSL 证书管理指南

服务器环境:Ubuntu + Nginx 1.18.0 + acme.sh v3.1.3
本文档基于当前服务器真实操作记录整理,所有命令均可直接复用。


1. acme.sh 基本信息

安装路径: /root/.acme.sh
配置文件: /root/.acme.sh/account.conf
证书目录: /root/.acme.sh/<域名>_ecc/

2. 签发方式:Webroot 模式

本服务器使用 webroot 模式验证域名所有权。acme.sh 会在网站根目录下生成一个临时验证文件,CA 通过 HTTP 访问该文件来确认你拥有该域名。

优点:不需要 DNS API,不需要停 Nginx,适合已有运行中网站的场景。

前提:

  • 域名已解析到服务器 IP
  • Nginx 能正常响应 HTTP 请求
  • 网站根目录可写入(acme.sh 会在 .well-known/acme-challenge/ 下创建临时文件)

3. 实际案例

案例一:china-planet.com + www.china-planet.com

签发命令(ZeroSSL):

/root/.acme.sh/acme.sh --issue \
  -d china-planet.com \
  -d www.china-planet.com \
  -w /mnt/data/www \
  --keylength ec-256

参数说明:

参数 含义
-d china-planet.com 主域名
-d www.china-planet.com 附加域名(SAN,一张证书覆盖多个域名)
-w /mnt/data/www webroot 目录,acme.sh 在此目录下创建验证文件
--keylength ec-256 使用 ECC 密钥(EC secp256r1),比 RSA 更快更安全

CA 选择:未指定 --server,默认使用 ZeroSSL(acme.sh v3+ 的默认 CA)。

安装证书到 Nginx:

mkdir -p /etc/nginx/ssl/china-planet.com

/root/.acme.sh/acme.sh --install-cert -d china-planet.com --ecc \
  --key-file       /etc/nginx/ssl/china-planet.com/key.pem \
  --fullchain-file /etc/nginx/ssl/china-planet.com/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"
参数 含义
--ecc 指定 ECC 密钥类型的证书目录
--key-file 私钥安装路径
--fullchain-file 证书链安装路径(证书 + 中间证书)
--reloadcmd 证书安装/续期后执行的命令

案例二:git.china-planet.com

签发命令(Let's Encrypt):

/root/.acme.sh/acme.sh --issue \
  -d git.china-planet.com \
  -w /mnt/data/www \
  --keylength ec-256 \
  --server letsencrypt

为什么换了 Let's Encrypt?

  • 首选用 ZeroSSL 签发,但遇到 retryafter=86400 错误(CA 要求等 24 小时重试)
  • ZeroSSL 的验证服务器可能存在网络延迟或频率限制
  • 换成 Let's Encrypt 后立即成功,验证速度很快

遇到的坑:Nginx 反向代理拦截验证请求

git.china-planet.com 的 Nginx 配置将所有请求反向代理到 Gitea(proxy_pass http://127.0.0.1:3000),导致 acme.sh 的验证文件无法被外部访问。解决方法是给 Nginx 添加一个静态文件 location:

location ^~ /.well-known/acme-challenge/ {
    root /mnt/data/www;
}

完整配置参考:

server {
    listen 80;
    listen [::]:80;
    server_name git.china-planet.com;

    # 必须:让 acme 验证文件走静态文件,不走反向代理
    location ^~ /.well-known/acme-challenge/ {
        root /mnt/data/www;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

记住:任何做了全路径反向代理的子域名,都必须加上这个 location ^~ /.well-known/acme-challenge/ 块,否则证书无法签发和续期。

安装证书:

mkdir -p /etc/nginx/ssl/git.china-planet.com

/root/.acme.sh/acme.sh --install-cert -d git.china-planet.com --ecc \
  --key-file       /etc/nginx/ssl/git.china-planet.com/key.pem \
  --fullchain-file /etc/nginx/ssl/git.china-planet.com/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

4. 自动续期

acme.sh 安装时会自动添加 cron 任务。当前服务器配置:

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

每天 23:27 执行,acme.sh 会检查所有证书,在到期前 30 天 自动续期。续期后会自动执行 --reloadcmd(即 systemctl reload nginx)。

手动检查续期:

/root/.acme.sh/acme.sh --cron --home /root/.acme.sh

查看所有证书状态:

/root/.acme.sh/acme.sh --list

5. CA 选择:ZeroSSL vs Let's Encrypt

对比 ZeroSSL Let's Encrypt
默认 acme.sh v3+ 默认 需 --server letsencrypt
速率限制 较严格(遇到过 24h 冷却) 较宽松
证书兼容性 好 极好(几乎所有客户端信任)
通配符 支持(需 DNS 验证) 支持(需 DNS 验证)
ECC 支持 ✅ ✅

建议:日常用 ZeroSSL 就行(acme.sh 默认),遇到验证失败换 Let's Encrypt。


6. 添加新子域名速查

假设新增 docs.china-planet.com:

# 1. 确保 DNS 已解析
dig +short docs.china-planet.com

# 2. 签发证书
/root/.acme.sh/acme.sh --issue \
  -d docs.china-planet.com \
  -w /mnt/data/www \
  --keylength ec-256

# 3. 安装证书
mkdir -p /etc/nginx/ssl/docs.china-planet.com
/root/.acme.sh/acme.sh --install-cert -d docs.china-planet.com --ecc \
  --key-file       /etc/nginx/ssl/docs.china-planet.com/key.pem \
  --fullchain-file /etc/nginx/ssl/docs.china-planet.com/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

# 4. 配置 Nginx,记得加 acme-challenge location
# 5. nginx -t && systemctl reload nginx

7. 故障排查

验证超时 / retryafter

# 先确认验证文件可访问
curl http://你的域名/.well-known/acme-challenge/test

# 如果 404,检查:
# - 反向代理是否拦截了 .well-known 路径
# - webroot 目录是否正确
# - 是否有防火墙拦截

# 换 CA 重试
--server letsencrypt

查看详细日志

/root/.acme.sh/acme.sh --issue ... --debug 2

强制续期

/root/.acme.sh/acme.sh --renew -d 你的域名 --ecc --force

8. 证书目录结构总览

/etc/nginx/ssl/
├── china-planet.com/
│   ├── key.pem          # 私钥
│   └── fullchain.pem    # 证书 + 中间证书
└── git.china-planet.com/
    ├── key.pem
    └── fullchain.pem

Nginx 引用:

ssl_certificate     /etc/nginx/ssl/xxx/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/xxx/key.pem;

最后更新:2026-07-03 · 基于真实操作记录