猎奇向:如何自动化地签发与轮替 Google Trust Services 的 7 日证书
目录
前情提要
近几日主播将博客和 jsd 加速等面向中国大陆的基础设施由腾讯云 CDN 迁移到了阿里云 ESA(其实就是阿里云版的腾讯云 Edge One。如果你感兴趣的话,可以走我的 邀请链接 试一试),总体体验还不错(尽管 ESA 的操作逻辑一股浓郁的 Cloudflare 味?)
由于 licaoz.com 的 DNS 服务使用 DNSPod,因此,在腾讯云时期,腾讯云证书托管功能有权通过 DNSPod 直接添加 DNS 类型的 challenge 记录,并在证书签发成功后重新同步回腾讯云 CDN 服务。尽管阿里云 ESA 依旧提供免费证书自动化续期与托管 DCV 能力,但免费证书仅限 10 张 Let's Encrypt 与 1 张 DigiCert Encryption Everywhere 单域名证书。本人个人不太喜欢 ISRG 根,并且依旧刻板地认为它的兼容性不如 GTS;而 DigiCert 那个又只支持单域名、还仅限一条。因此,使用 acme.sh 来申请一个 GTS 证书就很符合我的折腾尿性。
而又因为我印象中很久很久之前我见过或是 @renbaoshuo 或是 @menci 发过类似的文章,在 Google 上简单搜索了一下翻到了 使用 GitHub Actions 自动申请与部署 ACME SSL 证书。
环境安装与 ACME 账户凭据生成
安装 acme.sh
如果你喜欢 curl(或者单纯就是环境里没 wget 又懒得装),那么可以运行下面这行命令(所有花括号 {} 均表示变量,需在运行前按描述修改。所有变量均无需键入花括号本身。下同):
curl https://get.acme.sh | sh -s email={替换为你的邮箱,例如 email=pki@zaochih.com}
对于访问 GitHub 存在困难的中国大陆用户,可使用以下替代方式:
curl https://jsd.licaoz.com/gh/zaochih/get.acme.sh@master/index.sh | sh -s email={替换为你的邮箱,例如 email=pki@zaochih.com}
如果你倾向于使用 wget,则可以使用:
wget -O - https://get.acme.sh | sh -s email={替换为你的邮箱,例如 email=pki@zaochih.com}
同样的,对于中国大陆用户,可使用:
wget -O - https://jsd.licaoz.com/gh/zaochih/get.acme.sh@master/index.sh | sh -s email={替换为你的邮箱,例如 email=pki@zaochih.com}
获取 GCP 的 EAB 凭据
完成本步骤需要你拥有一个 Google 账号和一个能够访问 Google 账户服务及 Google Cloud Platform 的网络环境。若还没有 Google 账号,你可前往 这里 注册。
你需要先前往 此处 新建一个项目。记得保留下图红框里的 Project ID,后面要用;如果你看不顺眼系统自动生成的,也可以点击旁边的 Edit 编辑一个。

创建好 project 后,选中它,找到屏幕右上角的那个长得像终端一样的图标。如果你正在使用拥有键盘的设备,也可以先后按下 G 和 S 键以打开 Cloud Shell。
如果一切正常,你应该能看到如下的消息:
Welcome to Cloud Shell! Type "help" to get started, or type "gemini" to try prompting with Gemini CLI.
Your Cloud Platform project in this session is set to gts-certificates.
Use `gcloud config set project [PROJECT_ID]` to change to a different project.
zaochih@cloudshell:~ (gts-certificates)$
其中,gts-certificates 应该是你刚才创建的项目 ID。如果没有项目相关信息,你可以通过运行 gcloud config set project [PROJECT_ID] 来切换到那个项目。
打开 Cloud Shell 后,分别运行下面三个命令:
# 给自己授权
gcloud projects add-iam-policy-binding {刚才记下的 Project ID} \
--member=user:{你刚才登录 GCP 的 Google 账号的邮箱} \
--role=roles/publicca.externalAccountKeyCreator
# 启用 Public CA API
gcloud services enable publicca.googleapis.com
# 生成 EAB Key
gcloud publicca external-account-keys create
运行完最后一条命令后,你应该能得到类似这样的返回消息,请保留其中的 b64MacKey 和 keyId 字段内容:

zaochih@cloudshell:~ (gts-certificates)$ gcloud publicca external-account-keys create
Created an external account key
[b64MacKey: 一串字母、数字、下划线组合而成的字符串
keyId: 一串字母和数字组合而成的字符串]
在本地注册 ACME 账户凭据
运行下面这条命令:
acme.sh --register-account \
--server google \
-m {你接收 CA 通知的邮箱;如果你刚才安装的时候没有省略 "-s email" 字段,则可以省略此处的 "-m"} \
--eab-kid "{你的 keyId}" \
--eab-hmac-key "{你的 b64MacKey}"
如果一切正常,你应该能得到以下的控制台输出:
[这里是时间] Account key creation OK.
[这里是时间] Registering account: https://dv.acme-v02.api.pki.goog/directory
[这里是时间] Registered
[这里是时间] ACCOUNT_THUMBPRINT='一串字母、数字、下划线组合而成的字符串'
此时 ACME 账户已经注册,凭据已经生成;该小节告一段落。
获取阿里云 RAM 子用户 AccessKey
前往 阿里云 RAM 访问控制控制台,切换到“快速开始”tab,在下方的“创建程序用户”中选择“用于程序访问的超级用户”。

然后自定义一个你能看出来它是做什么的的登录名称(以后不会用到),例如 esa-certificates-workflow。然后点击 执行配置。你将被要求使用短信验证码或人脸识别核验身份。

核验通过后,你将能够看到如上图所示的 AccessKey ID 和 Secret。请妥善暂存它们,我们将在之后的环节用到。
权限最小化
默认情况下,通过此预配选项创建的用户拥有管理账户下所有资源的权限,而这并不符合“权限最小化”原则。因此,我们可以前往 用户页面,找到该用户,点击用户名进入用户管理页面,切换到“权限管理”选项卡并移除系统自动授予的 PowerUserAccess 权限。而后,请点击“新增授权”,并授予该账户 AliyunESAFullAccess 权限。
获取 DNSPod Token
前往 https://console.dnspod.cn/account/token/token,创建一个 DNSPod 密钥。暂存好 ID 和 Token 字段。
创建 GitHub 仓库与部署 GitHub Actions
前往 https://github.com/new 创建一个新私有仓库(除非你想公开你正在做什么),起一个你喜欢的名字。而后在 Actions tab 选择创建 Workflow → “Set up a workflow yourself →”。这会带你来到一个新页面。
默认情况下,新 workflow 的文件名是 main.yml。除非你的仓库是专门只为运行这个 workflow 而创建的,否则,我推荐你更改一个新的文件名,例如 gts-certificates.yml。
本脚本默认使用 DNSPod 域名解析服务,部署至阿里云 ESA;你也可以询问 AI,让其帮你改写为其他你正在使用的平台。
完整复制并将以下内容粘贴至该文件的输入框内。
name: Renew GTS Wildcard Certificate
on:
schedule:
- cron: '45 3 */5 * *' # 每 5 天 03:45 UTC;你可以改为你喜欢的时间,其中第一个数字为分钟,第二个数字为小时
workflow_dispatch:
env:
DOMAIN: something.example # ← 改成你的主域名
jobs:
renew:
runs-on: ubuntu-latest
steps:
# ── 1. 安装 acme.sh ──────────────────────────────────────
- name: Install acme.sh
run: curl https://get.acme.sh | sh -s email=${{ vars.ACME_EMAIL }}
# ── 2. 还原 GTS 账号配置 ─────────────────────────────────
- name: Restore GTS account config
run: |
echo "${{ secrets.ACME_ACCOUNT_B64 }}" | base64 -d \
| tar xz -C ~/.acme.sh
# ── 3. 签发 7 天泛域名证书 ───────────────────────────────
- name: Issue certificate (7 days)
env:
DP_Id: ${{ secrets.DNSPOD_ID }}
DP_Key: ${{ secrets.DNSPOD_KEY }}
run: |
~/.acme.sh/acme.sh --issue \
--dns dns_dp \
-d "*.$DOMAIN" \
-d "$DOMAIN" \
--server google \
--keylength ec-256 \
--valid-to '+7d' \
--force \
--reloadcmd ""
# ── 4. 安装阿里云 CLI ────────────────────────────────────
- name: Install Aliyun CLI
run: |
curl -sL https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-amd64.tgz \
| tar xz -C /usr/local/bin aliyun
aliyun configure set \
--profile esa \
--mode AK \
--region cn-hangzhou \
--access-key-id ${{ secrets.ALI_KEY }} \
--access-key-secret ${{ secrets.ALI_SECRET }}
# ── 5. 部署证书到 ESA ────────────────────────────────────
- name: Deploy certificate to ESA
run: |
CERT_DIR=$(echo ~/.acme.sh/*.${DOMAIN}_ecc)
CERT=$(cat ${CERT_DIR}/fullchain.cer)
KEY=$(cat ${CERT_DIR}/*.${DOMAIN}.key)
aliyun --profile esa esa SetCertificate \
--SiteId "${{ vars.ESA_SITE_ID }}" \
--Type upload \
--Certificate "$CERT" \
--PrivateKey "$KEY" \
--Name "wildcard-$(date +%Y%m%d)"
# ── 6. Bark 通知:成功 ───────────────────────────────────
- name: Notify success
if: success()
run: |
curl -s -X POST "https://api.day.app/${{ vars.BARK_KEY }}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"✅ 证书已更新\",
\"body\": \"*.$DOMAIN 7天证书已签发并部署至 ESA\",
\"group\": \"cert-renew\",
\"sound\": \"bell\"
}"
# ── 7. Bark 通知:失败 ───────────────────────────────────
- name: Notify failure
if: failure()
run: |
curl -s -X POST "https://api.day.app/${{ vars.BARK_KEY }}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"❌ 证书更新失败\",
\"body\": \"*.$DOMAIN 签发或部署出错,请检查 Actions 日志\",
\"group\": \"cert-renew\",
\"sound\": \"alarm\",
\"level\": \"timeSensitive\"
}"
其中用到了这些环境变量:
-
Secrets:
-
ACME_ACCOUNT_B64,可以运行tar czf - -C ~/.acme.sh ca accounts \ | base64 -w 0然后将输出内容粘贴进去。
-
ALI_KEY和ALI_SECRET参考 获取阿里云 RAM 子用户 AccessKey 节。
-
DNSPOD_ID和DNSPOD_KEY参考 获取 DNSPod Token 节。
-
-
Variables:
-
ACME_EMAIL,即你刚才安装时使用的邮箱。 -
BARK_KEY,用于使用 Bark 向你推送证书续期成功与否的消息;为 api.day.app 后面那一串 -
ESA_SITE_ID,用于指定证书上传的 ESA 站点。可在 ESA 控制台 进入具体站点后查看左上角的“站点 ID”。
-
实际效果
blog.licaoz.com、dl.licaoz.com 与 jsd.licaoz.com 等由阿里云 ESA 加速的站点现已使用通过该自动化流程创建的 7 日证书,欢迎中国大陆的朋友查看本站证书详情了解。
评论
评论由 GitHub Discussions 提供。参与讨论会受到 GitHub 隐私声明约束。 GitHub 隐私声明
正在加载评论区
评论区由 giscus 提供,稍等片刻即可查看和参与讨论。