acme.sh
acme.sh 介绍
acme.sh
是一个用 shell 编写的自动化的 Let's Encrypt SSL/TLS 证书管理工具,它能够帮助用户自动化地申请、安装和续签 Let's Encrypt 提供的免费 SSL 证书。与其它类似的工具相比,acme.sh
的特点在于它的轻量级特性——不需要额外依赖(如 Python、PHP 等),并且可以完全在 shell 脚本中运行。
特点
跨平台:可以在各种操作系统上使用,包括 Linux, macOS, Windows (通过 Cygwin 或 Git Bash)。
零依赖:无需安装其他软件包或库即可运行。
自动续签:可以设置为定期检查证书的有效性,并在必要时自动进行更新。
支持多种 DNS 提供商:除了常见的 Web 根文件验证方法之外,acme.sh 还支持通过 API 从多个 DNS 提供商处获取 TXT 记录以完成域名所有权的证明。
acme.sh 安装
安装命令:
curl https://get.acme.sh | sh
acme.sh 配置
bash环境引入
export PATH="~/.acme.sh:$PATH"
zsh环境引入
export PATH="$HOME/.acme.sh:$PATH"
acme.sh 机构
查看当前使用的CA机构
acme.sh --info
可以在输出中找到 CA
字段,显示的是当前使用的 CA 机构。
CA切换命令:
acme.sh --set-default-ca --server
默认机构(ZeroSSL):
该机构需要注册邮箱使用,默认使用,不需要切换;
acme.sh --set-default-ca --server zerossl
条件:需要邮箱验证;证书有限期:90天/1年
Let's Encrypt 机构:
acme.sh --set-default-ca --server letsencrypt
条件:直接使用;证书有限期:90天;
Buypass 机构:
acme.sh --set-default-ca --server buypass
条件:无邮箱注册,证书有效期180天
SSL.com 机构:
acme.sh --set-default-ca --server sslcom
条件:邮件验证 + API认证
注册邮箱命令
acme.sh --register-account -m [email protected]
acme.sh 模式
Standalone 模式
说明:
acme.sh
内置了一个临时 Web 服务器,用于进行 HTTP-01 验证。适用于没有 Web 服务器运行,或者希望临时启动服务器进行验证的情况。
使用方式:
acme.sh --issue --standalone -d example.com
要求:
需要 root 权限(或者确保 80 端口可用)。
不能有其他进程占用 80 端口,否则会导致绑定失败。
80 端口必须未被占用,否则需使用 --httpport
指定其他端口:
acme.sh --issue --standalone --httpport 8080 -d example.com
Nginx 模式
说明:
acme.sh
自动为 Nginx 配置 ACME 认证所需的 .well-known/acme-challenge/
目录,适用于已有 Nginx 运行的环境。
使用方式:
acme.sh --issue --nginx -d example.com
要求:
必须安装并运行 Nginx。
需要 nginx.conf
允许 /.well-known/acme-challenge/
目录可访问:
location /.well-known/acme-challenge/
{
root /var/www/html;
}
80 端口必须可用并可被外部访问。
Apache 模式
说明:
类似于 Nginx,适用于运行 Apache Web 服务器的环境,acme.sh
会自动配置 Apache 以提供 ACME 验证文件。
使用方式:
acme.sh --issue --apache -d example.com
要求:
必须安装并运行 Apache。
mod_rewrite
必须启用,并且/.well-known/acme-challenge/
可被访问。
Webroot 模式
说明:
适用于已有 Web 服务器的情况,acme.sh
会将验证文件放入指定的 Web 目录,服务器需要正确提供访问。
使用方式:
acme.sh --issue --webroot /var/www/html -d example.com
要求:
Web 服务器必须运行且可通过
HTTP://example.com/.well-known/acme-challenge/
访问。需要
acme.sh
具有写入webroot
目录的权限。
DNS API 模式
说明:
使用 DNS-01 方式进行域名验证,适用于无法开启 80/443 端口,或需要申请泛域名(Wildcard *.example.com
)的情况。
使用方式:
例:
export CF_Key="your-cloudflare-api-key"
export CF_Email="[email protected]"
acme.sh --issue --dns dns_cf -d example.com -d "*.example.com"
要求:
需要 DNS 提供商的 API 密钥(不同 DNS 解析商配置不同)。
acme.sh
内置支持多种 DNS 解析商(如 Cloudflare、Aliyun、DNSPod、AWS Route 53 等)。
DNS 手动模式
说明:
如果 DNS 解析商不支持 API,可以手动创建 TXT 记录进行验证。
使用方式:
acme.sh --issue --dns -d example.com
执行后会显示:
Add the following TXT record to your DNS: _acme-challenge.example.com TXT "random-string"
然后手动添加到 DNS 解析中,再继续执行:
acme.sh --renew -d example.com
要求:
需要手动管理 DNS 记录。
适用于不支持 API 操作的 DNS 解析商。
TLS ALPN 模式
说明:
使用 TLS-ALPN-01 方式进行验证,适用于 443 端口可用但 80 端口受限的情况(如 Let's Encrypt
适用于 haproxy
、traefik
等)。
使用方式:
acme.sh --issue --alpn -d example.com
要求:
服务器需要支持
ALPN
(Application-Layer Protocol Negotiation)。443 端口必须对外开放。
适用于 Traefik、HAProxy 之类的代理服务器。
SFTP / FTP / SCP 模式
说明:
acme.sh
可以将验证文件上传到远程服务器的 Web 目录中进行 HTTP-01 验证,适用于不直接管理 Web 服务器的情况。
使用方式:
acme.sh --issue --ftp myftpserver.com:21 --ftp-user myuser --ftp-password mypassword -d example.com
要求:
目标服务器必须允许 FTP/SFTP/SCP 访问。
需要配置正确的身份凭据。
Custom Hook 模式
说明:
acme.sh
允许使用自定义 Hook 脚本来处理域名验证,比如自动创建 DNS 记录、上传验证文件等。
使用方式:
acme.sh --issue --dns --dnsscript /path/to/custom_script.sh -d example.com
要求:
自定义脚本需要能正确创建 DNS TXT 记录或处理 HTTP 验证文件。
Acme.sh 模式 表格
acme.sh --dns 参数
查看支持的 dns厂家列表命令:
acme.sh --list-dns
以下是 acme.sh
主要支持的 DNS 解析提供商及其对应的 --dns
选项:
API 认证参数详细说明
Cloudflare (--dns dns_cf
)
环境变量
export CF_Token="your_cloudflare_api_token"
export CF_Account_ID="your_cloudflare_account_id"
API 说明
CF_Token
:Cloudflare 的 API 令牌(建议使用基于 Least Privilege 的 API Token)。CF_Account_ID
:Cloudflare 账户 ID。
阿里云 (--dns dns_ali
)
环境变量
export Ali_Key="your_aliyun_access_key"
export Ali_Secret="your_aliyun_secret_key"
API 说明
Ali_Key
:阿里云 API 访问密钥 ID。Ali_Secret
:阿里云 API 访问密钥 Secret。
DNSPod / 腾讯云 (--dns dns_dp
/ --dns dns_tencent
)
环境变量
export DP_Id="your_dnspod_api_id"
export DP_Key="your_dnspod_api_key"
API 说明
DP_Id
:DNSPod API 用户 ID(老版本)。DP_Key
:DNSPod API 密钥。
对于新版腾讯云 DNS:
环境变量
export Tencent_SecretId="your_tencent_secret_id"
export Tencent_SecretKey="your_tencent_secret_key"
API 说明
Tencent_SecretId
:腾讯云 API 密钥 ID。Tencent_SecretKey
:腾讯云 API 密钥。
GoDaddy (--dns dns_gd
)
环境变量
export GODADDY_API_KEY="your_godaddy_api_key"
export GODADDY_API_SECRET="your_godaddy_api_secret"
API 说明
GODADDY_API_KEY
:GoDaddy API 密钥。GODADDY_API_SECRET
:GoDaddy API 密钥 Secret。
Amazon Route 53 (--dns dns_aws
)
环境变量
export AWS_ACCESS_KEY_ID="your_aws_access_key" export AWS_SECRET_ACCESS_KEY="your_aws_secret_key"
API 说明
AWS_ACCESS_KEY_ID
:AWS 访问密钥 ID。AWS_SECRET_ACCESS_KEY
:AWS 访问密钥。
Google Cloud DNS (--dns dns_gcloud
)
环境变量
export GCE_PROJECT="your_google_cloud_project_id"
export GCE_SERVICE_ACCOUNT="your_google_service_account_json"
API 说明
GCE_PROJECT
:Google Cloud 项目 ID。GCE_SERVICE_ACCOUNT
:Google Cloud Service Account JSON 文件路径。
Namecheap (--dns dns_nc
)
环境变量
export NAMECHEAP_API_KEY="your_namecheap_api_key"
API 说明
NAMECHEAP_API_KEY
:Namecheap API 密钥。
Vultr (--dns dns_vultr
)
环境变量
export VULTR_API_KEY="your_vultr_api_key"
API 说明
VULTR_API_KEY
:Vultr API 密钥。
其他 DNS API 使用方式
如果 acme.sh
没有直接支持你的 DNS 提供商,可以:
使用通用 API:
--dns dns_custom
,自己编写 API 交互脚本。
使用手动 DNS 验证:
s
提交 PR 贡献新 DNS API:
参考
dnsapi
目录,编写新的dns_xxx.sh
。
acme.sh 示例
DNS 手动模式
适用于不支持 API 的 DNS 解析商,需要手动创建 TXT 记录进行验证。
命令
acme.sh --issue --dns -d example.com
步骤
执行后会输出需要添加的 TXT 记录,例如:
_acme-challenge.example.com. TXT "random-string"
手动添加 TXT 记录到 DNS 解析。
等待 DNS 生效后,继续执行:
acme.sh --renew -d example.com
证书安装
申请成功后,可以安装证书到特定路径,例如:
acme.sh --install-cert -d example.com \
--key-file /etc/ssl/example.com.key \
--fullchain-file /etc/ssl/example.com.pem \
--reloadcmd "systemctl restart nginx"
--key-file
:指定私钥存放路径--fullchain-file
:完整证书存放路径--reloadcmd
:证书更新后自动重启服务器
证书续签
acme.sh
会自动续签证书,但也可以手动触发:
acme.sh --renew -d example.com --force
证书撤销
如果需要撤销已申请的证书:
acme.sh --revoke -d example.com
证书删除
如果不再需要某个证书:
acme.sh --remove -d example.com
acme.sh 问题
1. 80 端口被占用
问题
使用 --standalone
模式申请证书时,如果 80 端口被其他服务(如 Nginx、Apache)占用,可能会出现:
Error: Port 80 is already in use by another process
解决办法
方法 1:临时停止占用 80 端口的服务
systemctl stop nginx acme.sh --issue --standalone -d example.com systemctl start nginx
方法 2:使用其他端口(如 8080)
acme.sh --issue --standalone --httpport 8080 -d example.com
方法 3:使用 Webroot 或 DNS 方式申请证书(推荐)
acme.sh --issue --webroot /var/www/html -d example.com
2. 访问 .well-known/acme-challenge/
失败
问题
如果使用 --webroot
或 --nginx
模式,但 .well-known/acme-challenge/
目录无法访问,可能会导致:
Verify error: Invalid response from http://example.com/.well-known/acme-challenge/...
解决办法
检查 Nginx 配置
location /.well-known/acme-challenge/ { root /var/www/html; allow all; }
重新加载配置:
systemctl reload nginx
手动测试 .well-known
目录
mkdir -p /var/www/html/.well-known/acme-challenge/
echo "test" > /var/www/html/.well-known/acme-challenge/test.txt
curl -v http://example.com/.well-known/acme-challenge/test.txt
如果访问失败,说明服务器未正确配置。
检查 Web 服务器权限
chmod -R 755 /var/www/html/.well-known/ chown -R www-data:www-data /var/www/html/
3. 证书续签失败
问题
acme.sh
会自动续签证书,但可能因为 DNS 解析、Web 服务器问题导致续签失败:
Renew: example.com failed, skipping.
解决办法
手动尝试续签
acme.sh --renew -d example.com --force
检查证书过期情况
openssl x509 -noout -dates -in /etc/ssl/example.com.pem
更换 DNS 解析模式(如果之前使用 Webroot/Nginx)
acme.sh --issue --dns dns_ali -d example.com -d "*.example.com"
检查 acme.sh
自动任务 acme.sh
默认使用 cron
任务自动续签,检查是否存在:
crontab -l | grep acme
如果任务不存在,可以手动添加:
crontab -e
添加:
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
4. 证书自动更新失败
问题
即使 acme.sh
续签成功,Nginx 或 Apache 可能仍然使用旧证书。
解决办法
检查 acme.sh
是否正确安装证书
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.pem \
--reloadcmd "systemctl reload nginx"
确保 nginx
/apache
重新加载新证书
systemctl reload nginx
5. 证书过期导致网站无法访问
问题
如果证书过期,浏览器可能会报错:
NET::ERR_CERT_DATE_INVALID
复制编辑
解决办法
手动续签
acme.sh --renew -d example.com --force
检查 acme.sh
的 cron
任务是否存在
crontab -l | grep acme
如果不存在,重新添加:
crontab -e
bash
复制编辑
0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
添加自动更新证书并重启 Web 服务器 在 /etc/crontab
中添加:
0 0 * * * root /root/.acme.sh/acme.sh --cron --home "/root/.acme.sh" && systemctl reload nginx
6. 证书撤销失败
问题
如果尝试撤销证书但失败:
Revoke error: Certificate not found
解决办法
手动撤销
acme.sh --revoke -d example.com --force
删除证书
acme.sh --remove -d example.com rm -rf ~/.acme.sh/example.com/
7. 证书路径找不到
问题
某些环境下,acme.sh
申请的证书路径可能不在默认目录:
/root/.acme.sh/example.com/
解决办法
查看证书路径
acme.sh --list
重新安装证书到指定路径
acme.sh --install-cert -d example.com \ --key-file /etc/ssl/private/example.com.key \ --fullchain-file /etc/ssl/certs/example.com.pem \ --reloadcmd "systemctl reload nginx"
8. 如何迁移到另一台服务器
方法
备份 acme.sh
目录:
tar -czf acme_backup.tar.gz ~/.acme.sh
复制到新服务器:
scp acme_backup.tar.gz user@newserver:/root/
在新服务器解压:
tar -xzf acme_backup.tar.gz -C /root/
重新安装 acme.sh
:
curl https://get.acme.sh | sh
重新加载证书:
acme.sh --install-cert -d example.com \
--key-file /etc/ssl/private/example.com.key \
--fullchain-file /etc/ssl/certs/example.com.pem \
--reloadcmd "systemctl reload nginx"