背景:混合云中的 UDP 服务暴露

企业迁移至 AWS 常采用分批策略,部分时延敏感或需保留本地的负载(如虚拟桌面网关、IPsec VPN 头端)仍驻留本地。借助 AWS Global Accelerator 的任播地址与内部 Network Load Balancer(NLB),可将用户就近接入并经由 Direct Connect 将本地服务注册为后端目标。然而,当协议为 UDP(例如桌面投屏、QUIC、实时媒体或 IPsec 封装)时,会话往往悄然退化至 TCP 或直接建立失败,而传统监控如 VPC Flow Logs 却显示双向流量正常。

根因:NLB 对 UDP 目标组的地址转换限制

NLB 在处理 UDP、TCP_UDP 等目标组时,始终开启客户端 IP 保留且不可关闭。这意味着负载均衡器仅执行目的地址转换(DNAT),将流量转发给后端,但不修改源地址;后端服务看到的是客户端真实公网 IP。由于本地服务位于 VPC 之外,没有弹性网络接口(ENI)隶属于 VPC,NLB 无法在返回路径上执行反向转换(即无状态转换依赖目标 ENI 完成)。

因此,本地服务直接向客户端公网 IP 回送 UDP 包:若站点无指向 AWS 的路由,包从本地互联网边缘发出被客户端丢弃;若默认路由指向 AWS,包经 Direct Connect 回到 VPC,但沿途无人重写目的地址,客户端依然无法识别。结果是协议层握手失败或被迫 fallback 到 TCP,造成卡顿与黑屏。

常见排查误区

  • 双向流日志不代表会话成功:Flow Logs 仅证明某一跳有来回包,不验证客户端是否接受回包。
  • 目标不健康却通流量:当所有目标健康检查失败时,NLB 会 fail-open 向全部目标转发,易被误判为正常。
  • 协议层假象:如 IPsec 因 NLB 改写目的端口而触发 NAT 探测漂移至 UDP 4500,仅表明首轮交换完成,隧道并未真正确立。

解决方案:每可用区部署 EC2 内核 NAT 代理

核心约束是后端目标必须具备 VPC 内 ENI,且服务需回应 VPC 内地址。修复方法是在 NLB 所在的每个可用区(AZ)启动一台轻量 EC2 实例作为 UDP 代理,利用 Linux 内核 nftables 执行有状态 NAT,而非用户态代理,以降低开销并允许健康检查直达真实服务。

数据流转发路径

  1. 客户端报文抵达 Global Accelerator 任播 IP。
  2. Global Accelerator 与 NLB 将报文投递给同 AZ 的 EC2 代理,保留客户端源 IP。
  3. 代理将源地址重写为自身私有 IP,经 Direct Connect 转发至本地服务。此步是关键修复点。
  4. 本地服务回包至代理私有 IP,因代理持有会话状态,回包原路返回。
  5. 各跳反向转换,客户端收到来自 Global Accelerator 地址的响应。

实施要点

  • 先决条件:标准 Global Accelerator 加速器、内部 NLB(UDP/TCP_UDP 监听)、VPC 内互联网网关(GA 要求)、Direct Connect 或 Site-to-Site VPN 混合连接、相应权限与运维通道。
  • 代理实例:基于 Amazon Linux 2023,按持续带宽而非突发选型;开启 net.ipv4.ip_forward=1;保持 SourceDestCheck 启用,因为代理自身 IP 即收发地址。
  • NAT 规则:使用 nftables 配置 DNAT 与 SNAT,使入站服务流量被重定向且源地址被改写。

对读者的意义与技术解读

对于运维、SRE 与网络工程师,该案例揭示了混合云架构中 UDP 服务暴露的隐性陷阱:公有云负载均衡器的客户端 IP 保留特性在跨网络边界时会导致非对称路由与无状态转换失效。仅依赖 Flow Logs 或仪表盘绿灯不足以发现此类“静默降级”。建议在进行云上 UDP 服务发布前,明确后端目标是否具备云内网络接口,或预先规划有状态 NAT 代理层。此外,QUIC、IPsec 等依赖 UDP 的现代化协议对路径对称性极为敏感,故障排查应结合协议层探测(如主动 UDP 健康检查)而非仅看包计数。该思路同样适用于其他云厂商的类似 LB 与本地互联场景,具备通用参考价值。

了解更多实现细节可参考 AWS 官方博客。