[转]服务器程序防止Socket攻击的解决方案
2012-11-16 19:21
99 查看
我这里说的“Socket攻击”是指,用一台或N台肉机进行TCP连接,以此来消耗服务器程序的可用Socket。
看了很多程序或组件的源代码,一般对客户端Socket管理是这样的:
1、用一个TThreadList(只要是线程安全的列表管理都行)来存储连接成功的Socket:后文统称“Socket列表”
2、服务器程序预设一个超时时间,比如10秒
3、限制每个IP能连接的Socket数量-----这个可以防止用一台机子写个程序疯狂的来连接这种情况
4、单独开一个线程,每隔几秒去检查一下这个 Socket列表,看是否有超时没有验证通过的Socket,然后将其这些超时的Socket关闭
实际部署被攻击出现的问题:
1、服务器检测到大量的IP(有近5万个),每个IP都有3,5个连接来连接服务器程序,只连接但不发验证信息,判定是攻击
2、Socket列表 好几万(我的是64位的程序,WIN SERVER 2008 R2下实际测试可接受11万多的连接)
3、这些连接不断连上、断开,再连上,Socket列表很长,检测Socket超时的线程工作时间很长导致占用Socket列表的时间很长,把整个服务器程序完全拖慢了。服务器程序处于假死状态
解决方案
一、加入单位时间能连接的Socket数量,单位时间以两秒为准效果不错,比如2秒内只能500个连接,这就可以很好的控制 Socket列表 的长度
二、引入IP黑名单,当一个IP超过10次非法连接后,将其IP拉黑,拉黑后任何从这个IP来的连接直接就Close掉,这样他怎么来连接也没影响了
三、改进 Socket列表, 只用一个 Socket列表 由于要处理线程安全的问题,在超多线程的环境下必然导致线程争用 Socket列表 的情况,这样多线程的效率就大打折扣了
所以我提出,用 双Socket列表 的方案。简单实现如下:
1、定义:fClientGuidMap, fClientGuidMap2: ThHashStringList(这个类是我自己实现的,大家可以用TThreadList之类的);
2、两个操作函数:
function ExchangeClientGuidMap: ThHashStringList;
procedure ClientGuidMap_AddObject(const S: string; AObject: TObject);
实现如下:
function TROBaseIOCPSuperTcpServer.ExchangeClientGuidMap: ThHashStringList;
begin
ExchangeLock.Acquire;
try
Pointer(fClientGuidMap2) := InterlockedExchangePointer(Pointer(fClientGuidMap), Pointer(fClientGuidMap2));
Result := fClientGuidMap2;
finally
ExchangeLock.Release;
end;
end;
3、检测线程的代码就不贴出来了,检测线程就是先调用 ExchangeClientGuidMap 后,对取得的列表循环判断其是否超时未验证,超时就CloseSocket就OK了
经过上面的改造,服务器程序防止攻击的能力大大提高
//来源:http://www.cnblogs.com/AnyDelphi/archive/2012/09/14/2685183.html
看了很多程序或组件的源代码,一般对客户端Socket管理是这样的:
1、用一个TThreadList(只要是线程安全的列表管理都行)来存储连接成功的Socket:后文统称“Socket列表”
2、服务器程序预设一个超时时间,比如10秒
3、限制每个IP能连接的Socket数量-----这个可以防止用一台机子写个程序疯狂的来连接这种情况
4、单独开一个线程,每隔几秒去检查一下这个 Socket列表,看是否有超时没有验证通过的Socket,然后将其这些超时的Socket关闭
实际部署被攻击出现的问题:
1、服务器检测到大量的IP(有近5万个),每个IP都有3,5个连接来连接服务器程序,只连接但不发验证信息,判定是攻击
2、Socket列表 好几万(我的是64位的程序,WIN SERVER 2008 R2下实际测试可接受11万多的连接)
3、这些连接不断连上、断开,再连上,Socket列表很长,检测Socket超时的线程工作时间很长导致占用Socket列表的时间很长,把整个服务器程序完全拖慢了。服务器程序处于假死状态
解决方案
一、加入单位时间能连接的Socket数量,单位时间以两秒为准效果不错,比如2秒内只能500个连接,这就可以很好的控制 Socket列表 的长度
二、引入IP黑名单,当一个IP超过10次非法连接后,将其IP拉黑,拉黑后任何从这个IP来的连接直接就Close掉,这样他怎么来连接也没影响了
三、改进 Socket列表, 只用一个 Socket列表 由于要处理线程安全的问题,在超多线程的环境下必然导致线程争用 Socket列表 的情况,这样多线程的效率就大打折扣了
所以我提出,用 双Socket列表 的方案。简单实现如下:
1、定义:fClientGuidMap, fClientGuidMap2: ThHashStringList(这个类是我自己实现的,大家可以用TThreadList之类的);
2、两个操作函数:
function ExchangeClientGuidMap: ThHashStringList;
procedure ClientGuidMap_AddObject(const S: string; AObject: TObject);
实现如下:
function TROBaseIOCPSuperTcpServer.ExchangeClientGuidMap: ThHashStringList;
begin
ExchangeLock.Acquire;
try
Pointer(fClientGuidMap2) := InterlockedExchangePointer(Pointer(fClientGuidMap), Pointer(fClientGuidMap2));
Result := fClientGuidMap2;
finally
ExchangeLock.Release;
end;
end;
3、检测线程的代码就不贴出来了,检测线程就是先调用 ExchangeClientGuidMap 后,对取得的列表循环判断其是否超时未验证,超时就CloseSocket就OK了
经过上面的改造,服务器程序防止攻击的能力大大提高
//来源:http://www.cnblogs.com/AnyDelphi/archive/2012/09/14/2685183.html
相关文章推荐
- RO IOCP开发心得系列(01):服务器程序防止Socket攻击的解决方案
- RO IOCP开发心得系列(01):服务器程序防止Socket攻击的解决方案
- 防止 XSS 攻击 解决方案
- 防止 XSS 攻击 解决方案
- 防止 XSS 攻击 解决方案
- 如何判断socket是否已经断开和防止外部攻击,只连接不传输数据
- 防止 XSS 攻击 解决方案
- Mysql在高并发情况下,防止库存超卖而小于0的解决方案
- ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的方法
- ASP.NET Core 防止跨站请求伪造(XSRF\/CSRF)攻击
- .NET中如何防止注入攻击
- 修改内核,防止 syn_cookie攻击
- sql防止注入式攻击
- 配置 Haproxy 防止 DDOS 攻击
- Android http java.net.SocketException: sendto failed: EPIPE 解决方案
- .NET平台下几种SOCKET编程通信模型选择以及简要性能供参考解决方案
- 校园网ARP攻击原理及防御解决方案
- 防止SQL注入安全性解决方案
- iis 防火墙防止恶意ip攻击
- 防止跨站攻击和sql注入的方法