代表性面试主题

系统设计面试:如何设计基于 MASQUE 的 CONNECT-UDP 代理?

系统设计困难
Offer.cc 编辑团队发布 更新

题干

请设计一个让移动客户端通过 HTTPS 代理访问 UDP 服务的系统。说明 CONNECT-UDP 建隧道、HTTP/3 数据承载、鉴权、限流、DNS、故障转移、滥用防护和验证指标。

题干与适用场景

移动客户端只能稳定访问 HTTPS,但语音、游戏和实时探测依赖 UDP。请设计一个代理,让客户端通过 HTTP 建立到目标 UDP 主机的隧道,并覆盖连接生命周期、数据转发、鉴权、限流、DNS、故障转移和回退。

RFC 9298 定义了 CONNECT-UDP 方法和代理模板;RFC 9297 定义 HTTP Datagrams 与 Capsule Protocol,分别承载不可靠数据和可靠控制信息。高质量回答要把协议语义、代理资源和安全策略分层,不能把“加了 TLS”当成完整的滥用防护。

面试官考察点

  • 能否区分 CONNECT-UDP 的隧道建立、数据转发和关闭。
  • 是否说明 HTTP/3 Datagram 与 Capsule 的适用边界及无 Datagram 时的回退。
  • 是否设计目标地址白名单、端口策略、用户鉴权和租户配额。
  • 是否处理 DNS 解析、超时、重试、半开连接与故障转移。
  • 是否给出带宽、并发、丢包、延迟、滥用和成本指标。
  • 是否知道代理不能保证 UDP 的可靠性、顺序或端到端加密语义。

回答前需要澄清的问题

  1. 客户端和代理是否都支持 HTTP/3 Datagrams,还是必须兼容 HTTP/2?
  2. 目标是企业内网访问、实时媒体,还是开放互联网代理?目标决定白名单和滥用风险。
  3. 客户端是否提供目标主机名,代理是否代做 DNS?解析结果的生命周期和隐私要求是什么?
  4. 单个用户允许多少隧道、带宽和并发 UDP 流?是否需要按区域就近接入?
  5. 允许的最大空闲时间、单包大小和总会话时长是多少?

30 秒回答框架

我会先把代理限定为已鉴权的目标集合,再用 CONNECT-UDP 建立会话。控制消息走 Capsule,支持时用 HTTP/3 Datagram 承载 UDP 数据;不支持时回退到可靠封装或拒绝,不假装提供相同延迟。数据面按租户做令牌桶、并发和空闲超时,DNS 在受控解析器完成并绑定会话。节点异常时只重建可重放的会话,避免复制不可重放数据。验收同时看 p99 延迟、丢包、建连成功率、资源占用、拒绝率和滥用告警。

分步骤深入解答

1. 建立会话与状态机

客户端向代理发送 CONNECT-UDP,请求目标主机和端口。代理先验证身份、策略和配额,再解析目标并创建会话。状态至少包括待鉴权、已连接、排空和关闭;每个状态都设置超时与原因码,防止半开会话长期占用资源。

http
CONNECT / .well-known/masque/udp/example.test/443 HTTP/3
Host: proxy.example

实际实现应遵循 RFC 9298 的请求模板和编码规则,示例只表达意图,不替代完整的协议字段。

2. 划分控制面与数据面

Capsule Protocol 适合可靠的会话控制、错误和关闭通知;HTTP/3 Datagram 适合不要求重传的 UDP 数据。代理把每个 Datagram 映射到对应的 UDP socket,并限制单包大小、队列深度和突发量。若路径不支持 Datagram,应明确回退到可靠封装或返回不支持,避免把可靠传输引入实时路径却不计成本。

3. 设计鉴权与目标策略

代理先验证短期令牌、租户状态和设备绑定,再依据目标域名、IP 段、端口及用途做 allowlist。禁止客户端任意指定内网地址、环回地址、云元数据地址或高风险端口。DNS 解析应在受控解析器完成,记录解析版本和 TTL,避免重新解析把同一会话悄悄切到不同租户边界。

4. 限流、配额与成本控制

按租户同时限制隧道数、每秒包数、字节速率、单会话时长和空闲时间。入口和出口都使用令牌桶,超过配额返回可观测的拒绝原因;节点还要保留全局保护阈值。统计代理 CPU、内核 socket、队列、出口带宽和每会话成本,避免只限制 HTTP 请求数而放过长时间 UDP 流。

5. 处理故障与回退

对建连失败、目标不可达、DNS 超时和代理过载分别记录原因。新会话可在健康节点重试;已发送的 UDP 数据通常不可安全重放,因此故障转移应只恢复控制状态或让上层重新建立会话。客户端不支持 Datagram 时,服务端应根据业务选择可靠封装或明确失败,并在指标中区分两种路径。

6. 观测与安全运营

每个会话记录租户、代理节点、目标策略版本、建立和关闭原因、字节数、包数、丢包估计、p50/p95/p99 延迟及限流事件。日志不得记录完整令牌或敏感载荷。检测端口扫描、异常目标集中度、突发放大和跨租户资源争抢,并准备按租户、目标和区域快速撤销策略。

7. 灰度与验收

先在固定区域和 allowlist 目标灰度,使用对照组比较直连、Datagram 路径和回退路径。压力测试覆盖丢包、乱序、代理重启、DNS 变化、半开连接和超额流量。发布门槛应包含建连成功率、实时请求 p99、丢包率、每会话资源、拒绝误报和滥用告警延迟;任一安全阈值超限就收紧策略或关闭新路径。

高质量示范回答

我会把它做成只服务已鉴权租户和明确目标集合的代理。客户端发起 CONNECT-UDP 后,代理验证令牌、目标和配额,受控 DNS 解析并创建会话。控制消息使用 Capsule;支持 HTTP/3 Datagram 时承载不要求重传的 UDP 数据,并为每个会话设置包大小、队列、速率、空闲和总时长上限。

出口策略阻断内网、环回、元数据和高风险端口,入口出口都做租户令牌桶。故障时新会话可切换健康节点,已发送 UDP 数据不自动重放。观测建连成功率、p99 延迟、丢包、资源和成本,同时监控扫描与放大行为。灰度对比 Datagram、回退和直连,安全或资源门槛超限就关闭新路径。

常见错误

  • 只说“用 HTTPS 包住 UDP” → 没有定义隧道语义和数据承载 → 分开 CONNECT-UDP、Capsule 和 Datagram。
  • 把代理当成可靠传输 → UDP 的丢包和顺序语义仍由上层负责 → 明确能力边界与指标。
  • 允许任意目标地址 → 形成内网探测或反射放大器 → 使用目标和端口 allowlist,阻断特殊地址。
  • 只按 HTTP 请求限流 → 长连接仍可耗尽 socket 和带宽 → 同时限制隧道、包、字节、时长和空闲。
  • 故障时重放全部 UDP 数据 → 可能重复交易或破坏实时协议 → 只恢复可重放控制状态,让上层重建数据会话。
  • 只测平均延迟 → 尾延迟和滥用会被隐藏 → 同时看 p99、丢包、拒绝和安全告警。

追问及应对

HTTP/2 不能发送 HTTP/3 Datagram 时怎么办?

根据业务选择可靠封装、长轮询式传输或明确拒绝,并单独计量延迟、CPU 和带宽成本;不要声称它与不可靠 Datagram 等价。

代理如何避免 SSRF?

在解析后和连接前都检查目标 IP,阻断环回、链路本地、私网、云元数据和策略外网段,并处理 DNS 重绑定;策略版本要绑定会话并可撤销。

UDP 丢包应由谁重试?

代理只报告可观测的传输结果,不擅自重放业务包。由具备幂等和序列语义的上层协议决定重试,实时媒体通常选择丢弃或纠错。

代理重启如何恢复会话?

优先让客户端重新鉴权并建立新会话;若必须保留控制状态,只恢复短期、可验证且不包含不可重放数据的状态,旧 socket 立即排空。

如何证明限流没有误伤?

按租户、区域、目标和客户端版本比较拒绝率与成功率,设置错误拒绝预算,并用回放流量验证突发、长连接和节点故障下的配额行为。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具