总共600分-完成端口 的高手来讨论,如何对付只连接不传输数据的[拒绝服务]攻击? (200分)

  • 主题发起人 主题发起人 delphiroad
  • 开始时间 开始时间
多谢以上各位的意见,思路越来越广了。不过我暂时不会结贴,希望有更多建议!
多谢所有的DFW,600分一定送出,请大家继续支持!
 
用IOCP的人都会遇到这个问题[:D]
客户端也就是个2000左右的规模,上10000是太严重了
建议使用acceptex

出现你说的这种情况,除了恶意的不发送数据的攻击外,还可能是对方机器突然当机,或者中间网络断开。。。。
如果服务器逻辑是应答方式的这种情况就更严重了

想想游戏服务器为什么不怕这个呢?因为有了loginServer

所以当用户通过验证后再把对应的socket投递到IOCP是一个解决办 ,验证就用ThreadPool+select

如果你的服务器是匿名的,那轮训吧


 
呵呵,这个贴子还在呀,建议用AcceptEx + so_connect_time套接字选项。

barton曾经对这个问题有过论述,现在我贴上来给大家参考一下:
在部分人都认为服务器上需要专门做一个线程去定时查看是否有实际已经不存在的连接,以便腾出
更多的资源供新的连接使用。这也并不是用完成端口模型编写的服务器才需要考虑的问题,用其它
模型编写的服务器一样存在这个问题。我没有测试过这样做的实效。无论如何,对完成端口模型中
总是有一个对连接的读操作请求一直没有返回,如果连接被某种因素断开应该会导致完成端口返回
一个字节数为零的读操作结果,同样会导致服务器断开此连接。我没有从Microsoft的相关文档上
看到有关的警告。
如果接受连接采用的是Microsoft扩展的AcceptEx函数而不是Accept或WSAAccept函数的话,需要考
虑防止DoS(拒绝服务)攻击,恶意客户占用连接后并不发送数据将导致函数AcceptEx的调用不能够正
常返回,而令合法客户无法连接进来。这是另外一个问题。这时候的轮询只需要考虑每一个守候着
的AcceptEx函数是否已连接以及连接的时间长短。长时间的连接而不发送数据的连接可以主动关闭
它。AcceptEx是唯一一个支持完成端口的接受连接函数。Accept/WSAAccept函数在与客户连接后,
才返回一个新的套接字,所以无法事先与完成端口关联。与而AcceptEx是事先创建一个套接字,在
还没有与客户连接的时候就与完成端口关联,一旦连接成功,便获得完成端口的通知。只可惜MS在
设计这个函数的时候一定要接收到部分数据才返回,所以给Dos攻击者提供了机会。不过我认为这样
可以省去监听线程,而设计一个不算繁忙的轮询线程一定会带来服务器性能的提升。
 
gxcooo:
“想想游戏服务器为什么不怕这个呢?因为有了loginServer
所以当用户通过验证后再把对应的socket投递到IOCP是一个解决办 ”
其实我现在的服务器也是这样设计的,但loginServer也怕攻击阿!一样会担心
loginServer拒绝服务阿!
ego:
用AcceptEx和WSAAccept我倒是觉得差不多(AcceptEx可能会提升性能),但有两
点不明白:
1、AcceptEx会不会不少Socket2,结果导致反而性能降低!(好像有这说法,但我
不太明白是怎么回事)
2、用AcceptEx会拒绝服务,只是因为AcceptEx相当于WSAAcept之后马上WSARecv,
但我现在用的就是WSAAcept,之后与完成端口关联,之后马上WSARecv,也就是说连
接建立之后马上等待客户端发来的请求命令,我只有根据对方的请求来判断下一步
应该做什么,如果对方不发来任何数据,我也无从下手。所以我一直无法理解大家都
只在讲到AcceptEx时才有DoS攻击,其实我觉得WSAAcept也会阿(加上WSARecv)!
另外,barton曾经对这个问题有过论述,barton的帖子在哪里?给个连接好吧!
 
loginServer采用线程池
我现在的服务器这样做的: 认证成功前超时为16s 认证成功后为5分钟

我在对用户服务的服务器上用AcceptEx时不接收数据
AcceptEx绝对高,并且可以Sokcet(Object)复用

这种连接上不发数据的DoS还是小case 真正的是不完成3次握手[:D]
 
to gxcooo:
哈哈,对,不完成3次握手你的超时控制也没有用了,因为没有连接上,怎么解决呢
 
to tangrh:
那是OS内部的事情并且不好解决 一般是用硬件SYN防火墙
 
讨论的范围越来越宽了, 我也来灌点水````可能跑题了:)

可以说,到目前为止还没发明能彻底防御DoS/DDoS的方法(要不Yahoo这样的网站也就不会被攻瘫痪了, 呵呵),我们能做的也就是尽力提高服务器(群)的抗攻击能力罢了.

个人认为,应用服务器的写法固然重要,但对一个服务器群来讲, 只是很小一部分,
因为很多防御是建立在OS内核层里的,
应用服务器根本无能为力.抗DoS攻击应该从建立多层构架的服务器群,分工负责,分摊攻击入手.

真好我现在管理着一个不算太小的服务器, 效果不错(瘫痪过一次,原因是IDC的路由被挤爆),把框架和大家分享一下,欢迎讨论

1) 防火墙 -- 限制SYN包的通过速率, 按照客户分布, 对不同网段设置不同限制, 通过速率总和位服务器群最大处理能力的2-3倍, 同时配合网络流量监测, 动态调整部分规则
2) 负载均衡-- 平摊连接到3层的多个服务器, 使用随机丢弃新连接的方式再次限制新连接通过速率, 调整到服务器群最大处理能力的90%左右
3) 应用层 -- IOCP, 用WSAEventSelect异步方式,专门线程处理Accept, 专门线程处理Recv超时

2,3层配能根据1层SYN包丢弃率为参考变量,动态调整OS中TCP超时和重试次数参数, 特别是SYN应答包的参数
 
to sofox:
用WSAEventSelect异步方式,专门线程处理Accept---何不试试AcceptEx呢?
 
sofox:
你不能算跑题的,我觉得你说得已经很具体,真是感谢!
不过我仍有三个问题期望你更具体的给予解答(当然如能提供一些参考资料也是可以的):
1、你的:3) 应用层 -- IOCP, 用WSAEventSelect异步方式,专门线程处理Accept, 专门线程处理Recv超时
IOCP是完成端口,那还要WSAEventSelect来干什么?在我的完成端口模型中,只要一个Accept线程和
一个等待完成的工作线程而已阿!不知道WSAEventSelect的加入起什么重要作用?
我的理解是WSAEventSelect和一个专门线程一起来处理Recv超时的判断和处理吧!
2、专门线程处理Recv超时我大概理解,但不知道怎么做到(比如最大会同时存在2000个连接(已连接成功),连
接1s如果WSARecv还不返回就关闭Socket)?
3、微软的ISA能做到防止不完成3次握手的攻击吗?还是一定要用硬件防火墙?用什么比较好?
 
看看我的想法是不是可行?
如果你写的东西是一个自己定义的通讯协议可以设立一个“负载均衡服务器”,这里的负载均衡服务器实际上还是一个ip登记服务器,每次用户访问的时候需要首先访问夫在均衡服务器,当连接建立以后,客户端什么也不需要做,负载均衡服务器返回一个ip:port后断开连接,同时附在均衡服务器会通过内部通讯通知该服务器客户端的IP,服务器将该IP假如白名单用户即可正常与该服务器建立连接,用户断开连接后服务器从白名单中将该IP删除。同时对于白名单中的IP的登陆数量也进行限制,一旦超过警戒值就将其从白名单中删除。

如果你的系统只有一台服务器可以采用同时监听多个端口的办法来实现,比如1000端口充当“负载均衡”1001-1010端口为应用服务器。

同时还可以在应用服务器上设立陷阱,如果某个IP没有被加入白名单就与应用服务器建立连接,那么应用服务器应该立即向“负载均衡”发送通知,将这个IP放入特殊黑名单,在一定时间内不接受其登陆。
 
这个办法也想过,对不公开实现方式的服务器有点用
 
如果是http等公开方式的恐怕要将读写线程和处理线程分离,对端口进行读写的应该是分别的两个线程,根据实际需要予生成一些处理线程,在工作过程中对端口进行读取操作的线程根据实际需要可以动态的生成和杀死处理线程。
 
后退
顶部