TCP重传缓冲区

来源:互联网 发布:js实现继承的几种方式 编辑:程序博客网 时间:2024/04/29 04:19

七、缓冲区管理

7.1TCP重传缓冲区

7.1.1TCP重传缓冲区的缺点:

[Shalunov,2000]中描述了一种针对TCP的资源耗尽型攻击(Netkill)。它的攻击方法是:通过创建大量的TCP连接然后丢弃它们,从而耗尽被攻击对象的内存资源。通常按如下操作进行攻击:

  • 黑客创建一个与服务器的TCP连接,这个连接可以通过发送短的客户端请求数据包,触发服务器一个大的数据包响应(如HTTP)。黑客除了依靠内核TCP的实现外,还使用专门的包构造工具建立这个TCP连接。通过这个工具,可以使黑客先创建一个连接,然后在丢弃它。通过丢弃连接,使TCP连接在黑客主机上没有消耗资源,从而可以耗尽被攻击对象的资源。

  • 当连接建立后(即:完成了三次握手),黑客将发送一个应用请求,然后丢弃该TCP连接。通过这种方法,黑客主机中的所有保存的状态信息都被移除。

  • 被攻击的服务器为这个TCP分配了一个用于传输对客户端请求响应的缓冲区。这导致了该TCP不仅消耗了TCB的资源,而且也消耗了需要被发送的应用数据资源。

  • 一旦应用响应信息放入传输队列,应用就关闭TCP连接,此时TCP就负责考虑将已排好数据投递出去,应用一旦关闭连接,这件对黑客有利,因为此时应用将不能在跟踪正在使用的TCP连接的数目,因而应用也无法进行连接数量限制。

  • 黑客重复上述步骤多次,使得被攻击服务器的大量内存被消耗在这些丢弃的连接上。当系统内存耗尽后,被攻击的机器将拒绝新的服务请求,甚至会宕机。

有几点影响这种攻击效果的因素需要考虑:第一,当攻击的对象是如HTTP服务器这样的典型目标时,攻击通常会产生系统范围的影响。第二,依赖于服务器响应的大小,底层TCP连接可能会关闭,也可能不关闭:如果响应比服务器TCP发送缓冲区的大小大,应用将一直阻塞在write()send()调用上,因而不会关闭该TCP连接,这就允许应用层实现对已经建立连接的连接数量限制。因此,黑客通常试着诱发一个等于或略小于被攻击服务器TCP缓冲区大小的响应。第三,正如[Shalunov,2000]中说的那样,这种攻击的一个可见影响是:有大量连接处于FIN-WAIT-1状态,存在大量这种状态是不正常的。既然黑客除了响应三次握手中的SYN/ACK报文外,从不响应任何其他报文。那么被攻击服务器的TCP将试着发送应哟个响应的冲突窗口(cwnd)通常是4×SMSS大小。如果应用的响应大于4×MSS字节,那么不管应用是否已经关闭了这个连接,FIN报文将永不发送,因而连接将一直处于ESTABLISHED状态。


7.1.2、应对策略

7.1.1.节描述的资源耗尽型攻击并不需要与一个合法的高负载情况相区分。因此,在对TCP的稳定性产生消极影响时,很难减轻这种攻击。然而,通过限制这种攻击的影响也能实现互补的减轻攻击。

强制限定非用户空间控制进程的连接数

5.3.2节中提出的这种“强制限制非用户空间控制进程的连接数”可以用于减轻这种攻击。

强制每个用户和每个进程的限制

由于Netkill攻击的目标通常都是一个如HTTP的服务器,它通常是系统范围的影响。一个针对某个服务的攻击可能影响到整个系统(如可能阻止远程系统管理),是极其不希望出现这种情况。

为了避免对单个服务的攻击影响到其他服务,我们建议TCP的实现中强制限制每个用户和进程在任何时候的最大内存使用量。此外,我们也建议在任何时候每个用户和每个进程对已建立连接TCP数量的限制。

在应用中限制已建立连接的数量

5.3.2节中建议的“在应用中强制限制连接的数量”也可用于减轻这种攻击。

使应用对已建立连接进行强制限制

正如6.1.1节中讨论的那样,系统调用close()的实际作用是将相应的文件描述符标记为已关闭,通过强制限制相应的连接来阻止在TCP上层运行的应用。

由于应用程序中通常都是系统调用close()来终止连接。也可以在应用程序中触发连接终止(保留了对连接的控制)而不是关闭相应的文件描述符。

为了实现这个目的,对于执行主动关闭(即启动连接终止)的应用应使用如下代码步骤替换对close(sockfd)的调用

  • 调用shutdownsockfdSHUT_WR)来关闭这个连接的发送端。

  • 不断调用read(),直到它返回0,此时表示远端TCP已经完成了数据发送。

  • 调用setsockopt(sockfd,SOL_SOCKET, SO_LINGER, &l, sizeof(l)。其中l是一个结构体structlingerl.l_onoff= 1 l.l_linger-90

  • 调用close(sockfd)关闭响应文件描述符。

shutdown()允许在连接由FIN-WAIT-1FIN-WAIT-2态过程中,使应用程序仍保持对底层TCP连接的控制。然而,当连接状态从CLOSINGTIME-WAIT态转变时,应用程序将不保持对底层TCP连接的控制。此外,在这些状态下的TCP没有任何其他就绪的数据将发送到远程TCP或将被运行在上层的应用接收的数据。因而在这种攻击中将不关心这些状态。

也应注意到:严格的说,close(sockfd)是递减对描述符sockfd的引用,只有当该引用计数变为0时,才触发连接终止过程。另一方面,shutdown(sockfd,SHUT_WR)直接触发连接终止过程,而不管sockfd描述符的引用计数值。这个特点在进行上述代码替换时需要进行考虑。如:对两个共享同一个描述的进程(如父子进程)调用shutdown时将产生一个bug

执行被动关闭的一侧需使用如下代码进行替换close(sockfd)

  • 调用setsockopt(sockfd,SOL_SOCKET, SO_LINGER, &l, sizeof(l)。其中l是一个结构体structlingerl.l_onoff= 1 l.l_linger-90

  • 调用close(sockfd)关闭响应文件描述符。

这里假定如果应用执行被动关闭,应用已经检测到了远端TCP通过read()调用返回0值,完成了发送数据。

在这种场景下,当发送了LAST_ACT状态后,应用程序将不再拥有对底层连接的控制。然而,在这种状态的TCP也不再有就绪数据需要发送到远端TCP或从运行在TCP上层的应用接收数据。因而在这种攻击中将不关心这些状态。

在防火墙中限制同时连接的数量

在第5.3.2节提出的“在防火墙中限制同事连接的数量”也可用于减轻这种攻击。

在已建立连接商执行一个启发算法

一些启发式算法作用于TCP连接,将有助于危机系统的需求(如内存已经耗尽)。多个参数可以用于执行这种启发式算法。

[Shanlunov,2000]中描述的Netkill攻击中,有两个参数用于描述TCP正在被攻击的特征:

  • TCP重传缓冲区中有大量的数据在排队(如socket的发送缓冲区)。

  • 只有少量数据被传送到了远端

显而易见的,这两个参数并不一定表示正在被攻击,然而,如果系统资源耗尽已经迫在眉睫,这两个参数可以用于在选择终止现有连接时的启发算法。

应当注意到,当黑客通告一个0大小的窗口将引起目标系统绑定系统内存到TCP重传缓冲区,从窗口通告中很难执行任何有用的评估。由于对维持状态强加一个限制很方便(参见3.7.2),黑客可以每次打开一个简单的窗口(通告一个大于零的窗口)来阻止由于强制限制引起的恶意连接被终止。

1 0
原创粉丝点击