上个月 30 日,Google Cloud 在其博客发表文章 Automate Public Certificates Lifecycle Management via RFC 8555 (ACME) 发布了测试版的自动化公共 CA 管理程序。
简而言之就是 Google 也开放了类似于 Let’s Encrypt 的免费证书申请。并且和 Google 各项服务使用相同的根证书。

优劣分析

  1. 可以设置颁发证书的有效期;(最长 90 天
  2. 支持多域名及通配符;(与 Let’s Encrypt 相同)
  3. 支持 DNS 验证和文件验证,不支持邮件验证;(与 Let’s Encrypt 相同)
  4. 支持 IP 地址,但是仅允许该 IP 地址块的所有者进行验证;(Let’s Encrypt 暂不支持)
  5. 不支持 IDN (International Domain Name, 国际化域名,使用 Punycode 进行编码,形如 xn–1.xn–2).(Let’s Encrypt 已经支持)
  6. 目前签发的证书,即使选择 ECC 类型,证书链的中级证书也是 RSA 的(Let’s Encrypt 已经支持全链 ECC)
  7. ocsp.pki.goog国内节点,访客体验还是很不错的。
  8. 目前有 DNSSEC CAA 问题,在 DNSPod 添加了 DNSSEC 的用户请暂缓申请

申请方法

申请 GOOGLE 域名 API

登录 google 账号后,进入下面链接

https://cloud.google.com/sdk/gcloud/reference/publicca?hl=zh-cn

单击右上角的“激活 Cloud Shell”,打开Cloud Shell

然后在在 Cloud Shell 输入

1
gcloud publicca external-account-keys create

要等待一会才会返回 keyidb64mackey,不行就多输入几次

Created an external account key
[b64MacKey: xxxxxxxxxxxxxxxxxxx
keyId: xxxxxxxxxxxx]

保存好keyId和b64MacKey

安装 acme.sh

如果已经安装请忽略这步

1
curl https://get.acme.sh | sh -s email=你的邮箱

或者

1
wget -O -  https://get.acme.sh | sh -s email=你的邮箱

若后面出现 command not found,则需要手动执行以下命令:

1
source ~/.bashrc

Acme.sh 默认生成 Let’s Encrypt R3 证书,我们需要修改一下让它默认生成 google 证书

1
acme.sh --set-default-ca --server google

申请 google 证书

获取申请 google 证书的资格

~/.acme.sh/acme.sh --register-account --server google \
    --eab-kid "xxxxx" \
    --eab-hmac-key "xxxxx"

eab-kid 为申请到的谷歌 keyId

eab-hmac-key 申请到的 b64MacKey

注意: API 获取的凭证应该是只能使用一次,重新获取 API 凭证之后可以成功注册(更新:每台服务器都需要单独的凭证注册一次,之后的签发则不再需要)。

签发证书

acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: http 和 dns 验证.

  1. http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.
acme.sh --issue -d mydomain.com --webroot /home/wwwroot/mydomain.com/

只需要指定域名, 例如: mydomain.com 多个可以后面再加 -d www.mydomain.com

并指定域名所在的网站根目录, 例如: /home/wwwroot/mydomain.com/

acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用.

查看已证书安装信息

1
acme.sh --info -d example.com

选择默认 CA

目前 acme.sh 支持 5 个正式环境 CA,分别是 Let’s EncryptBuypassZeroSSLSSL.com和 Google Public CA,默认使用 ZeroSSL,如果需要更换可以使用如下命令:

切换 Let’s Encrypt

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

切换 Buypass

1
acme.sh --set-default-ca --server buypass

切换 ZeroSSL

1
acme.sh --set-default-ca --server zerossl

切换 SSL.com

1
acme.sh --set-default-ca --server ssl.com

切换 Google Public CA

1
acme.sh --set-default-ca --server google

如果已有 ZeroSSL 帐号,可以在后台控制面板拿到 API Key,然后执行如下命令

1
2
apt install jq
curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=你的API_Key" | jq

终端会输出如下内容

{
  "success": true,
  "eab_kid": "kid字符串",
  "eab_hmac_key": "hmac_key字符串",
}

然后手工添加帐号

acme.sh --register-account  --server zerossl \
        --eab-kid kid字符串  \
        --eab-hmac-key hmac_key字符串

Google Public CA 需要按照官方博客申请内测,然后获取 Key。

几个 CA 的简单对比

功能 LE Buypass ZeroSSL SSL.com Google Public CA
有效期 90 天 180 天 90 天 90 天 90 天
多域名 支持 支持,最多 5 个 支持 收费支持 支持
泛域名 支持 不支持 支持 收费支持 支持
Rate Limit 收费无 未知
GUI 管理
ECC 证书链 未知
客户支持 社区 收费 收费 收费 收费

简单来说,如果没有特殊需求,可以选择 Let’s Encrypt,如果服务器在国内,可以选择 ZeroSSL 或 Buypass,如果愿意付费得到更好的服务和保障,可以选择 ZeroSSL 和 SSL.com,如果面向欧盟用户,可以选择 Buypass 和 ZeroSSL。

注意:经过测试 Google Public CA 的 ACME 验证域名在国内是无法访问的,只有国外服务器才可以申请,申请完成后的证书并无影响。

使用 HTTP 验证签发证书

我们以 Let’s Encrypt 为例,直接在终端运行

1
acme.sh --issue -d example.com -w /var/www/letsencrypt

如果希望签发 ECC 证书,则运行

1
acme.sh --issue -d example.com --keylength ec-256 -w /var/www/letsencrypt

如果需要多个域名,则运行

1
acme.sh --issue -d example.com -d example.org -w /var/www/letsencrypt

然后就等他执行完,直到出现 Cert success 的提示

Pasted image 20230829023310

然后我们可以安装证书

Nginx

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file        /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd     "systemctl restart nginx"

对应的 Nginx 配置指定证书文件

1
2
3
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com.ca.crt;

Apache

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file       /etc/apache2/ssl/example.com.key  \
--fullchain-file /etc/apache2/ssl/example.com.crt \
--ca-file        /etc/apache2/ssl/example.com.ca.crt \
--reloadcmd     "curl https://ssl-config.mozilla.org/ffdhe2048.txt >> /etc/apache2/ssl/example.com.crt && systemctl restart apache2"

对应的 Apache 配置指定证书文件

1
2
SSLCertificateFile      /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile   /etc/apache2/ssl/example.com.key

如果是 ECC 证书,则安装的时候需要带上 --ecc 参数,比如

1
2
3
4
5
acme.sh --install-cert --ecc -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file        /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd     "systemctl restart nginx"

注意如果是多个域名,也仅需要在 -d 参数后面指定第一个域名即可。

使用 DNS 验证签发证书

有时候因为不想暴露一些二级域名,或者希望在多台机器上部署同一个域名的证书,这时候就需要用到 DNS 插件了,acme.sh 支持几十种 DNS 插件。

这里以 Cloudflare 为例,登录 Cloudflare Dash 后在 API Token 菜单里添加一个 API Token:

Pasted image 20230829023544

然后选择 Edit Zone DNS 的模板

Pasted image 20230829023556

选择你要编辑的域名,也可以加入你服务器的 IP 作为白名单

Pasted image 20230829023610

完成后会给你一串字符,把他复制下来,需要填入下方的 CF_Token 参数

Pasted image 20230829023626

然后进入域名的管理页面,在右侧 API 列找到 Account ID 和 Zone ID 并复制

Pasted image 20230829023641

接着在终端运行

1
2
3
export CF_Token="复制下来的 Token"
export CF_Account_ID="复制下来的 Account ID"
export CF_Zone_ID="复制下来的 Zone ID"

然后开启 acme.sh 的 DNS API 模式申请证书

1
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

如果是dns.la:

1
2
export LA_Id="<appid>"
export LA_Key="<apikey>"
1
acme.sh --issue --dns dns_la -d example.com -d *.example.com

安装证书方法同上,另外吐槽下,很多教程会让你用 Cloudflare 的全局 Global API Key,真的是,风险太大了,最后怎么被黑的都不知道 = =

如果不想使用第三方的 DNS 服务完全可以自建 acme-dns 或者 PowerDNS,篇幅有限,我们之后再介绍。

更新证书

目前证书在 60 天以后会自动更新,您无需进行任何操作。接下来可能会讲这个时间,但是都是自动的,你不用担心。

请确保 cronjob 正确安装,看起来类似如下:

crontab  -l

56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

更新acme.sh

目前由于 acme 协议和 Letscrypt CA 都在关闭的更新,因此 acme.sh 也经常更新以保持同步。

升级 acme.sh 到最新版本:

1
acme.sh --upgrade

如果您不想手动升级,可以开启自动升级:

1
acme.sh --upgrade --auto-upgrade

此后,acme.sh就会自动保持更新了。

您也可以随时关闭自动更新:

acme.sh --upgrade --auto-upgrade  0

官方文档

https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf