本文是一份面向 Debian / Ubuntu 的 acme.sh 实战指南,重点讲清楚如何安装、签发证书、安装到 Nginx、自动续期、DNS 验证,以及常见故障排查。目标不是“会跑一次命令”,而是能在真实服务器上稳定长期使用。
适用场景
- 给网站签发免费的 Let’s Encrypt 证书
- 给多个域名或泛域名签证书
- 与 Nginx / Apache 集成
- 通过 DNS API 完成自动化签发
- 自动续期并在证书更新后执行重载动作
acme.sh 是什么
acme.sh 是一个纯 shell 编写的 ACME 客户端,用于自动申请和续期 TLS 证书。它的核心特点是:
- 纯 shell 实现,依赖少
- 支持 webroot、standalone、tls-alpn、DNS API 等多种验证方式
- 支持单域名、多域名和泛域名证书
- 安装后可自动建立定时续期任务
安装前准备
先确认:
- 你的系统有 curl 或 wget
- 你有可用的 shell 环境
- 如果使用 webroot,你已经有 Nginx 或 Apache 在运行
- 如果使用 standalone,80/443 端口未被占用
- 如果使用 DNS 验证,你有对应 DNS 服务商的 API 权限
安装 acme.sh
官方推荐方式之一是通过安装脚本:
curl https://get.acme.sh | sh -s email=you@example.com也可以用 wget:
wget -O - https://get.acme.sh | sh -s email=you@example.com安装完成后,程序通常会被放到:
~/.acme.sh/如果你是从 Git 仓库安装:
git clone https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m you@example.com安装结果通常会做什么
- 把 acme.sh 复制到用户家目录
- 创建一个命令别名或软链接
- 设置定时任务,用于自动续期
安装后可以查看帮助:
acme.sh -h基本概念
证书申请流程
ACME 的流程本质上是:
- 证明你控制了域名
- CA 验证完成
- CA 签发证书
- 你把证书安装到 Web 服务或应用里
- 到期前自动续期
常见验证方式
- webroot:最适合已有 Nginx/Apache 的站点
- standalone:由 acme.sh 自己监听 80 端口验证
- tls-alpn:通过 443 端口验证
- dns:通过 DNS TXT 记录验证,适合泛域名
选择验证方式
1. Webroot 模式
如果你已经有 Nginx 正在运行,这是最常见的方式。
特点:
- 不需要停掉现有 Web 服务
- 只需要写入站点根目录
- 适合普通单域名和多域名证书
2. Standalone 模式
适合临时申请证书,或者机器上没有 Web 服务运行。
特点:
- acme.sh 会临时起一个内置 Web 服务
- 需要占用 80 端口
- 签发时可能需要暂停其他占用 80 端口的服务
3. DNS 模式
适合泛域名,例如 *.example.com。
特点:
- 不依赖 80/443 可达
- 适合内网、云环境、泛域名
- 通常需要 DNS 提供商 API 权限
使用 Webroot 签发证书
假设站点根目录是:
/var/www/example.com签发证书:
acme.sh --issue -d example.com -d www.example.com -w /var/www/example.com说明:
- -d 可以重复多次,表示多域名证书
- -w 指定 webroot 目录
- Webroot 目录必须能被 Web 服务器正常对外提供
使用 Standalone 签发证书
如果当前没有站点服务占用 80 端口:
acme.sh --issue -d example.com --standalone如果你有多个域名:
acme.sh --issue -d example.com -d www.example.com --standalone注意:
- 80 端口必须能被外网访问
- 如果机器上已有 Nginx/Apache,可能需要先临时停止它们
使用 DNS API 签发泛域名
泛域名常见写法:
acme.sh --issue -d example.com -d '*.example.com' --dns dns_xxx其中 dns_xxx 是对应 DNS 服务商的 API 插件名。
典型用途
- example.com
- www.example.com
- api.example.com
- *.example.com
典型场景
- 你想给一组子域统一发证
- 你不能暴露 80/443 给外部验证
- 你的站点在内网或临时环境
安装证书到 Nginx
签发后,还要把证书安装到真正使用的服务里。
示例:
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.fullchain.cer \
--reloadcmd "sudo systemctl reload nginx"这条命令做了什么
- 把私钥写到指定位置
- 把完整证书链写到指定位置
- 证书更新后执行重载命令
为什么推荐这样做
- Nginx 不需要自己管理证书生成过程
- 证书续期后可以自动 reload
- 证书路径稳定,便于统一管理
Nginx 配置示例
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
index index.html;
}HTTP 跳转 HTTPS:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}证书管理
查看已签发证书
acme.sh --list查看某个证书信息
acme.sh --info -d example.com手工续期
acme.sh --renew -d example.com强制续期
acme.sh --renew -d example.com --force撤销证书
acme.sh --revoke -d example.com删除本地记录
acme.sh --remove -d example.com自动续期
acme.sh 安装后通常会自动配置定时任务,定期检查证书是否需要续期。
手工触发 cron
acme.sh --cron --home ~/.acme.sh查看 cron 是否存在
crontab -l续期后的自动动作
建议使用 --reloadcmd,这样证书更新后会自动重载服务。
申请前后的常见检查
DNS 是否解析正确
dig example.com
dig www.example.com80 端口是否可达
ss -ltnp | grep ':80'站点根目录是否可写
ls -ld /var/www/example.comNginx 配置是否通过
sudo nginx -t常见问题
1. 签发失败,提示验证不通过
常见原因:
- 域名 DNS 没解析到当前服务器
- 防火墙未放行 80/443
- Webroot 路径不对
- server_name 不匹配
2. standalone 模式启动失败
通常是端口被占用。先检查:
sudo ss -ltnp | grep ':80'3. DNS API 模式失败
通常是:
- API key 配错
- 权限不足
- 服务商插件名写错
- DNS 生效太慢
4. 证书生成了但 Nginx 没更新
检查:
- --reloadcmd 是否正确
- reload 命令是否有权限
- Nginx 证书路径是否写对
5. 证书快到期但没自动续期
检查:
- crontab -l
- acme.sh --cron --home ~/.acme.sh
- 日志输出
推荐工作流
如果你已经有 Nginx 站点,推荐这个顺序:
sudo mkdir -p /var/www/example.com
acme.sh --issue -d example.com -d www.example.com -w /var/www/example.com
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.fullchain.cer \
--reloadcmd "sudo systemctl reload nginx"
sudo nginx -t
sudo systemctl reload nginx安全建议
- 私钥路径不要随便开放权限
- 不要把 API 密钥硬编码到公开脚本
- 不要同时让多个证书客户端管理同一个证书目录
- 证书文件和 Nginx 配置要保持对应关系
结论
acme.sh 在 Debian 上最实用的落地方式是:
- 用官方安装脚本安装
- 根据场景选 webroot、standalone 或 dns
- 签发后用 --install-cert 放到 Nginx 使用的位置
- 依靠定时任务自动续期
- 续期后自动重载服务