为什么选择 acme.sh#
在证书自动化管理领域,Certbot 是最知名的 ACME 客户端,但它依赖 Python 环境,体积较大。acme.sh 是一个纯 Shell 编写的轻量级 ACME 客户端,优势明显:
- 零依赖:仅需
curl 和 sed,可在任意 Linux 发行版运行
- 体积小巧:安装包仅几百 KB
- 支持 DNS API:可自动申请通配符证书
- 兼容性强:支持 Let’s Encrypt、ZeroSSL、Buypass 等多 CA
安装 acme.sh#
方式一:在线安装(推荐)#
1
|
curl https://get.acme.sh | sh -s email=admin@example.com
|
安装完成后,acme.sh 会自动创建配置目录 ~/.acme.sh/,并添加 cron 任务实现自动续期。
方式二:离线安装#
在没有网络的环境下,可以先在其他机器下载安装脚本:
1
2
3
4
5
6
|
# 在有网络的机器上下载
curl https://get.acme.sh > install.sh
# 传输到目标机器后安装
chmod +x install.sh
./install.sh --online no -s email=admin@example.com
|
验证安装#
输出类似:
申请证书:HTTP 验证方式#
HTTP 验证是最简单的证书申请方式,需要 80 端口开放。
1. 申请单域名证书#
1
|
acme.sh --issue -d example.com -w /var/www/html
|
-d 指定域名,-w 指定网站根目录。acme.sh 会在该目录下创建 .well-known/acme-challenge/ 目录用于验证。
2. 申请多域名证书#
1
|
acme.sh --issue -d example.com -d www.example.com -w /var/www/html
|
3. 使用 Nginx 自动模式#
acme.sh 可以自动配置 Nginx,无需手动放置验证文件:
1
|
acme.sh --issue -d example.com --nginx
|
此命令会自动修改 Nginx 配置,完成验证后再恢复。
申请证书:DNS 验证方式#
DNS 验证不需要开放端口,支持申请通配符证书。
1. 配置 DNS API#
acme.sh 支持数十种 DNS 提供商的 API 自动验证。以 Cloudflare 为例:
1
2
|
export CF_Key="your_cloudflare_api_key"
export CF_Email="your_email@example.com"
|
⚠️ 安全提示:API 密钥建议写入 acme.sh 配置文件,而非命令行历史记录。
2. 申请通配符证书#
1
|
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
|
3. 其他常用 DNS 提供商#
| 提供商 |
环境变量 |
命令参数 |
| Cloudflare |
CF_Key, CF_Email |
dns_cf |
| 阿里云 |
Ali_Key, Ali_Secret |
dns_ali |
| 腾讯云 |
TXY_SECRET_ID, TXY_SECRET_KEY |
dns_tx |
| DNSPod |
DP_Id, DP_Key |
dns_dp |
| GoDaddy |
GD_Key, GD_Secret |
dns_gd |
完整列表参考:acme.sh DNS API 支持列表
证书安装与部署#
申请到证书后,需要将证书安装到实际使用的位置。
1. 安装证书到指定目录#
1
2
3
4
|
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/cert.pem \
--reloadcmd "nginx -s reload"
|
参数说明:
--key-file:私钥保存路径
--fullchain-file:完整证书链保存路径
--reloadcmd:证书更新后自动重载服务的命令
2. 使用 standalone 模式#
如果不想修改现有配置,可以使用 standalone 模式:
1
2
3
|
acme.sh --install-cert -d example.com \
--key-file ./key.pem \
--fullchain-file ./cert.pem
|
然后在 Nginx 配置中引用:
1
2
|
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
|
自动续期配置#
acme.sh 安装时会自动添加 cron 任务:
1
2
|
# 查看 cron 任务
crontab -l
|
输出类似:
1
|
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
|
默认每天凌晨检查证书是否需要续期。续期逻辑:
- 证书距离过期少于 30 天时自动续期
- 续期成功后执行
--install-cert 时指定的 --reloadcmd
- 失败时记录日志,不影响服务运行
手动触发续期#
1
|
acme.sh --renew -d example.com
|
强制续期#
1
|
acme.sh --renew -d example.com --force
|
证书管理常用命令#
查看已安装证书#
输出格式:
1
2
|
Main_Domain KeyLength CreatedDate RenewDate
example.com 2048 2026-07-09T00:08:46Z 2026-08-08T00:08:46Z
|
撤销证书#
1
|
acme.sh --revoke -d example.com
|
删除证书#
1
|
acme.sh --remove -d example.com
|
导出证书为其他格式#
1
2
3
4
5
|
# 导出为 PFX 格式(适用于 IIS)
acme.sh --export -d example.com -f pfx --pfxpass yourpassword
# 导出为 PKCS12
acme.sh --export -d example.com -f pkcs12 --password yourpassword
|
实际案例:Nginx HTTPS 配置#
完整演示从申请证书到配置 Nginx 的流程。
步骤 1:安装 acme.sh#
1
|
curl https://get.acme.sh | sh -s email=admin@example.com
|
步骤 2:申请证书(DNS 方式)#
1
2
3
|
export CF_Key="your_cloudflare_api_key"
export CF_Email="your_email@example.com"
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
|
步骤 3:创建证书目录并安装#
1
2
3
4
5
|
mkdir -p /etc/nginx/ssl/example.com
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/cert.pem \
--reloadcmd "nginx -s reload"
|
步骤 4:配置 Nginx#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com/cert.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
location / {
root /var/www/html;
index index.html;
}
}
|
步骤 5:强制续期测试#
1
|
acme.sh --renew -d example.com --force
|
确认证书更新后 Nginx 自动重载:
1
|
nginx -t && nginx -s reload
|
常见问题#
Q: 证书申请失败,提示 “Validate error”#
检查以下内容:
- 域名是否正确解析到当前服务器 IP
- 80 端口(Nginx 验证)或 443 端口是否开放
- 防火墙是否放行了相应端口
- 网站根目录权限是否正确
Q: DNS 验证失败#
- 确认 API 密钥正确
- DNS 记录传播可能需要几分钟,等待后重试
- 使用
--debug 2 查看详细日志
Q: 续期后服务未重载#
- 检查
--reloadcmd 命令是否正确
- 查看日志:
cat ~/.acme.sh/acme.sh.log
- 确认 cron 任务是否存在
Q: 切换 CA 提供商#
1
2
3
4
5
|
# 切换到 ZeroSSL
acme.sh --set-default-ca --server zerossl
# 切换回 Let's Encrypt
acme.sh --set-default-ca --server letsencrypt
|
参考来源#