全站加速WebSocket偶发访问失败-劫持行为

本文涉及的产品
边缘安全加速 ESA,基础版 3个月
全站加速 DCDN,50GB 1年
日志服务 SLS,月写入数据量 50GB 1个月
简介: 对于能复现的问题,可以尝试抓包分析具体的请求得出结论。劫持行为可以通过配置HTTPS来改善。

问题描述

客户使用DCDN的WebSocket业务,偶发出现无法访问的情况,线上有1%左右的失败率。根据客户沟通,该问题并不是必现的,目前是其中一位同事家里的wifi网络下能复现问题,而且重启家里的光猫以后能正常,但一段时间以后又会出现问题。

问题排查

1. 客户端信息

尝试让客户复现问题,提供客户端的Netwrok信息和客户端抓包信息。从抓包信息看,是源站响应了500。进一步跟客户确认源站逻辑,根据客户的反馈是源站会先校验Upgrade: websocket 这个请求头,如果没有这个请求头就会返回500。但是奇怪的是,根据抓包文件看,客户端明明是带了Upgrade: websocket请求头的,因此怀疑是DCDN节点转发的问题。

根据WebSocket的RFC协议文档可以知道

  1. Websocket请求必须包含一个Upgrade header字段,它的值必须包含"websocket"。
  2. WebSocket请求必须包含一个Connection header字段,它的值必须包含"Upgrade"。

2. 模拟访问测试

根据抓包信息,使用curl指定到对应的DCDN请求模拟发WebSocket请求测试,发现在客户侧能稳定复现的情况下,我们curl测试并不能复现,排查来看又跟节点没有关系。

curl -sv 'http://xxx.xxx.com/' -H'Connection: Upgrade' -H'Upgrade: websocket' -H'Sec-WebSocket-Key: pCnMykJwUTQB14FCbP2Beg==' -H'Sec-WebSocket-Version: 13' -H'Origin:http://xxx.xxx.com' -H'Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits' -H'Accept-Encoding: gzip, deflate' -x 116.253.29.212:80

3. 源站打印

尝试让客户在源站侧加一下打印,将收到的请求头打印出来,从源站的打印来看,出问题的时候的确是没有收到Upgrade: websocket头。而如果是正常的请求,源站是能打印出Upgrade: websocket头的。如果尝试在源站侧去掉这个Upgrade的校验,虽然可以请求成功,但是无法进行WebSocket通信,因为整条链路并不是走的WebSocket。

3. 排查CDN日志

排查后台CDN的日志,发现正常请求的hit_info字段显示的是WS,也就是走的WebSocket请求。而异常请求的hit_info字段是dynamic,也就是走的动态加速,并不是WebSocket。从现象分析来看,怀疑是L1收到的请求里就没有Upgrade: websocket相关的头,所以L1认为这不是WebSocket请求,走的是普通的动态加速,转发回源站也不会带Upgrade头。

4. DCDN侧增加debug日志

由于日志里并没有记录收到的客户端Upgrade字段,因此需要后台加一下debug日志,打印下该字段。

5. 重新复现问题

重新让客户复现了一次问题,并提供客户端抓包数据。从抓包数据看,客户端请求确实带了Upgrade头,而从DCDN的日志来看,确实是没有收到Upgrade头的,因此走的也是普通动态加速请求。同时从客户端收到的来自DCDN的报文看,这个TTL是64,这明显是不正常的。正常情况由于DCDN节点发出的报文TTL原始值是64,中间每经过一个网络路由节点,TTL减1,客户端收到的报文TTL不应该是64。因此判断是客户端存在劫持行为,走了代理,应该是客户端发出请求以后客户端层面做了异常转发,按照普通的HTTP请求转发,没有转WebSocket相关头导致的。

问题解决

配置HTTPS证书,客户端走wss请求以后,客户侧能复现问题的现场就正常了,无法再复现问题,而且线上错误率明显改善。

适用产品

DCDN

目录
相关文章
|
Web App开发 应用服务中间件 nginx
|
6月前
|
网络协议 Java 应用服务中间件
如何将本地websocket发布至公网并实现远程访问服务端
如何将本地websocket发布至公网并实现远程访问服务端
211 0
|
4月前
|
前端开发 网络协议 JavaScript
在Spring Boot中实现基于WebSocket的实时通信
在Spring Boot中实现基于WebSocket的实时通信
|
25天前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
249 1
|
29天前
|
前端开发 Java C++
RSocket vs WebSocket:Spring Boot 3.3 中的两大实时通信利器
本文介绍了在 Spring Boot 3.3 中使用 RSocket 和 WebSocket 实现实时通信的方法。RSocket 是一种高效的网络通信协议,支持多种通信模式,适用于微服务和流式数据传输。WebSocket 则是一种标准协议,支持全双工通信,适合实时数据更新场景。文章通过一个完整的示例,展示了如何配置项目、实现前后端交互和消息传递,并提供了详细的代码示例。通过这些技术,可以大幅提升系统的响应速度和处理效率。
|
3月前
|
开发框架 网络协议 Java
SpringBoot WebSocket大揭秘:实时通信、高效协作,一文让你彻底解锁!
【8月更文挑战第25天】本文介绍如何在SpringBoot项目中集成WebSocket以实现客户端与服务端的实时通信。首先概述了WebSocket的基本原理及其优势,接着详细阐述了集成步骤:添加依赖、配置WebSocket、定义WebSocket接口及进行测试。通过示例代码展示了整个过程,旨在帮助开发者更好地理解和应用这一技术。
268 1
|
3月前
|
小程序 Java API
springboot 微信小程序整合websocket,实现发送提醒消息
springboot 微信小程序整合websocket,实现发送提醒消息
|
3月前
|
JavaScript 前端开发 网络协议
WebSocket在Java Spring Boot+Vue框架中实现消息推送功能
在现代Web应用中,实时消息提醒是一项非常重要的功能,能够极大地提升用户体验。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为实现实时消息提醒提供了高效且低延迟的解决方案。本文将详细介绍如何在Java Spring Boot后端和Vue前端框架中利用WebSocket实现消息提醒功能。
158 0
|
5月前
|
前端开发 JavaScript 安全
集成WebSocket在Spring Boot中可以用于实现实时的双向通信
集成WebSocket在Spring Boot中可以用于实现实时的双向通信
86 4
|
4月前
|
监控 网络协议 Java
如何在Spring Boot中使用WebSocket
如何在Spring Boot中使用WebSocket