# 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): ```bash /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**: ```bash 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): ```bash /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: ```nginx location ^~ /.well-known/acme-challenge/ { root /mnt/data/www; } ``` 完整配置参考: ```nginx 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/` 块,否则证书无法签发和续期。 **安装证书**: ```bash 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`)。 **手动检查续期**: ```bash /root/.acme.sh/acme.sh --cron --home /root/.acme.sh ``` **查看所有证书状态**: ```bash /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`: ```bash # 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 ```bash # 先确认验证文件可访问 curl http://你的域名/.well-known/acme-challenge/test # 如果 404,检查: # - 反向代理是否拦截了 .well-known 路径 # - webroot 目录是否正确 # - 是否有防火墙拦截 # 换 CA 重试 --server letsencrypt ``` ### 查看详细日志 ```bash /root/.acme.sh/acme.sh --issue ... --debug 2 ``` ### 强制续期 ```bash /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 引用: ```nginx ssl_certificate /etc/nginx/ssl/xxx/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/xxx/key.pem; ``` --- *最后更新:2026-07-03 · 基于真实操作记录*