一次普通请求,泄露了什么
小美打开 Flo 想查自己的经期记录。如果手机直接连服务器,服务器日志里会静静记下这一串—— 注意,哪怕她没登录,这些信息也足以把她「认出来」:
# 服务器看到的(普通 HTTPS)
ipAddress: 192.0.2.33 # 你在哪
ASN: 7922
tlsCipher: AEAD-CHACHA20-POLY1305-SHA256 # 你手机的指纹,可能唯一
tlsVersion: TLSv1.3
Country / Region / City: US / California / Campbell # 精确到城市
body: "查询我这个月的周期记录" # 你查了什么
问题不只是「服务器知道了你查经期」。而是:同样的 IP + 同样的设备指纹,会让服务器把几十次请求 串成同一个人的行为轨迹——你什么时候查、查了几次、有没有变化,全都能对上号。 就算不登录,也一样能被追踪。
OHTTP 的两跳:Relay 与 Gateway
OHTTP(Oblivious HTTP,IETF 标准 RFC 9458)的思路很干脆:把一次请求拆成两跳, 让身份和内容分别落在两个不同的人手里。
- Relay(中继):看到客户端身份(IP、TLS 指纹),但只看到一坨密文,盲转发。
- Gateway(网关):负责解密请求、加密响应,看到明文内容,但看不到客户端是谁。
请求体用 HPKE(混合公钥加密)封装,只有客户端和应用服务器能解开;Relay 拿到的永远只是噪声。 于是形成「双盲」:Relay 只有身份,Gateway 和应用服务器只有内容,没有一方同时掌握两者。
三个场景,一次说清
没有 OHTTP
正确的 OHTTP(Relay 与 Gateway 由不同方运营)
两家都放在 Cloudflare(隐私模型破功)
这也是这次发布的核心:过去,服务器已经跑在 Cloudflare 上的客户,没法用 Cloudflare 的 Relay—— 因为那样 Cloudflare 会同时看到元数据和明文。现在客户可以按架构二选一,既不破坏双盲,也不用自建网关。
现实中已经在跑的例子
- Flo Health 匿名模式:让用户访问健康数据时,不让请求可关联到个人身份。
- Apple Private Cloud Compute:把 AI 推理请求与用户身份解绑。
- Apple LiveCallerID:来电识别很敏感——「你正在查一个陌生号码」本身就是信息。用 OHTTP 后, 查询动作与设备身份被拆开放进两跳里。这正是文章强调「接第三方 OHTTP 请求该选 Gateway」的场景。
Cloudflare 的五个工程决策
全边缘部署
网关跑在 Cloudflare 全球每台边缘服务器上。Relay→Gateway 的跳数被压到最低;如果源站也在 Cloudflare, 解密与回源甚至能落在同一台机器上。
密钥全托管
HPKE 公钥配置由平台维护,公钥挂在 /.well-known/ohttp-gateway。客户端还能从不同 IP 下载密钥,进一步防关联。
先鉴权,再解密
Cloudflare Access 在解密之前执行策略:mTLS、静态服务凭证、自定义外部逻辑,用来只放行可信 Relay。
拒绝自破双盲
如果请求来自 Cloudflare Workers 或被 Cloudflare 代理的源站,网关会拒绝解密——防止客户不小心把 Relay 和 Gateway 放在同一家。
绑定 zone
网关只服务自己的域名:foo.example.com 能发,wikipedia.com 不能,避免有人把你的 zone 当成打别人域名的跳板。
支持分块传输
同时支持标准与 chunked OHTTP。官方推荐 chunked —— 网关可以按「块」增量处理,延迟更低。
怎么接入
- 作为付费插件加到你的 zone,几点击启用;端点固定在
https://your-zone.com/.well-known/ohttp-gateway。 - 容量自动伸缩,普通 HTTP 流量照常直达源站,不经过网关。
- 需要自己实现 OHTTP 客户端(参考 ohttp.info 与 Cloudflare 的示例库),并自带一个 Relay——Relay 可以跑在任何基础设施上。
- 上线后用 Cloudflare 开源的
pvcli客户端做测试与调试。
一个必踩的坑
{"email":"xiaomei@example.com", …},那么 Gateway 和应用服务器照样看得一清二楚——
前面所有加密全部白做。所以「别在请求体里塞能识别身份的信息」是使用 OHTTP 的硬要求。