上个月 30 日,Google Cloud 在其博客发表文章 Automate Public Certificates Lifecycle Management via RFC 8555 (ACME) 发布了测试版的自动化公共 CA 管理程序。
简而言之就是 Google 也开放了类似于 Let’s Encrypt 的免费证书申请。并且和 Google 各项服务使用相同的根证书。
优劣分析
- 可以设置颁发证书的有效期;(
最长 90 天
) - 支持
多域名及通配符
;(与 Let’s Encrypt 相同) - 仅
支持 DNS 验证和文件验证
,不支持邮件验证;(与 Let’s Encrypt 相同) 支持 IP 地址
,但是仅允许该 IP 地址块的所有者进行验证;(Let’s Encrypt 暂不支持)- 不支持 IDN (International Domain Name, 国际化域名,使用 Punycode 进行编码,形如 xn–1.xn–2).(Let’s Encrypt 已经支持)
- 目前签发的证书,即使选择
ECC
类型,证书链的中级证书也是 RSA 的(Let’s Encrypt 已经支持全链 ECC) ocsp.pki.goog
有国内节点
,访客体验还是很不错的。- 目前有 DNSSEC CAA 问题,在 DNSPod 添加了 DNSSEC 的用户请暂缓申请
申请方法
申请 GOOGLE 域名 API
登录 google 账号后,进入下面链接
https://cloud.google.com/sdk/gcloud/reference/publicca?hl=zh-cn
单击右上角
的“激活 Cloud Shell
”,打开Cloud Shell
然后在在 Cloud Shell 输入
gcloud publicca external-account-keys create
要等待一会才会返回 keyid
和 b64mackey
,不行就多输入几次
Created an external account key
[b64MacKey: xxxxxxxxxxxxxxxxxxx
keyId: xxxxxxxxxxxx]
保存好keyId和b64MacKey
安装 acme.sh
如果已经安装请忽略这步
curl https://get.acme.sh | sh -s email=你的邮箱
或者
wget -O - https://get.acme.sh | sh -s email=你的邮箱
若后面出现 command not found,则需要手动执行以下命令:
source ~/.bashrc
Acme.sh 默认生成 Let’s Encrypt R3 证书,我们需要修改一下让它默认生成 google 证书
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 验证.
- http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.
acme.sh --issue -d mydomain.com --webroot /home/wwwroot/mydomain.com/
只需要指定域名
, 例如: mydomain.com 多个可以后面再加 -d www.mydomain.com
并指定域名所在的网站根目录
, 例如: /home/wwwroot/mydomain.com/
acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用.
查看已证书安装信息
acme.sh --info -d example.com
选择默认 CA
目前 acme.sh 支持 5 个正式环境 CA,分别是 Let’s Encrypt、Buypass、ZeroSSL、SSL.com和 Google Public CA,默认使用 ZeroSSL,如果需要更换可以使用如下命令:
切换 Let’s Encrypt
acme.sh --set-default-ca --server letsencrypt
切换 Buypass
acme.sh --set-default-ca --server buypass
切换 ZeroSSL
acme.sh --set-default-ca --server zerossl
切换 SSL.com
acme.sh --set-default-ca --server ssl.com
切换 Google Public CA
acme.sh --set-default-ca --server google
如果已有 ZeroSSL 帐号,可以在后台控制面板拿到 API Key,然后执行如下命令
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 为例,直接在终端运行
acme.sh --issue -d example.com -w /var/www/letsencrypt
如果希望签发 ECC 证书,则运行
acme.sh --issue -d example.com --keylength ec-256 -w /var/www/letsencrypt
如果需要多个域名,则运行
acme.sh --issue -d example.com -d example.org -w /var/www/letsencrypt
然后就等他执行完,直到出现 Cert success
的提示
然后我们可以安装证书
Nginx
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 配置指定证书文件
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
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 配置指定证书文件
SSLCertificateFile /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com.key
如果是 ECC 证书,则安装的时候需要带上 --ecc
参数,比如
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:
然后选择 Edit Zone DNS 的模板
选择你要编辑的域名,也可以加入你服务器的 IP 作为白名单
完成后会给你一串字符,把他复制下来,需要填入下方的 CF_Token
参数
然后进入域名的管理页面,在右侧 API 列找到 Account ID
和 Zone ID
并复制
接着在终端运行
export CF_Token="复制下来的 Token"
export CF_Account_ID="复制下来的 Account ID"
export CF_Zone_ID="复制下来的 Zone ID"
然后开启 acme.sh 的 DNS API 模式申请证书
acme.sh --issue --dns dns_cf -d example.com -d *.example.com
如果是dns.la:
export LA_Id="<appid>"
export LA_Key="<apikey>"
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 到最新版本:
acme.sh --upgrade
如果您不想手动升级,可以开启自动升级:
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