Kiln 怎么搬上 Cloudflare + 加登录

把刚才那一长串 Cloudflare / Cloud Run 操作,用大白话 + 图讲清楚:每一步在干嘛、为什么非做不可、它们怎么环环相扣。

0我们到底想要什么

Kiln(那个游戏生成观测台)跑在 Google Cloud Run 上,它自带一个又长又难记的网址 kiln-platform-…run.app。我们想要的是三件事:

核心难题:Cloud Run 那个 run.app 网址就像房子的后门。如果它对外开着,你前门装再好的锁也没用——别人绕后门就进来了。所以全部操作的本质就两句话:开一道带门禁的正门(kiln.luddi.ai),同时把后门(run.app)锁死。

团队成员 浏览器 你 / 运维 直连调试 正门 · Cloudflare Access 登录闸 先邮箱登录才放行 后门 · run.app 只认 ?key= 钥匙 没钥匙 → 拒绝(401) Kiln 应用 Cloud Run 生成 / 观测
两道门都有锁,都通向同一个 Kiln 应用

1一个请求是怎么走完全程的

先看"正常团队成员打开网页"这条路,后面每个操作都是为了让这条链路成立:

① 浏览器 开 kiln.luddi.ai ② DNS 查询 → 指向 Cloudflare ③ Cloudflare 边缘 国内连得通 ④ Access 登录闸 弹邮箱登录 只放行 @hakko.ai ⑤ 盖"通行证" 签名头 Cf-Access-Jwt-Assertion ⑥ Cloud Run 域名映射认得 Host = kiln.luddi.ai ⑦ Kiln 验通行证 合法 → 放行 返回游戏界面 ✓ 进入
浏览器 → DNS → Cloudflare → 登录 → 盖通行证 → Cloud Run → Kiln 验证 → 进入
Cloudflare Google Cloud Run Kiln 应用

下面把这条链路上的每一个操作拆开讲——为什么要做它

2域名映射:让 Cloud Run "认识" kiln.luddi.ai

Cloud Run 同一台机器上可能跑很多服务,它靠请求里的 Host(你访问的域名)来分辨该把请求交给谁。它默认只认自己那个 run.app 网址。你直接拿 kiln.luddi.ai 去敲它,它一脸懵:"没这域名" → 返回 404。

域名映射就是去 Cloud Run 登记一句话:"kiln.luddi.ai 这个域名,请交给 Kiln 服务"。登记后它才认得。

为什么要先做"域名验证"(加一条 TXT 记录):Google 不能让任何人随便把不属于自己的域名映射到自己的服务(否则我就能把 你的银行.com 映射到我的钓鱼网站)。所以它要你先证明"luddi.ai 确实是你的"——往 luddi.ai 的 DNS 里加一条只有域名主人能加的 TXT 记录,Google 一查到,就信你了。这一步是一次性的。

📌 我们这步:`gcloud ... domain-mappings create` → Google 通过 Cloudflare 一键加 TXT 验证 → 映射建成,它回了一条要配的 DNS:kiln → ghs.googlehosted.com

3DNS:把 kiln.luddi.ai 这个名字指向某个地方

DNS 就是互联网的"通讯录":输入一个域名,它告诉浏览器该去哪个地址。我们加了一条记录:

kiln  CNAME  ghs.googlehosted.com  (Cloud Run 的入口)
为什么:没有这条记录,浏览器根本不知道 kiln.luddi.ai 在哪、连都连不上。有了它,访问 kiln.luddi.ai 就会被引导到 Cloud Run(中间还会经过 Cloudflare,见下一节)。

4先"灰云"再"橙云":一个关键的先后顺序

Cloudflare 的每条 DNS 记录有个开关:灰云(DNS only)= 只做通讯录、流量不经过 Cloudflare;橙云(Proxied)= 流量先进 Cloudflare 再转发。这俩在我们这儿用途完全不同:

灰云(签证书阶段) 浏览器 Google 直连 国内 ✗ 被墙 ✓ 但 Google 能验 DNS、签出 HTTPS 证书 橙云(日常使用) 浏览器 Cloudflare 国内 ✓ Google ✓ 连得通 + ✓ Access 登录闸能拦
灰云用来"签证书",橙云用来"日常访问 + 登录拦截"

为什么必须先灰云?

Cloud Run 要给 kiln.luddi.ai 申请一张 HTTPS 证书(否则浏览器会报"不安全")。申请时 Google 要通过公网 DNS 亲眼看到这个域名确实指向它自己,才肯签。灰云时公网看到的就是 ghs.googlehosted.com(Google 自己)→ 验得过、证书签得出。
如果一上来就橙云,公网看到的是 Cloudflare 的 IP,Google 验不了 → 证书永远卡住。

为什么签完要翻橙云?

  • 国内能访问:直连 Google 在国内常被墙(你那次 ERR_CONNECTION_CLOSED 就是),走 Cloudflare 中转才连得通——luddi.ai 本身就是这么做的。
  • 登录闸才生效:Cloudflare Access 只能拦"经过 Cloudflare"的流量。不翻橙云,登录这道闸根本插不进去。
顺带 SSL/TLS = Full:这个开关保证"Cloudflare → Cloud Run"那一段也是 HTTPS 加密(而不是明文)。全程加密。

5Cloudflare Access:那道"先登录再放行"的正门

这是整件事的登录闸。我们给 kiln.luddi.ai 建了一个 Access Application,配了一条策略:只放行邮箱以 @hakko.ai 结尾的人(你也可以把自己的邮箱加进去)。

有人访问 kiln.luddi.ai → Cloudflare 先弹出登录页 → 输入邮箱、收验证码登录 → 邮箱符合策略才放进去。不符合的,连 Kiln 的门都摸不到就被 Cloudflare 拦下了。

关键机制 ——"通行证":登录通过后,Cloudflare 会在转发给 Cloud Run 的请求里,盖一个它签名的通行证(一个叫 Cf-Access-Jwt-Assertion 的请求头)。这个签名别人伪造不了——这正是下一步"锁后门"的钥匙。

6应用验"通行证" + 运维"钥匙":把后门锁死

光有正门还不够——别人还是可能直接敲那个 run.app 后门。所以 Kiln 应用自己也加了一道判断:每个进来的请求,必须满足下面之一,否则一律 401 拒绝。

收到请求 有合法 CF 通行证? (走了 kiln.luddi.ai 邮箱登录) 有运维钥匙 ?key= ? (直连 run.app 调试用) 两个都没有 ✓ 放行 ✓ 放行 ✗ 401 拒绝
应用收到请求后的"三选一"判断
后门为什么就锁死了:直连 run.app 的请求,没经过 Cloudflare,就没有那张签名通行证;除非它带着运维钥匙 ?key=,否则一律 401。于是:普通人走正门(邮箱登录),你/运维走后门(钥匙),其他人哪儿都进不去。

7为什么这些步骤缺一不可(它们怎么咬合)

域名映射没有它 → Cloud Run 不认 kiln.luddi.ai → 404。(它是终点能收货的前提)

DNS 记录没有它 → 浏览器找不到 kiln.luddi.ai → 连不上。(它把名字指到入口)

先灰云没有它 → 证书签不出来 → 浏览器报不安全 / 连不上。(它让 HTTPS 成立)

后翻橙云没有它 → 国内访问不了 + 登录闸插不进。(它让"可访问"和"可拦截"同时成立)

Access 登录没有它 → 谁都能进。(它是正门的锁,并产出"通行证")

应用验通行证 + ?key没有它 → run.app 后门大开。(它把后门锁死)

所以这是一条环环相扣的链:DNS 把人引到 Cloudflare → Cloudflare 验人、盖通行证 → Cloud Run(靠域名映射)收下 → Kiln(靠验通行证)放行。任何一环缺了,要么连不上、要么不安全、要么没拦住。

8现在的状态 & 怎么用

✓ 正门:浏览器开 https://kiln.luddi.ai → 邮箱登录(@hakko.ai)→ 直接进,不用记钥匙。

✓ 后门(运维):直连 run.app/?key=… 仍可用,给你/运维不走登录时调试。

✓ 其他人:既没登录、又没钥匙 → 401,进不来。AI 费用不会被白嫖。

一个未来的小提醒:Cloud Run 的 HTTPS 证书续期需要再"验一次 DNS",长期橙云时,续期前可能要临时把 kiln 记录翻一下灰云、等续期完再翻回橙云。不影响现在使用。