Google Cloud 在上个月也推出了通过 Automatic Certificate Management Environment(也就是我们常说的 acme 协议)实现的自动化证书管理服务。这也意味着我们现在可以免费申请到和 Let's Encrypt 一样的 Google 公共证书了,主要特性如下:

  • 支持多域名以及通配符证书(通配符证书目前需要通过 DNS 验证)
  • 支持申请 ECC 和 RSA 证书
  • 支持申请 IP 证书(目前只能该 IP Block 的所有者进行验证)
  • 证书最长有效期 90 天
  • 不支持 IDN 域名
  • OCSP 地址为 ocsp.pki.goog,有国内服务器节点

acme.sh 更新也很快,第二天就进行了增加了对 Google Public CA 的支持,下面就简单分享下使用 acme.sh 申请 Google 公共证书的流程。

注:虽然 OCSP 在国内可用,但国内访问不了 Google CA 的 ACME Server,因此暂时无法在国内服务器上申请签发该证书。

我前面写过一篇文章 使用acme.sh自动签发和更新证书,如果你需要了解 acme.sh 的使用或者申请 Let's Encrypt 证书的话可以参考一下。

获取 GCP API Key

首先你需要注册一个 Google Cloud Platform(GCP)账号。

申请内测功能

目前(2022 年 4 月 15 日)仍处于内测阶段,需要填写一个表单申请该功能:https://docs.google.com/forms/d/1Euhflb5CXpuLik8czElhyAloTZJZobar4086dmlPqXA,否则直接申请的话会提示错误:

(gcloud.alpha.publicca.external-account-keys.create) NOT_FOUND: Method not found.

其中需要填写你的 Google Cloud Project ID *,可以在你的控制台面板菜单栏左上角点击你的项目名查看:

gcp-get-project-id

我在提交一天后也没收到消息,看网友都是几小时就收到了...就又提交了一次,最后花了三天才收到了开通成功的邮件提醒:

gcp-public-certificate-authority-api-mail

获取 API Key

1. 登录你的 GCP 控制台面板,进入 Public Certificate Authority API 管理页面(https://console.cloud.google.com/apis/library/publicca.googleapis.com)点击启动

gcp-public-certificate-authority-api

或者直接在下一步的 Cloud Shell 中使用下面的命令启动也可以:

gcloud services enable publicca.googleapis.com

2. 点击右上角的菜单栏激活 Cloud Shell,输入下面内容选中项目,如果你只有一个项目的话可以跳过这步,会自动设置为唯一项目:

gcloud config set project [project ID]

3. 获取 API Key:

gcloud beta publicca external-account-keys create

中途弹窗点击授权之后会返回下列格式的信息,记录下来后面会用到:

Created an external account key
[b64MacKey: xxxxxxxxxxxxxxxxxxxxxxx
keyId: xxxxxxxxxxxxxxx]

申请证书

默认以 root 用户进行操作演示。

安装 acme.sh

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

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

source ~/.bashrc

签发证书

这里以使用 Cloudflare 的 API 为例,通过 DNS 验证申请通配符证书。

1. 获取 Cloudflare API,可以自己选择全局 API 还是单域 API,我这里选择了单域 API,获取到 API 后注意保存,然后导入:

export CF_Token="xxxxxxxxxxxxxxxxxxxxxxxx"
export CF_Account_ID="xxxxxxxxxxxxxxxxxxxxxxxx"
export CF_Zone_ID="xxxxxxxxxxxxxxxxxxxxxxxx"

其中 CF_Token 为你获取到的 API 密钥,CF_Account_IDCF_Zone_ID 可以在你域名概述页面侧边栏的 API 分栏看到。

2. 设置 API:

acme.sh  --register-account -m [邮箱] --server google \
    --eab-kid [申请到的 keyId] \
    --eab-hmac-key [申请到的 b64MacKey]

我在第一次注册的时候提示错误:

Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 6

无法解析 host,想了下应该是我的 acme.sh 是很久以前安装的,没有开启自动更新,使用 acme.sh --upgrade 命令更新一下就好了,或者将上面的 --server google 改成 --server https://dv.acme-v02.api.pki.goog/directory 手动指定服务器。

* 注:申请成功之后我又尝试在另一台 VPS 上使用上面的凭证注册,结果提示错误:

Register account Error: {"type":"urn:ietf:params:acme:error:unauthorized","detail":"Unknown external account binding key."}

API 获取的凭证应该是只能使用一次,重新获取 API 凭证之后可以成功注册。

3. 设置默认 CA,如果你一台服务器上有多个域名的 acme 任务,则可能自动更新失败,因此这里推荐使用 --accountconf 指定一个配置文件:

acme.sh --set-default-ca --server google --accountconf /root/.acme.sh/account-custom.conf

4. 签发证书:

acme.sh --issue --dns dns_cf -d mydomain.com -d *.mydomain.com --accountconf /root/.acme.sh/account-custom.conf

* 签发 ECC 证书:

acme.sh --issue --dns dns_cf -d mydomain.com -d *.mydomain.com --keylength ec-256 --accountconf /root/.acme.sh/account-custom.conf

如果你和我一样使用了 --accountconf 参数指定了配置文件,此时你的 Cron 自动任务也要做出对应的修改,运行 crontab -e 进行修改(如果有多个域名则应该相应的有多个任务):

30 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --accountconf "/root/.acme.sh/account-custom.conf" > /dev/null

5. 最后将证书安装到 Nginx 下:

acme.sh --install-cert -d mydomain.com \
--key-file       /path/to/ssl/private.key  \
--fullchain-file /path/to/ssl/fullchain.pem \
--reloadcmd     "service nginx restart"

* 安装 ECC 证书:

acme.sh --install-cert -d mydomain.com --ecc \
--key-file       /path/to/ssl/ecc_private.key  \
--fullchain-file /path/to/ssl/ecc_fullchain.pem \
--reloadcmd     "service nginx restart"

最后贴一张 Google 公共证书的证书路径:

google-public-ca-path

体验下来如果国内 OCSP 节点将来不被搞的话还挺不错的,虽然我还是开启了 OCSP Stapling😶