基于“加固tcp/ip协议栈中的SynAttackProtect机制”的防止SYN泛洪攻击

来源:互联网 发布:淘宝店铺名称设计 编辑:程序博客网 时间:2024/06/09 18:56

这里只讲“加固tcp/ip协议栈中的SynAttackProtect机制”这种方法。详细描述请见

http://blog.csdn.net/luojunjing/archive/2005/02/12/286333.aspx

防范SYN攻击的另一项主要技术是调整tcp/ip协议栈,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等。tcp/ip协议栈的调整可能会引起某些功能的受限,管理员应该在进行充分了解和测试的前提下进行此项工作。

SynAttackProtect机制

为防范SYN攻击,win2000系统的tcp/ip协议栈内嵌了SynAttackProtect机制,Win2003系统也采用此机制。SynAttackProtect机制是通过关闭某些socket选项,增加额外的连接指示和减少超时时间,使系统能处理更多的SYN连接,以达到防范SYN攻击的目的。默认情况下,Win2000操作系统并不支持SynAttackProtect保护机制,需要在注册表以下位置增加SynAttackProtect键值:

  HKLM/SYSTEM/CurrentControlSet/Services/Tcpip/Parameters

SynAttackProtect值(如无特别说明,本文提到的注册表键值都为十六进制)为0或不设置时,系统不受SynAttackProtect保护。

SynAttackProtect值为1时,系统通过减少重传次数和延迟未连接时路由缓冲项(route cache entry)防范SYN攻击。

SynAttackProtect值为2时(Microsoft推荐使用此值),系统不仅使用backlog队列,还使用附加的半连接指示,以此来处理更多的SYN连接,使用此键值时,tcp/ipTCPInitialRTTwindow size和可滑动窗囗将被禁止。

我们应该知道,平时,系统是不启用SynAttackProtect机制的,仅在检测到SYN攻击时,才启用,并调整tcp/ip协议栈。那么系统是如何检测SYN攻击发生的呢?事实上,系统根据TcpMaxHalfOpen,TcpMaxHalfOpenRetriedTcpMaxPortsExhausted三个参数判断是否遭受SYN攻击。

TcpMaxHalfOpen表示能同时处理的最大半连接数(也即服务器处于SYN_RECV阶段),如果超过此值,系统认为正处于SYN攻击中。Win2000 server默认值为100Win2000 Advanced server500

TcpMaxHalfOpenRetried定义了保存在backlog队列且重传过的半连接数(即服务器处于SYN_RECV阶段,并且对于一些连接,若发送了SYN-ACK后没有响应使得服务器重发SYN-ACK,如果超过此值,系统自动启动SynAttackProtect机制。Win2000 server默认值为80Win2000 Advanced server400

TcpMaxPortsExhausted 是指系统拒绝的SYN请求包的数量(也即服务器处于LISTEN阶段,个人认为是与socket中的listen第二个参数backlog一样的意思,也即等待连接队列的长度),默认是5

如果想调整以上参数的默认值,可以在注册表里修改(位置与SynAttackProtect相同)

 

附上MSDN中的专题《如何:强化 TCP/IP 堆栈安全》

http://www.microsoft.com/china/technet/security/guidance/secmod109.mspx#EPC

启用 SYN攻击保护

启用 SYN攻击保护的命名值位于此注册表项的下面:HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services

值名称SynAttackProtect

建议值 2

有效值 0 – 2

说明:使TCP调整 SYN-ACK的重传。配置此值后,在遇到 SYN攻击时,对连接超时的响应将更快速。在超过TcpMaxHalfOpenTcpMaxHalfOpenRetried的值后,将触发 SYN攻击保护。

设置 SYN保护阈值

下列值确定触发 SYN保护的阈值。这一部分中的所有注册表项和值都位于注册表项HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services的下面。这些注册表项和值是:

值名称TcpMaxPortsExhausted
建议值 5
有效值
0 – 65535
说明:指定触发 SYN洪水攻击保护所必须超过的 TCP连接请求数的阈值。

值名称TcpMaxHalfOpen
建议的数值数据 500
有效值
100 – 65535
说明:在启用SynAttackProtect后,该值指定处于 SYN_RCVD状态的 TCP连接数的阈值。在超过SynAttackProtect后,将触发 SYN洪水攻击保护。

值名称TcpMaxHalfOpenRetried
建议的数值数据 400
有效值
80 – 65535
说明:在启用SynAttackProtect后,该值指定处于至少已发送一次重传的 SYN_RCVD状态中的 TCP连接数的阈值。在超过SynAttackProtect后,将触发 SYN洪水攻击保护。

 

同时附上codeproject中的启用SYN泛洪攻击的代码C++实现。(可用A simple IOCP ServerClient Class查找源码)。

BOOL IOCPS::XPNTSYNFloodProtection(int iValue, int iTcpMaxHalfOpen, int iTcpMaxHalfOpenRetried,int iTcpMaxPortsExhausted,int iTcpMaxConnectResponseRetransmissions)

{

      CString sKey_PATH="//SYSTEM//CurrentControlSet//Services//Tcpip//Parameters";

      CString sKey_SynAttackProtect="SynAttackProtect";

      CString sKey_TcpMaxHalfOpen="TcpMaxHalfOpen";

      CString sKey_TcpMaxHalfOpenRetried="TcpMaxHalfOpenRetried";

      CString sKey_TcpMaxPortsExhausted="TcpMaxPortsExhausted";

      CString sKey_TcpMaxConnectResponseRetransmissions="TcpMaxConnectResponseRetransmissions";

 

      HKEY   hKey;

      DWORD  val=0;

      LONG    r=0;

      BOOL bRet=TRUE;

 

      //

      // Set the sKey_SynAttackProtect

      //

      val=iValue;

      if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey_PATH, &hKey) != ERROR_SUCCESS)

             if (RegCreateKey(HKEY_LOCAL_MACHINE, sKey_SynAttackProtect, &hKey) != ERROR_SUCCESS)

                    return FALSE;

      r = RegSetValueEx(hKey, sKey_SynAttackProtect, 0, REG_DWORD, (BYTE *)&val, sizeof(val));

      RegCloseKey(hKey);

      bRet&= (r == ERROR_SUCCESS);

 

      //

      // Special Parameters is used.

      //

      if(iValue==1)

      {

             //

             // Set the sKey_SynAttackProtect

             //

             val=iTcpMaxHalfOpenRetried;

             if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey_PATH, &hKey) != ERROR_SUCCESS)

                    if (RegCreateKey(HKEY_LOCAL_MACHINE, sKey_TcpMaxHalfOpen, &hKey) != ERROR_SUCCESS)

                           return FALSE;

             r = RegSetValueEx(hKey, sKey_TcpMaxHalfOpen, 0, REG_DWORD, (BYTE *)&val, sizeof(val));

             RegCloseKey(hKey);

             bRet&= (r == ERROR_SUCCESS);

 

             //

             // Set the sKey_TcpMaxHalfOpenRetried

             //

             val=iTcpMaxHalfOpenRetried;

             if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey_PATH, &hKey) != ERROR_SUCCESS)

                    if (RegCreateKey(HKEY_LOCAL_MACHINE, sKey_TcpMaxHalfOpenRetried, &hKey) != ERROR_SUCCESS)

                           return FALSE;

             r = RegSetValueEx(hKey, sKey_TcpMaxHalfOpenRetried, 0, REG_DWORD, (BYTE *)&val, sizeof(val));

             RegCloseKey(hKey);

             bRet&= (r == ERROR_SUCCESS);

 

 

             //

             // Set the sKey_TcpMaxPortsExhausted

             //

             val=iTcpMaxPortsExhausted;

             if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey_PATH, &hKey) != ERROR_SUCCESS)

                    if (RegCreateKey(HKEY_LOCAL_MACHINE, sKey_TcpMaxPortsExhausted, &hKey) != ERROR_SUCCESS)

                           return FALSE;

             r = RegSetValueEx(hKey, sKey_TcpMaxPortsExhausted, 0, REG_DWORD, (BYTE *)&val, sizeof(val));

             RegCloseKey(hKey);

             bRet&= (r == ERROR_SUCCESS);

 

 

             //

             // Set sKey_TcpMaxConnectResponseRetransmissions

             //

             val=iTcpMaxConnectResponseRetransmissions;

             if (RegOpenKey(HKEY_LOCAL_MACHINE, sKey_PATH, &hKey) != ERROR_SUCCESS)

                    if (RegCreateKey(HKEY_LOCAL_MACHINE, sKey_TcpMaxConnectResponseRetransmissions, &hKey) != ERROR_SUCCESS)

                           return FALSE;

             r = RegSetValueEx(hKey, sKey_TcpMaxConnectResponseRetransmissions, 0, REG_DWORD, (BYTE *)&val, sizeof(val));

             RegCloseKey(hKey);

             bRet&= (r == ERROR_SUCCESS);

 

      }

 

      return bRet;

 

}