Skip to content

CDN代理WebSocket时开启Early Data的风险 #46

Description

@RememberOurPromise

前情提要:CDN,监控


WebSocket Early Data

如果客户端路径中包含 ed 参数(如 /mypath?ed=2560),将会启用 Early Data 以降低延迟,在升级的同时使用 Sec-WebSocket-Protocol 头承载首包数据,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。推荐值为 2560,最大值为8192,过大的值可能导致部分兼容问题,如果遇到兼容性问题,可以尝试调低阈值。

风险

正常情况下,WebSocket 建立连接后的数据帧(message frame)不会被 Cloudflare 的 Observability/Logs 记录——它只记录 HTTP 请求的 header、状态码、耗时等"元数据",不主动记录帧内容。

但 ?ed=2560 这类 Early Data 优化,是把首包数据 base64 编码后塞进 Sec-WebSocket-Protocol 这个请求头字段里,目的是省一次 RTT。代价是:这段数据从此被系统当作"请求元数据"处理,而不是"应用层负载"——于是它就进入了 Observability、Logpush 等一切会持久化 header 的日志管线,变成可检索、可导出、可留存的结构化记录。

Image

一个常见误区

"我用了 wss(TLS)所以是安全的"——这个前提本身就不成立,而且和这条泄露路径无关。原因是:

Early Data 真正引入的额外风险,是让这段本来"过一下就走、默认不落盘"的首包数据,变成了"被专门记录进日志系统"的数据——暴露面从"理论上可见"变成了"持久化可查询",这是质的差别。

如果内层 VLESS 没有开启加密,这个首包通常就是 VLESS 请求头本身(UUID、目标地址、端口等路由信息,某些实现下还可能带上首段应用层数据如 TLS ClientHello/HTTP 请求),相当于把"你在用这套代理连去哪里"明文写进了 Cloudflare 自己的日志表里,可被有日志访问权限的运维人员、Logpush 导出目标、日后的合规/取证请求读取到。

证据一:2025 年 11 月 18 日全网宕机复盘

这是 Cloudflare 六年来最严重的一次核心流量中断事故。复盘原文明确提到,故障期间除了 HTTP 5xx 错误外,还出现了明显的延迟上升,原因是内部的调试与可观测性系统消耗了大量 CPU,这些系统会在出现未处理错误时自动为其附加额外的调试信息。

这句话本身就是关键证据:它说明 Cloudflare 存在一套自动化、常态运行的内部可观测性系统,会针对每个出错的请求自动采集并附加详细调试信息——这与用户截图里看到的"完整 header(含 Sec-WebSocket-Protocol)被记录进 Overview/Logs"是同一类基础设施在起作用。

复盘时间线里还能看到工程师是如何排障的:11:32 到 13:05 期间,团队通过内部系统旁路对 Workers KV 和 Access 进行了排查和绕过操作,过程中人工调查从 11:32 开始,并在 11:35 建立了事故处理会议——这些"人工调查"依赖的正是内部日志/指标/追踪系统,而不是等外部用户上报。

证据二:Cloudflare 自己的日志分析技术博客(ClickHouse)

Cloudflare 在一篇讲解其日志分析架构的博客中直接承认:当 Cloudflare 处理的请求出现错误时,相关信息会被记录进内部的 requests_error 管线,这些错误日志被用来帮助排查客户特定问题或全网性问题。

这等于官方明确说明:请求级别的日志数据不是只存不用的"黑盒",而是内部工程师日常排障时会主动查询的数据源。

说明

上面两篇文章证明的是机制层面——Cloudflare 存在成规模、自动化的请求级调试/日志系统,且明确承认内部工程师用它排障。但没有哪篇公开复盘会写"Sec-WebSocket-Protocol 字段"这种客户级明细,这类信息属于内部操作细节,Cloudflare 不会在公开复盘里披露到这个粒度。

Cloudflare 自己的复盘和技术博客证实这套日志/调试体系是内部工程师在故障排查中的常规查询对象,而官方进行的排查滥用与封禁可能与此机制有关。

解决方法

  1. 开启VLESS-ENC

  2. 并且停用WebSocket Early Data

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions