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 适用于 haproxytraefik 等)。

使用方式:

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 模式 表格

模式

适用场景

主要要求

Standalone

服务器无 Web 服务器

80 端口需可用,无法与 Nginx/Apache 共存

Nginx

Nginx 已运行

80 端口需可访问,Nginx 配置 .well-known/acme-challenge/

Apache

Apache 已运行

80 端口需可访问,Apache 配置 .well-known/acme-challenge/

Webroot

服务器已有 Web 目录

80 端口需可访问,需写入 webroot

DNS API

适用于泛域名

需 DNS 解析商 API 支持

DNS 手动

适用于不支持 API 的 DNS

需手动添加 TXT 记录

TLS ALPN

适用于 443 端口可用但 80 端口受限

需要支持 ALPN

FTP/SFTP/SCP

远程服务器

需要远程访问凭据

Custom Hook

特殊需求

需自行编写 Hook 脚本

acme.sh --dns 参数

查看支持的 dns厂家列表命令:

acme.sh --list-dns

以下是 acme.sh 主要支持的 DNS 解析提供商及其对应的 --dns 选项:

DNS 解析提供商

参数 (--dns 选项)

API 认证环境变量

Cloudflare

--dns dns_cf

CF_Token / CF_Account_ID

Aliyun (阿里云)

--dns dns_ali

Ali_Key / Ali_Secret

DNSPod (腾讯云)

--dns dns_dp

DP_Id / DP_Key

GoDaddy

--dns dns_gd

GODADDY_API_KEY / GODADDY_API_SECRET

Amazon Route 53

--dns dns_aws

AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY

Google Cloud DNS

--dns dns_gcloud

GCE_PROJECT / GCE_SERVICE_ACCOUNT

Namecheap

--dns dns_nc

NAMECHEAP_API_KEY

CloudXNS

--dns dns_cx

CX_Key / CX_Secret

Dynu

--dns dns_dynu

DYNU_Customer / DYNU_Username / DYNU_Password

DigitalOcean

--dns dns_do

DO_API_KEY

Hurricane Electric (HE)

--dns dns_he

HE_Username / HE_Password

Linode

--dns dns_linode

LINODE_API_KEY

OVH

--dns dns_ovh

OVH_AK / OVH_AS / OVH_CK

Porkbun

--dns dns_porkbun

PORKBUN_API_KEY / PORKBUN_SECRET_KEY

DNSMadeEasy

--dns dns_dme

ME_Key / ME_Secret

Rackspace

--dns dns_rs

RS_Username / RS_APIKey

Gandi

--dns dns_gandi

GANDI_LIVEDNS_KEY

Vultr

--dns dns_vultr

VULTR_API_KEY

Tencent Cloud (DNSPod)

--dns dns_tencent

Tencent_SecretId / Tencent_SecretKey

Yandex

--dns dns_yandex

YANDEX_PDD_TOKEN

Infomaniak

--dns dns_infomaniak

INFOMANIAK_USERNAME / INFOMANIAK_APP_KEY

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 提供商,可以:

  1. 使用通用 API--dns dns_custom,自己编写 API 交互脚本。

使用手动 DNS 验证

s
  1. 提交 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.shcron 任务是否存在

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"