websocket 实现了统计在线人数,那 websocket 该如何防爆,防跨站?

2021-01-25 10:27:27 +08:00
 douyacun

站点在线人数统计实现思路: https://www.douyacun.com/article/d189d3d86915f5ff4c3be6a517570a0a

  1. 如何检测跨站点 WebSocket 劫持漏洞
    1. 我使用 jwt 来下发 token
    2. 申请 token 的接口也是对外暴露的
  2. 同一设备 ws 连接数如何限制,避免 bug 导致连接数过多导致服务挂掉
5344 次点击
所在节点    Go 编程语言
29 条回复
ihipop
2021-01-25 21:28:13 +08:00
@ihipop 忽略我上面的发言,原来楼主是做压力测试

我认为 ws,做在线是非常好的方案,实时性和性能开销比都不错。
caola
2021-01-25 21:40:21 +08:00
@douyacun #5 对外的 websocket 服务不是以端口为单位,而是以 URL 路径为单位的,websocket 可以发布于某个域名的某个路径或多个不同的路径下,与其他路径的 URL 页面或服务互不影响
cominghome
2021-01-26 08:14:17 +08:00
- -我一直以为这个数字是瞎整的(也不算瞎整,就是不需要那么严谨)
douyacun
2021-01-26 10:30:27 +08:00
@ihipop @caola websocket 和 http 是占用同一端口的( 80 | 443 ),linux kernel 3.9 引入的 SO_REUSEPORT 的选项,允许多个进程分享同一地址同一端口的 TCP 连接
> wss 统计在线人数,代价还是很低的,一般只是端口不够用
这个说法是错误的,我测试的 端口不够用 是因为客户端会占用本地端口,不是服务端的占用端口~
lesismal
2021-01-27 11:16:01 +08:00
跨站点劫持楼主已经写了,check origin + 业务层认证

单设备连接数限制这个不太合理,通常应该按照身份限制比较好:既然有业务层认证,每个连接都有身份,如果不允许同一个身份多个连接、认证后就把之前的踢掉,如果允许,那就自己服务节点配置提高、节点数量增加之类的(如果怕统一身份的连接散到多个服务节点上,可以加个网关层,网关层按身份指定到实际的业务节点、由业务节点进行踢下线处理)。如果实在是想按照设备限制,那策略里使用身份的地方就改用 ip 或者你的算法能够生成的设备 id

统计人数通常不需要太精确,即使是多个服务节点,每个节点定时(比如 5s )更新自己节点在线数到 redis/sql 都可以、更新多节点在线数量总和就可以了,实时在线本来就是不停跳动的,精确的意义不大。如果实在要求精确,自己再写个服务进行统计、并且同步到所有节点,或者直接用 redis incr 之类的,每秒查询、更新,但是都没法保证百分百精确,实时的本来就是跳动的数据,即使是股票 K 线的蜡烛图也都是按时间段的起值、止值、最高值、最低值进行统计的
lesismal
2021-01-27 11:21:06 +08:00
BTW,我这有个 ARPC 的 golang 框架提供了 websocket 聊天的简单示例

https://github.com/lesismal/arpc/tree/master/examples/webchat

另外 ARPC 支持发布订阅,如果想自己实现个管理服务器进行多个服务节点的在线数统计,管理服务器接收上报人数、然后把多节点的业务服在线总和发布就行了

想简单处理的话轮询写、读 redis 就好了
lesismal
2021-01-27 11:23:46 +08:00
节点数不多、redis 的话,每个节点每秒 hset 、hmget 下就行了,没啥压力,而且实时性也足够
lesismal
2021-01-27 11:27:05 +08:00
另外,怕连接数过多的话,单节点配置好最大在线数,新连接进来的时候判断下、超过了就拒绝掉,这个可以在网关或者业务节点的 upgrader checkorigion 里做,更好点的方式是自己 wrap 下 net.Listener,serve(listener),Accept 的地方直接做
lesismal
2021-01-27 11:33:38 +08:00
端口数量通常不是问题,文件描述符上限设置个 10w 、100w,其他的几个内核参数设置合理就行,只要你硬件配置足够。不过还真有的站点设置的不合理,golang 中国报错文件打开数量过多我就遇到过好多次。socket 是 4 元组,单 IP 自己过来的最大端口 65535,不代表服务器对所有 IP 加起来只能 65535,而且单 IP 除非故意写 bug 或者攻击、否则也不至于有这么多,而且这些 CDN 、防火墙那里就能挡,还轮不到业务层来处理这个(并且业务曾代码也没有这个能力处理)

如果是觉得某个设备只要超过两三个连接就算过多,那就看我上一楼说过,限制机制自己订制下就好

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/748054

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX