必须在握手阶段拦截非法扫描请求,通过Origin、IP、Token三重校验及反向代理层速率限制实现:校验Origin白名单(禁用通配符)、记录并丢弃无Origin头请求、Nginx配置limit_conn限制IP连接数、Token须在Upgrade请求头中传递并即时验证,严禁延至消息层。

直接结论:仅靠前端校验或简单日志记录无法阻止 WebSocket 扫描,必须在连接建立前就拦截——重点在握手阶段的 Origin、IP、Token 三重校验,配合反向代理层的速率限制。
WebSocket 握手阶段如何拦截非法扫描请求
扫描工具(如 ws://scan.example.com/chat)发起连接时,第一步是 HTTP Upgrade 请求。此时服务端尚未进入 WebSocket 协议,仍处于 HTTP 上下文,所有防护逻辑必须在此阶段生效。
- Origin 头不可信但必须校验:
CheckOrigin函数不能只比对字符串,要支持正则或白名单数组,避免硬编码写死成"https://trusted-site.com"导致内网调试失败 - 拒绝通配符:
origin == "*"或allowedOrigins: ["*"]是高危配置,会直接开放跨站 WebSocket 劫持(CSWSH)入口 - 务必记录并丢弃无 Origin 头的请求——真实浏览器必带,扫描器常省略,这是低成本识别扫描行为的信号
如何在反向代理层限制 WebSocket 连接频率
WebSocket 的 DoS 风险集中在连接建立环节,消息层限流(如每秒最多 10 条)意义不大。真正有效的防线在反向代理(Nginx / Traefik)上做 IP 级连接数控制。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- Nginx 示例中,
limit_conn_zone $binary_remote_addr zone=wsconn:10m;必须搭配limit_conn wsconn 5;,否则只是声明没启用 - 注意
$binary_remote_addr比$remote_addr更节省内存,且能正确处理 IPv6 - 若后端有 CDN 或云 WAF,需确认它是否透传真实客户端 IP——否则限流会误判为“所有流量来自同一个 IP”
为什么 Token 认证不能放在 WebSocket 消息里再校验
把认证逻辑放到 conn.ReadMessage() 之后,等于给攻击者留出 5~30 秒的连接窗口。这期间已占用内存、文件描述符和事件循环资源,足以构成资源耗尽型攻击。
- 正确做法是在 Upgrade 请求的查询参数或 Header 中传递
Authorization或自定义头(如X-Auth-Token),并在CheckOrigin后立即验证 - JWT 必须校验
exp和iss,且签名密钥不能硬编码在代码里,应通过环境变量注入 - 拒绝使用 URI 查询参数传 Token:
ws://api.com/chat?token=xxx会导致 Token 泄露到 Nginx access log、CDN 日志、浏览器历史记录中
最易被忽略的一点:很多团队只在应用层做防护,却忘了 WebSocket 握手请求本质是 HTTP 请求——WAF 规则、Nginx if 判断、甚至 iptables 限速都能在更早阶段掐断扫描流量。别让安全逻辑全部堆在 Upgrade 成功之后。

















