WebSocket 请求通过 CDN 返回 403 Forbidden 的问题排查与解决
Truman

Truman @truman_999999999

Joined:
Jun 11, 2024

WebSocket 请求通过 CDN 返回 403 Forbidden 的问题排查与解决

Publish Date: May 24
0 0

WebSocket 请求通过 CDN 返回 403 Forbidden 的问题排查与解决(wstest.example.com)

在一次使用 Kubernetes + NGINX Ingress + WebSocket 服务部署中,配置了 CDN(Funnell)接入域名:

wss://wstest.example.com/push/ws?token=xxx

服务端为 Go 编写的 go-push 应用,监听端口 8081,用于处理 WebSocket 请求。


问题描述

客户端(如 Postman、浏览器)访问 WebSocket 接口时,始终收到:

403 Forbidden

响应头极其简洁,仅包含:

Date: ...
Content-Length: 0

后端服务日志中无任何请求记录,初步判断 请求未到达服务层


排查过程

1. 检查 Ingress 配置

Kubernetes Ingress 使用以下配置:

annotations:
  nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
  nginx.ingress.kubernetes.io/connection-proxy-header: keep-alive
  nginx.ingress.kubernetes.io/use-forwarded-headers: "true"
  nginx.ingress.kubernetes.io/rewrite-target: /$2
  nginx.ingress.kubernetes.io/configuration-snippet: |
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
    proxy_set_header X-Request-From gateway;
Enter fullscreen mode Exit fullscreen mode

路径路由为:

- path: /push(/|$)(.*)
  pathType: ImplementationSpecific
  backend:
    service:
      name: go-push
      port:
        number: 8081
Enter fullscreen mode Exit fullscreen mode

确认路由正确,路径 /push/ws 会被重写为 /ws 并转发给 go-push 服务。


2. 测试绕过 CDN,直连 Ingress

使用 curl 模拟 WebSocket 握手:

curl -i -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: test123==" \
  -H "Host: wstest.example.com" \
  http://<Ingress-IP>:<Port>/push/ws
Enter fullscreen mode Exit fullscreen mode

返回 101 Switching Protocols,说明 Kubernetes 服务与 Ingress 正常,问题来自 CDN。


3. 确认 CDN(Funnell)拒绝连接

日志及响应特征表明:403 来自 CDN 层拦截而非应用或 Ingress 返回。主要怀疑:

  • WebSocket 未开启支持

  • 请求路径未允许回源

  • 请求头未透传


解决方案(Funnell 配置)

在 Funnell CDN 控制台中,对域名 wstest.example.com 做如下配置调整:

开启 WebSocket 支持

  • 开启「WebSocket 协议支持」或「连接升级(Upgrade)」功能

配置回源路径白名单

  • 添加 /push/.* 至允许回源路径

  • 若默认只允许 /api/static,未配置的新路径可能被直接 403 拦截

请求头透传设置

  • 保证以下头部 不被 CDN 移除或篡改
Header 正确值
Connection Upgrade
Upgrade websocket
Sec-WebSocket-* 保留原样

验证成功

完成配置后,再次通过 WebSocket 客户端访问:

wss://wstest.example.com/push/ws?token=xxx
Enter fullscreen mode Exit fullscreen mode

得到正确响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Enter fullscreen mode Exit fullscreen mode

服务端日志打印握手成功,连接稳定。


总结

当 WebSocket 请求经由 CDN(如 Funnell)出现 403 Forbidden,常见原因不在服务本身,而是 CDN 安全策略或协议限制。请务必检查以下:

  • CDN 是否开启 WebSocket 支持

  • 回源路径是否白名单允许

  • 是否保留关键握手头部(如 Upgrade、Connection)

  • Ingress 是否配置正确的 proxy_set_header 和路径转发规则

处理得当后,可实现 CDN 加速 + WebSocket 稳定通信 的双赢方案。

Comments 0 total

    Add comment