通过代理传输 UDP 与 QUIC

通过代理传输 UDP 与 QUIC

代理可能通过 Web 检查,却仍无法承载程序需要的流量。例如,游戏可能通过代理完成登录,却无法交换游戏状态更新;网站可能正常打开,但浏览器使用的是 HTTP/2 而非 HTTP/3。这些操作需要不同的网络能力。

更全面的协议选择,见SOCKS 与 HTTP 代理。本文说明 UDP 如何通过代理到达目标、QUIC 对这条路径有何要求,以及如何确认应用正在使用预期传输方式和出口 IP。

UDP、QUIC 和 HTTP/3 分别做什么

应用与网站交换 UDP 数据报。放大的数据报示意图展示 HTTP/3 数据位于 QUIC 内部,而 QUIC 由 UDP 承载。这是协议层次,不是三台服务器。

TCP 提供有序字节流。数据丢失时,它会安排重传,并在缺口补齐前暂不向应用交付后续字节。UDP 发送彼此独立的消息,称为数据报。UDP 本身不保证交付、顺序,也不防止重复;如何处理这些情况,由使用它的软件决定。

这样,应用就可以选择不同的行为。语音应用可能丢弃到达太晚、已无法播放的音频包;游戏可能更重视最新位置更新,而不是旧更新;DNS 交互可能只包含简短的一问一答。实际传输方式取决于程序:这些例子不意味着每次通话、每款游戏或每个 DNS 请求都使用 UDP。

QUIC 是构建在 UDP 之上的传输协议。它增加了连接建立、丢失数据恢复、拥塞控制和可靠流。通过可靠 QUIC 流传输的文件,可以完整、有序地到达。数据包在 UDP 数据报内传输,并不会消除 QUIC 所提供的可靠性。

QUIC 还允许多个流共用一条连接。当一个流的数据丢失时,数据已到达的其他流可以继续。与让所有流共用一条有序 TCP 连接相比,这可以减少等待。结果仍取决于路由、丢包、服务器和客户端;仅选择 QUIC,并不保证应用更快。

HTTP/3 在 QUIC 上承载 HTTP。HTTP/1.1 和 HTTP/2 通常使用 TCP。三者都能服务 HTTPS 网站,因此地址中的 https:// 既不能标识 HTTP 版本,也不能确认使用了 UDP。

加密是独立属性。UDP 不会加密数据。QUIC 使用 TLS 1.3 为应用流量建立保护。普通 UDP 应用可能使用其他安全机制,也可能不加密载荷;通过代理转发并不会自动增加这种保护。

SOCKS5 如何承载 UDP

SOCKS5 定义了 UDP 中继:接受客户端数据报、将载荷发给目标,再返回响应的服务。客户端先通过 TCP 安排转发,随后控制连接与数据报路径并行存在。

四个阶段:TCP 连接和身份验证、UDP ASSOCIATE 与中继端点、经中继传输 UDP 请求和响应,以及为该关联保持 TCP 连接打开。
  1. 客户端通过 TCP 连接 SOCKS5 服务器,并完成约定的身份验证流程。
  2. 客户端请求 UDP ASSOCIATE。如果代理接受,响应会提供中继地址和 UDP 端口。
  3. 客户端向中继发送带 SOCKS 头的数据报,其中标识目标。中继转发载荷之前移除该头部。返回响应时,中继先加上 SOCKS 头,再把数据报发回客户端。
  4. 使用中继期间,客户端保持 TCP 控制连接打开。关闭它,就会结束由该连接安排的 UDP 转发。控制连接与 UDP 转发之间的这种关系,称为 UDP 关联。

中继使用的地址或端口,可能不同于代理设置中填写的 TCP 端点。直接向那个熟悉的端点发送原始 UDP,并不会完成 SOCKS5 交互。仅实现 CONNECT 的客户端,可以使用 SOCKS5 传输 TCP,却缺少这里所需的流程。SOCKS4 没有定义这种 UDP 中继功能。

这解释了一种常见的部分成功情况:防火墙允许 TCP 连接和身份验证,却阻止发送到协商中继的数据报。密码有效,但应用仍收不到 UDP 响应。路径的两个部分都必须可用。

HTTP 代理能转发 UDP 吗?

普通 HTTP CONNECT 请求要求代理建立到目标的 TCP 连接,并承载字节流。它不会建立 UDP 转发。使用 TLS 连接 HTTPS 代理,可以保护该连接,但不会改变所请求隧道的类型。

HTTP 另有一种 UDP 隧道机制,通常称为 CONNECT-UDP,是 MASQUE 的组成部分。客户端和服务器兼容时,客户端请求通往 UDP 目标的隧道。代理向目标转发数据报,并将响应传回。这要求两端明确支持。

普通 CONNECT 建立到目标的 TCP 连接。受支持的 CONNECT-UDP 机制向目标转发 UDP。客户端和代理都必须支持这个附加机制。

在客户端到代理的连接上,如果支持 HTTP/3 和所需扩展,HTTP 数据报可以由 QUIC DATAGRAM 帧承载。它们也可以封装为 capsule,即可靠 HTTP 流中的带帧消息,包括基于 TCP 的 HTTP/2。此时,即使路径的第一段使用 TCP,代理仍然向目标发送 UDP。

这种选择会影响时序。如果 TCP 连接丢失数据,后续字节可能等待恢复,导致其中承载的数据报延迟。隧道可能正常工作,却不适合某种实时负载。仅在程序中填写一个 http:// 代理地址,并不会启用这些额外 UDP 机制。

哪条连接使用 QUIC?

“QUIC 代理”这个说法需要结合上下文。它可能描述连接代理使用的传输方式,也可能描述应用与目标之间的连接。这是交互中的不同部分。

QUIC 的使用位置代理做什么能够确认什么
客户端与代理之间通过 QUIC 接受连接。例如,通过 HTTP/3 发送普通 CONNECT,仍是要求代理建立到目标的 TCP 连接。到代理的连接使用 QUIC。网站连接需要单独检查。
应用与目标之间,通过 UDP 中继使用 SOCKS5 UDP 转发或合适的 HTTP UDP 隧道,转发承载应用 QUIC 数据包的数据报。如果整条路径正常,应用就能与目标建立 QUIC。HTTP/3 还必须由两端支持并实际选用。

普通 UDP 中继中,代理无需终止应用的 QUIC 连接。它只转发数据包,应用和目标仍是这次加密交互的端点。代理仍然知道流量转发到哪里,也能观察流量大小和时间。

应用支持为什么重要

程序需要实现服务提供的转发方法。一个 SOCKS5 复选框,不能说明是否支持 UDP ASSOCIATE。同样,程序可能在直接连接时支持 HTTP/3,但代理连接只支持 TCP。

两个示例使用同一个已启用 UDP 的代理。第一个客户端只发送 TCP,无法启动 UDP 流程;第二个客户端支持 UDP ASSOCIATE,并与中继交换数据报。

Chrome 是一个具体例子:它内置的 SOCKS5 支持会代理基于 TCP 的 URL 请求,但不会通过 SOCKS5 中继 UDP。使用这个设置加载页面,无法测试服务的 UDP 中继。这项限制针对的是该特定客户端模式;其他客户端或外部路由软件可能具备不同能力。

还应检查设置的覆盖范围。同一应用中的登录、文件下载、语音和游戏交互,可能使用不同网络组件。为 Web 请求配置的代理,可能只覆盖其中一部分。系统代理设置也取决于各程序是否遵循。

重定向其他应用流量的程序,如果支持 UDP 和服务所用的转发方法,就可以把 UDP 发往代理。仅重定向 TCP 还不够。如果程序使用虚拟网络接口,路由规则会决定哪些流量进入该接口。应测试完整组合:应用、路由程序和代理端点。

回退、失败与直接连接

所需路径不可用时,结果取决于应用能力和策略。如果只问“是否打开”,下面三种结果可能看起来很相似:

观测结果如何理解
操作失败所需交互未完成。应在客户端、隧道建立、网络路径或目标处定位故障。
网站通过 HTTP/2 或 HTTP/1.1 打开网站交互使用基于 TCP 的 HTTP 版本。Web 访问正常,但不能确认到该网站的 HTTP/3 正常。独立的到代理连接可能使用另一种传输方式。
UDP 交互直接成功流量没有经过预期代理路径。必须单独检查它的出口地址。

切换到基于 TCP 的 HTTP 版本称为回退。QUIC 不可用时,这可以保持正常浏览。客户端会打开另一条连接,QUIC 本身并不会变成 TCP。因此,禁用 QUIC 可能帮助 Web 应用使用可用的 TCP 路径,却不能为必须使用 UDP 的功能提供 UDP。

直接连接目标是一项路由决定。不支持的 UDP 并不都会直接发送:软件可能停止、尝试其他传输方式,或遵循配置的绕过规则。如果任务的全部流量都必须经过代理,应使用在该路径失败时停止的模式,并在代理不可用时检查其行为。

为什么 UDP 在建立后仍可能停止工作

四个场景分别展示:端口筛选阻止 UDP、空闲后状态过期、隧道头部导致超出大小限制,以及数据包丢失或延迟。

端口规则与返回路径

TCP 端口 443 和 UDP 端口 443 属于不同传输协议。允许其中一个,不会开放另一个。对于 SOCKS5,客户端必须能够访问返回的 UDP 中继端点;中继也必须获准访问目标 UDP 端口。HTTP/3 可以使用 443 以外的端口,因此应检查应用实际使用的端点。

响应必须通过中继、防火墙以及可能存在的 NAT 返回。NAT 在网络之间转换地址,通常也转换端口。仅发送了一个数据报,不能证明返回路径正常。网络变化可能改变客户端公网 IP 或端口映射。SOCKS5 中继必须拒绝源 IP 与该 UDP 关联记录不符的数据报,因此地址改变后,可能需要重新建立关联。

暂停与状态过期

中继和 NAT 设备为 UDP 交互保存临时记录。暂停期间,这些记录可能过期。通话或会话最初可以正常工作,之后却失去 UDP 路径,直到客户端重新建立。保持同一出口 IP 不能防止这种情况:转发 UDP 所需状态与服务的 IP 分配,是两回事。

数据报大小与 MTU

MTU 是网络链路无需分片即可承载的最大 IP 数据包大小。一条路径可用的大小,受沿途最小限制约束,称为路径 MTU。IP、UDP 和额外隧道头部都占用包内空间。小测试消息可能通过,较大数据报却被丢弃,因此应用必须考虑完整路径及新增头部。

QUIC 路径必须能够承载至少 1,200 字节的 UDP 载荷,不计 IP 和 UDP 头部。客户端会把承载 QUIC Initial 数据包的 UDP 数据报填充到至少这个载荷大小。客户端到代理这一段的代理头部还需要额外空间。这不是建议把接口 MTU 设置为 1,200,而是在解释:为什么小型 DNS 请求和响应可能正常,较大的 QUIC 握手却无法通过。

延迟、丢包与负载

对于通话或游戏,交付时间可能与能否交付同样重要。延迟波动、丢包和包速率限制,都可能影响原本正常工作的 UDP 中继。单靠带宽不能描述这些条件。代理为路径增加一个环节;根据网络和负载不同,它既可能改善,也可能降低性能。

如何验证通过代理的 UDP 和 HTTP/3

测试实际准备使用的应用,或实现相同转发方法的客户端。有效测试应针对同一次交互,检查响应、传输方式和出口地址。

  1. 选择会响应所需流量的目标。使用实际应用服务器,或可控的 UDP 响应服务。对于 HTTP/3,应选择已知支持它的目标。任意 UDP 端口没有响应,并不能说明哪一部分失败。
  2. 确认中继或隧道已被接受。使用 SOCKS5 时,查看 UDP ASSOCIATE 结果,以及返回的中继地址和端口。使用 HTTP UDP 隧道时,确认该隧道已被接受。身份验证本身不涵盖这一步。
  3. 完成一次请求与响应。可控的响应服务可以返回请求标识符,并记录它看到的源 IP。这样可以检查该次 UDP 交互使用的出口。单独的 Web IP 检查,只能覆盖它自己的请求。
  4. 对于 HTTP/3,应在与目标的交互中确认协议。在客户端或服务器连接日志中,查找 HTTP/3 或 h3,同时保留流量经过代理的证据。如果测试客户端有仅使用 HTTP/3 的模式,它可以暴露被自动回退掩盖的故障。
  5. 在相关条件下重复测试:实际数据报大小、持续流量,以及暂停后恢复活动。如果任务禁止直接流量,还应测试代理不可用时会发生什么。把客户端版本和连接设置与结果一起保存。

抓包可以帮助识别路由。标准 SOCKS5 UDP 转发会向协商好的中继发送数据报。HTTP UDP 隧道则可能使用外层 TCP 连接,因此第一段路径上没有 UDP,并不足以证明失败。

远程 DNS 和 ping 测试的是不同事情。代理可以为 TCP 连接查询主机名,却不转发应用的 UDP 流量。普通 ping 使用 ICMP。两种测试都不能替代在预期代理路径上观测到的 UDP 请求和响应。

何时值得选择 UDP 支持

先确定任务需要什么流量。基于 HTTP/1.1 或 HTTP/2 的网站与 API 工作,可能完全由仅支持 TCP 的代理满足。HTTP/3 测试、UDP 媒体和其他依赖 UDP 的功能,则需要合适的中继或隧道,以及能够使用它的客户端。

向服务商询问支持哪种 UDP 转发方式和客户端配置。然后检查允许的目标和端口、数据报大小限制、空闲行为,以及与负载相关的流量或包速率限制。如果 TCP 和 UDP 必须使用相同出口 IP 或位置,应在实际应用中验证。共用账户或成功通过 Web 检查,并不能证明出口行为相同。

返回知识库