猎奇向:如何自动化地签发与轮替 Google Trust Services 的 7 日证书
Contents
Language Unavailable
This article is not available in the current language. Showing the Simplified Chinese version instead.
前情提要
近几日主播将博客和 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 日证书,欢迎中国大陆的朋友查看本站证书详情了解。
Comments
Comments are powered by GitHub Discussions. Joining the discussion is subject to GitHub’s privacy statement. GitHub Privacy Statement
Loading comments
The discussion is provided by giscus and should be ready in a moment.