View in English

acme.sh 算是很有名气的自动 SSL 证书脚本了。国人开发,用起来也挺顺手。

因为俺用了互联网皇帝的 DNS 服务,故只演示如何与 cloudflare 整合。对于其他服务商,原理基本是一样的。

安装 acme.sh

调用 acme.sh 的安装脚本。

curl https://get.acme.sh | sh

重新加载 shell.

比如这样:

source ~/.bashrc

新建 Cloudflare API Key

在此强烈推荐 DNS API 模式,除非是从 freenom.com 白嫖的域名。

首先把域名丢给 Cloudflare 托管。这太简单了,实在不想演示了。

建立一个 API token 给 acme.sh 用。

别随便把全局 API key 交了。

回头记得把 Zone IDAccount ID 也加上。

点击 “Create Token”.

Cloudflare 写了样板,直接用。

选择 specific zone.

自行决定要不要设置有效期。

建议添加 IP 白名单,防止被盗。

确认一下设置。

拷贝一下 token 然后试试看能不能用。

这可不会再出现了,一定要拷贝走。

acme.sh 配置

先注册这 **的 zerossl 账户。

acme.sh --register-account -m [email protected]

噢,也可以继续用 Let’s Encrypt. 但要加参数 --server letsencrypt 或者干脆 把 default CA 改回去

acme.sh --set-default-ca --server letsencrypt

然后给 acme.sh 增加环境变量。

通常而言,它会自动在 ~/.acme.sh/account.conf 中自动保存这些凭证。

export CF_Token='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
export CF_Account_ID='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
export CF_Zone_ID='xxxxxxxxxxxxxxxxxxxxxx'

或者在 ~/.acme.sh/account.conf 中添加

SAVED_CF_Token='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SAVED_CF_Account_ID='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
SAVED_CF_Zone_ID='xxxxxxxxxxxxxxxxxxxxxx'

调用 acme.sh

然后直接一行指令,acme.sh 会帮你自动解决剩下的所有事情。

ECC 证书好啊。如果想要 RSA 可以把 ec-xxx 改成 RSA 位数(2048/4096

带通配符(*)的子域名,需用引号包住。

acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf --keylength ec-256 

然后你就可以看到证书和密钥的路径了。

然后它会创建一个定期的 cron 任务,用 API 自动帮你续期。

续签设置:自动重置私钥

感谢 Liet Blue 指出了这个问题。

acme.sh 不会在每次 renew 更新私钥

其他的 acme 客户端大部分都会更新私钥

acme.sh --issue xxxxx --always-force-new-domain-key

这样每次renew之后都会生成下一次会用到的私钥…可以增强前向安全

看起来是一个历史遗留问题,acme.sh 在续签证书时不会像 alternative 们那样,重置 domain key.

为什么 acme.sh 不默认 renew key

TLSA Roll-over 的简要介绍

查阅这两个 issue 后,大概可以知道,可以用 --always-force-new-domain-key 参数在续签证书时重置 domain key.

--cron 是有效的,添加在 crontab 中即可。

多个身份

添加 --home--config-home 参数,就能为不同的域名分别签署证书,互不干扰。

acme.sh --home /path/to/.acme.sh --config-home /path/to/.acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf --keylength ec-256 

得到的证书均在设定的 home 中。

DNS 手动模式

这个模式不需要其他解析记录。

需要的话可以添加 --force 参数。

acme.sh --issue -d example.com --dns --keylength ec-256 --yes-I-know-dns-manual-mode-enough-go-ahead-please 

输出大约长这样:

Add the following TXT record:
Domain: '_acme-challenge.example.com'
TXT value: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
Please be aware that you prepend _acme-challenge. before your domain
so the resulting subdomain will be: _acme-challenge.example.com
Please add the TXT records to the domains, and re-run with --renew.
Please add '--debug' or '--log' to check more details.
See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

添加 TXT 解析记录,并检查一下。

dig txt _acme-challenge.example.com

续签证书。

acme.sh --renew -d example.com --dns --ecc --yes-I-know-dns-manual-mode-enough-go-ahead-please

签出来的证书有效期只有90天,要记得及时续签。