• TCP三次握手详解


    摘自百度百科:

    三次握手

     锁定
    三次握手(three times handshake;three-way handshake)所谓的“三次握手”即对每次发送的数据量是怎样跟踪进行协商使数据段的发送和接收同步,根据所接收到的数据量而确定的数据确认数及数据发送、接收完毕后何时撤消联系,并建立虚连接。
    为了提供可靠的传送,TCP在发送新的数据之前,以特定的顺序将数据包的序号,并需要这些包传送给目标机之后的确认消息。TCP总是用来发送大批量的数据。当应用程序在收到数据后要做出确认时也要用到TCP。
    中文名
    三次握手
    外文名
    Three-way handshake
    别    称
    TCP握手协议
    应用学科
    计算机传输协议
    适用领域范围
    计算机

    过程

    第一次

    第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

    第二次

    第二次握手服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

    第三次

    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
    完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:

    未连接队列

    三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于 Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。

    Backlog参数

    表示内核为相应套接字排队的最大连接个数。SYN-ACK重传次数
    三次握手协议三次握手协议
    服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。
    《UNIX 网络编程》中指出,关于backlog参数从未有过正式的定义,BSD 4.2手册中宣称它的定义是:“the maximum length the queue of pending connections may grow to”,即未处理连接构成的队列可能增长到的最大长度,POSIX规范也逐字复制该定义。不过这个定义中并没有明确到底这个连接指的是SYN_RCVD状态的连接,还是未由进程接受的处于ESTABLISHED状态的连接,亦或两者皆可。
    不论这个backlog参数到底指的是哪一个,对于服务器而言,都需要尽快的去处理已经处于ESTABLISHED状态的连接。而仅仅对于backlog来说,我们需要取一个比较大的值以应对大量的服务请求。
    半连接存活时间
    是指半连接队列的条目存活的最长时间,也即服务器从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

    TCP头结构

    面向连接的TCP三次握手是Syn Flood存在的基础。
    TCP协议头最少20个字节,包括以下的区域(由于翻译不尽相同,文章中给出相应的英文单词):
    TCP源端口(Source Port):16位的源端口其中包含初始化通信的端口。源端口和源IP地址的作用是标示报文的返回地址。
    TCP目的端口(Destination port):16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。
    TCP序列号(序列码,Sequence Number):32位的序列号由接收端计算机使用,重新分段的报文成最初形式。当SYN出现,序列码实际上是初始序列码(ISN),而第一个数
    字节是ISN+1。这个序列号(序列码)是可以补偿传输中的 不一致。
    TCP应答号(Acknowledgment Number):32位的序列号由接收端计算机使用,重组分段的报文成最初形式。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码。
    数据偏移量(HLEN):4位包括TCP头大小,指示何处数据开始。
    TCP四次挥手结束连接TCP四次挥手结束连接
    保留(Reserved):6位值域,这些位必须是0。为了将来定义新的用途所保留。
    标志(Code Bits):6位标志域。表示为:紧急标志、有意义的应答标志、推、重置连接标志、同步序列号标志、完成发送数据标志。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN。
    窗口(Window):16位,用来表示想收到的每个TCP数据段的大小。
    校验位(Checksum):16位TCP头。源机器基于数据内容计算一个数值,收信息机要与源机器数值结果完全一样,从而证明数据的有效性。
    优先指针(紧急,Urgent Pointer):16位,指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段
    选项(Option):长度不定,但长度必须是一个字节。如果没有选项就表示这一个字节的域等于0。

    关闭TCP连接:改进的三次握手

    对于一个已经建立的连接,TCP使用改进的三次握手来释放连接(使用一个带有FIN附加标记的报文段)。TCP关闭连接的步骤如下:
    第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。
    第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段)。
    第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段。
    第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。[1] 

    标志控制

    URG:紧急标志
    紧急(The urgent pointer) 标志有效。紧急标志置位,
    ACK:确认标志
    确认编号(Acknowledgement Number)栏有效。大多数情况下该标志
    TCP三次握手是Syn Flood存在的基础TCP三次握手是Syn Flood存在的基础
    位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1,Figure:1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据
    PSH:推标志
    该标志置位时,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的。
    RST:复位标志
    复位标志有效。用于复位相应的TCP连接。
    SYN:同步标志
    同步序列编号(Synchronize Sequence Numbers)栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。
    FIN:结束标志
    带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。
    服务端处于监听状态客户端用于建立连接请求的数据包(IP packet)按照TCP/IP协议堆栈组合成为TCP处理的分段(segment)。
    分析报头信息: TCP层接收到相应的TCP和IP报头,将这些信息存储到内存中。
    检查TCP校验和(checksum):标准的校验和位于分段之中(Figure:2)。如果检验失败,不返回确认,该分段丢弃,并等待客户端进行重传。
    查找协议控制块(PCB{}):TCP查找与该连接相关联的协议控制块。如果没有找到,TCP将该分段丢弃并返回RST。(这就是TCP处理没有端口监听情况下的机制) 如果该协议控制块存在,但状态为关闭,服务端不调用connect()或listen()。该分段丢弃,但不返回RST。客户端会尝试重新建立连接请求。
    建立新的socket:当处于监听状态的socket收到该分段时,会建立一个子socket,同时还有socket{},tcpcb{}和pub{}建立。这时如果有错误发生,会通过标志位来拆除相应的socket和释放内存,TCP连接失败。如果缓存队列处于填满状态,TCP认为有错误发生,所有的后续连接请求会被拒绝。这里可以看出SYN Flood攻击是如何起作用的。
    丢弃:如果该分段中的标志为RSTACK,或者没有SYN标志,则该分段丢弃。并释放相应的内存。

    数据传输

    发送序列变量 SND.UNA :发送未确认
    SND.NXT :发送下一个
    SND.WND :发送窗口
    SND.UP :发送优先指针
    SND.WL1 :用于最后窗口更新的段序列号
    SND.WL2 :用于最后窗口更新的段确认号
    三次握手三次握手
    ISS :初始发送序列号
    接收序列号
    RCV.NXT :接收下一个
    RCV.WND :接收下一个
    RCV.UP :接收优先指针
    IRS :初始接收序列号
    当前段变量
    SEG.SEQ :段序列号
    SEG.ACK :段确认标记
    SEG.LEN :段长
    SEG.WND :段窗口
    SEG.UP :段紧急指针
    SEG.PRC :段优先级
    CLOSED表示没有连接,各个状态的意义如下:
    LISTEN :监听来自远方TCP端口的连接请求。
    SYN-SENT :在发送连接请求后等待匹配的连接请求。
    SYN-RECEⅣED :在收到和发送一个连接请求后等待对连接请求的确认。
    ESTABLISHED :代表一个打开的连接,数据可以传送给用户。
    FIN-WAIT-1 :等待远程TCP的连接中断请求,或先前的连接中断请求的确认。
    FIN-WAIT-2 :从远程TCP等待连接中断请求。
    CLOSE-WAIT :等待从本地用户发来的连接中断请求。
    CLOSING :等待远程TCP对连接中断的确认。
    LAST-ACK :等待原来发向远程TCP的连接中断请求的确认。
    TIME-WAIT :等待足够的时间以确保远程TCP接收到连接中断请求的确认。
    CLOSED :没有任何连接状态。
    TCP连接过程是状态的转换,促使发生状态转换的是用户调用:OPEN,SEND,RECEⅣE,CLOSE,ABORT和STATUS。传送过来的数据段,特别那些包括以下标记的数据段SYN,ACK,RST和FIN。还有超时,上面所说的都会时TCP状态发生变化。

    序列标识

    序列号
    在TCP连接中发送的字节都有一个序列号。因为编了号,所以可以确认它们的收到。对序列号的确认是累积性的。TCP必须进行的序列号比较操作种类包括以下几种:
    ①决定一些发送了的但未确认的序列号
    ②决定所有的序列号都已经收到了。
    ③决定下一个段中应该包括的序列号
    对于发送的数据TCP要接收确认,确认时必须进行的:
    SND.UNA = 最老的确认了的序列号
    SND.NXT = 下一个要发送的序列号
    三次握手数据三次握手数据
    SEG.ACK = 接收TCP的确认,接收TCP期待的下一个序列号
    SEG.SEQ = 一个数据段的第一个序列号
    SEG.LEN = 数据段中包括的字节数。
    SEG.SEQ+SEG.LEN-1 = 数据段的最后一个序列号
    如果一个数据段序列号小于等于确认号的值,那么整个数据段就被确认了。而在接收数据时下面的比较操作是必须的:
    RCV.NXT = 期待的序列号和接收窗口的最低沿。
    RCV.NXT+RCV.WND:1 = 最后一个序列号和接收窗口的最高沿。
    SEG.SEQ = 接收到的第一个序列号
    SEG.SEQ+SEG.LEN:1 = 接收到的最后一个序列号[2] 

    基于三次握手的SYN洪水攻击

    基本原理

    三次握手协议三次握手协议
    建设一个小型的模仿环境假设有3台接入互联网的机器。A为攻击者操纵的攻击机。B为中介跳板机器(受信任的服务器)。C为受害者使用的机器(多是服务器),这里把C机器锁定为目标机器。A机器向B机器发送SYN包,请求建立连接,这时已经响应请求的B机器会向A机器回应SYN/ACK表明同意建立连接,当A机器接受到B机器发送的SYN/ACK回应时,发送应答ACK建立A机器与B机器的网络连接。这样一个两台机器之间的TCP通话信道就建立成功了。
    B终端受信任的服务器向C机器发起TCP连接,A机器对服务器C发起SYN信息,使C机器不能响应B机器。在同时A机器也向B机器发送虚假的C机器回应的SYN数据包,接收到SYN数据包的B机器(被C机器信任)开始发送应答连接建立的SYN/ACK数据包,这时C机器正在忙于响应以前发送的SYN数据而无暇回应B机器,A机器的攻击者预测出B机器包的序列号(TCP序列号预测难度有些大)假冒C机器向B机器发送应答ACK这时攻击者骗取B机器的信任,假冒C机器与B机器建立起TCP协议的对话连接。这个时候的C机器还是在响应攻击者A机器发送的SYN数据。

    TCP协议栈的弱点

    TCP连接的资源消耗,其中包括:数据包信息、条件状态、序列号等。通过故意不完成建立连接所需要的三次握手过程,造成连接一方的资源耗尽。
    通过攻击者有意的不完成建立连接所需要的三次握手的全过程,从而造成了C机器的资源耗尽。序列号的可预测性,目标主机应答连接请求时返回的SYN/ACK的序列号时可预测的。

    syn洪水攻击原理:

    据统计,在所有黑客攻击事件中,SYN攻击是最常见又最容易被利用的一种攻击手法。相信很多人还记得2000年YAHOO网站遭受的攻击事例,当时黑客利用的就是简单而有效的SYN攻击,有些网络蠕虫病毒配合SYN攻击造成更大的破坏。本文介绍SYN攻击的基本原理、工具及检测方法,并全面探讨SYN攻击防范技术。

    一、TCP握手协议

    在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。

    第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

    第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

    第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

    完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:

    未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。 
    Backlog参数:表示未连接队列的最大容纳数目。

    SYN-ACK 重传次数 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。

    半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

    二、SYN攻击原理

    SYN攻击属于DOS攻击的一种,它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。SYN攻击除了能影响主机外,还可以危害路由器、防火墙等网络系统,事实上SYN攻击并不管目标是什么系统,只要这些系统打开TCP服务就可以实施。从上图可看到,服务器接收到连接请求(syn=j),将此信息加入未连接队列,并发送请求包给客户(syn=k,ack=j+1),此时进入SYN_RECV状态。当服务器未收到客户端的确认包时,重发请求包,一直到超时,才将此条目从未连接队列删除。配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

    三、SYN攻击工具

    SYN攻击实现起来非常的简单,互联网上有大量现成的SYN攻击工具。

    1、windows系统下的SYN工具

    以synkill.exe为例,运行工具,选择随机的源地址和源端囗,并填写目标机器地址和TCP端囗,激活运行,很快就会发现目标系统运行缓慢。如果攻击效果不明显,可能是目标机器并未开启所填写的TCP端囗或者防火墙拒绝访问该端囗,此时可选择允许访问的TCP端囗,通常,windows系统开放tcp139端囗,UNIX系统开放tcp7、21、23等端囗。

    四、检测SYN攻击

    检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。我们使用系统自带的netstat 工具来检测SYN攻击:

    # netstat -n -p TCP 
    tcp 0  0 10.11.11.11:23124.173.152.8:25882  SYN_RECV -
    tcp 0  0 10.11.11.11:23236.15.133.204:2577  SYN_RECV -
    tcp 0  0 10.11.11.11:23127.160.6.129:51748  SYN_RECV -
    tcp 0  0 10.11.11.11:23222.220.13.25:47393  SYN_RECV -
    tcp 0  0 10.11.11.11:23212.200.204.182:60427 SYN_RECV -
    tcp 0  0 10.11.11.11:23232.115.18.38:278 SYN_RECV -
    tcp 0  0 10.11.11.11:23239.116.95.96:5122SYN_RECV -
    tcp 0  0 10.11.11.11:23236.219.139.207:49162 SYN_RECV -
    ...

    上面是在LINUX系统中看到的,很多连接处于SYN_RECV状态(在WINDOWS系统中是SYN_RECEIVED状态),源IP地址都是随机的,表明这是一种带有IP欺骗的SYN攻击。

    我们也可以通过下面的命令直接查看在LINUX环境下某个端囗的未连接队列的条目数:

    #netstat -n -p TCP   grep SYN_RECV   grep :22   wc -l 324

    显示TCP端囗22的未连接数有324个,虽然还远达不到系统极限,但应该引起管理员的注意。

    五、SYN攻击防范技术

    关于SYN攻击防范技术,人们研究得比较早。归纳起来,主要有两大类,一类是通过防火墙、路由器等过滤网关防护,另一类是通过加固TCP/IP协议栈防范.但必须清楚的是,SYN攻击不能完全被阻止,我们所做的是尽可能的减轻SYN攻击的危害,除非将TCP协议重新设计。

    1、过滤网关防护

    这里,过滤网关主要指明防火墙,当然路由器也能成为过滤网关。防火墙部署在不同网络之间,防范外来非法攻击和防止保密信息外泄,它处于客户端和服务器之间,利用它来防护SYN攻击能起到很好的效果。过滤网关防护主要包括超时设置,SYN网关和SYN代理三种。

    ■网关超时设置

    防火墙设置SYN转发超时参数(状态检测的防火墙可在状态表里面设置),该参数远小于服务器的timeout时间。当客户端发送完SYN包,服务端发送确认包后(SYN+ACK),防火墙如果在计数器到期时还未收到客户端的确认包(ACK),则往服务器发送RST包,以使服务器从队列中删去该半连接。值得注意的是,网关超时参数设置不宜过小也不宜过大,超时参数设置过小会影响正常的通讯,设置太大,又会影响防范SYN攻击的效果,必须根据所处的网络应用环境来设置此参数。

    ■SYN网关

    SYN网关收到客户端的SYN包时,直接转发给服务器;SYN网关收到服务器的SYN/ACK包后,将该包转发给客户端,同时以客户端的名义给服务器发ACK确认包。此时服务器由半连接状态进入连接状态。当客户端确认包到达时,如果有数据则转发,否则丢弃。事实上,服务器除了维持半连接队列外,还要有一个连接队列,如果发生SYN攻击时,将使连接队列数目增加,但一般服务器所能承受的连接数量比半连接数量大得多,所以这种方法能有效地减轻对服务器的攻击。

    ■SYN代理

    当客户端SYN包到达过滤网关时,SYN代理并不转发SYN包,而是以服务器的名义主动回复SYN/ACK包给客户,如果收到客户的ACK包,表明这是正常的访问,此时防火墙向服务器发送ACK包并完成三次握手。SYN代理事实上代替了服务器去处理SYN攻击,此时要求过滤网关自身具有很强的防范SYN攻击能力。

    2、加固tcp/ip协议栈

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

    ■SynAttackProtect机制

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

    HKLMSYSTEMCurrentControlSetServicesTcpipParameters

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

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

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

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

    TcpMaxHalfOpen 表示能同时处理的最大半连接数,如果超过此值,系统认为正处于SYN攻击中。Win2000 server默认值为100,Win2000 Advanced server为500。

    TcpMaxHalfOpenRetried定义了保存在backlog队列且重传过的半连接数,如果超过此值,系统自动启动SynAttackProtect机制。Win2000 server默认值为80,Win2000 Advanced server为400。

    TcpMaxPortsExhausted 是指系统拒绝的SYN请求包的数量,默认是5。

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

    ■ SYN cookies技术

    我们知道,TCP协议开辟了一个比较大的内存空间backlog队列来存储半连接条目,当SYN请求不断增加,并这个空间,致使系统丢弃SYN连接。为使半连接队列被塞满的情况下,服务器仍能处理新到的SYN请求,SYN cookies技术被设计出来。

    SYN cookies应用于linux、FreeBSD等操作系统,当半连接队列满时,SYNcookies并不丢弃SYN请求,而是通过加密技术来标识半连接状态。

    在TCP实现中,当收到客户端的SYN请求时,服务器需要回复SYN+ACK包给客户端,客户端也要发送确认包给服务器。通常,服务器的初始序列号由服务器按照一定的规律计算得到或采用随机数,但在SYN cookies中,服务器的初始序列号是通过对客户端IP地址、客户端端囗、服务器IP地址和服务器端囗以及其他一些安全数值等要素进行hash运算,加密得到的,称之为cookie。当服务器遭受SYN攻击使得backlog队列满时,服务器并不拒绝新的SYN请求,而是回复cookie(回复包的SYN序列号)给客户端, 如果收到客户端的ACK包,服务器将客户端的ACK序列号减去1得到cookie比较值,并将上述要素进行一次hash运算,看看是否等于此cookie。如果相等,直接完成三次握手(注意:此时并不用查看此连接是否属于backlog队列)。

    在RedHat linux中,启用SYN cookies是通过在启动环境中设置以下命令来完成:

    # echo 1 ?? /proc/sys/net/ipv4/tcp_syncookies

    ■ 增加最大半连接数

    大量的SYN请求导致未连接队列被塞满,使正常的TCP连接无法顺利完成三次握手,通过增大未连接队列空间可以缓解这种压力。当然backlog队列需要占用大量的内存资源,不能被无限的扩大。

    WIN2000:除了上面介绍的TcpMaxHalfOpen, TcpMaxHalfOpenRetried参数外,WIN2000操作系统可以通过设置动态backlog(dynamic backlog)来增大系统所能容纳的最大半连接数,配置动态backlog由AFD.SYS驱动完成,AFD.SYS是一种内核级的驱动,用于支持基于window socket的应用程序,比如ftp、telnet等。AFD.SYS在注册表的位置: 
    HKLMSystemCurrentControlSetServicesAFDParametersEnableDynamicBacklog值为1时,表示启用动态backlog,可以修改最大半连接数。 

    MinimumDynamicBacklog表示半连接队列为单个TCP端囗分配的最小空闲连接数,当该TCP端囗在backlog队列的空闲连接小于此临界值时,系统为此端囗自动启用扩展的空闲连接(DynamicBacklogGrowthDelta),Microsoft推荐该值为20。

    MaximumDynamicBacklog是当前活动的半连接和空闲连接的和,当此和超过某个临界值时,系统拒绝SYN包,Microsoft推荐MaximumDynamicBacklog值不得超过2000。

    DynamicBacklogGrowthDelta值是指扩展的空闲连接数,此连接数并不计算在MaximumDynamicBacklog内,当半连接队列为某个TCP端囗分配的空闲连接小于MinimumDynamicBacklog时,系统自动分配DynamicBacklogGrowthDelta所定义的空闲连接空间,以使该TCP端囗能处理更多的半连接。Microsoft推荐该值为10。

    LINUX:Linux用变量tcp_max_syn_backlog定义backlog队列容纳的最大半连接数。在Redhat 7.3中,该变量的值默认为256,这个值是远远不够的,一次强度不大的SYN攻击就能使半连接队列占满。我们可以通过以下命令修改此变量的值:

    # sysctl -w net.ipv4.tcp_max_syn_backlog=`2048`

    Sun Solaris Sun Solaris用变量tcp_conn_req_max_q0来定义最大半连接数,在Sun Solaris 8中,该值默认为1024,可以通过add命令改变这个值:

    # ndd -set /dev/tcp tcp_conn_req_max_q0 2048

    HP-UX:HP-UX用变量tcp_syn_rcvd_max来定义最大半连接数,在HP-UX 11.00中,该值默认为500,可以通过ndd命令改变默认值:

    #ndd -set /dev/tcp tcp_syn_rcvd_max 2048

    ■缩短超时时间

    上文提到,通过增大backlog队列能防范SYN攻击;另外减少超时时间也使系统能处理更多的SYN请求。我们知道,timeout超时时间,也即半连接存活时间,是系统所有重传次数等待的超时时间总和,这个值越大,半连接数占用backlog队列的时间就越长,系统能处理的SYN请求就越少。为缩短超时时间,可以通过缩短重传超时时间(一般是第一次重传超时时间)和减少重传次数来实现。

    Win2000第一次重传之前等待时间默认为3秒,为改变此默认值,可以通过修改网络接囗在注册表里的TcpInitialRtt注册值来完成。重传次数由TcpMaxConnectResponseRetransmissions 来定义,注册表的位置是:HKLMSYSTEMCurrentControlSetServicesTcpipParameters registry key。

    当然我们也可以把重传次数设置为0次,这样服务器如果在3秒内还未收到ack确认包就自动从backlog队列中删除该连接条目。

    LINUX:Redhat使用变量tcp_synack_retries定义重传次数,其默认值是5次,总超时时间需要3分钟。

    Sun Solaris Solaris 默认的重传次数是3次,总超时时间为3分钟,可以通过ndd命令修改这些默认值。



  • 相关阅读:
    7-4 找出不是两个数组共有的元素(20 分)
    7-2 删除重复字符(20 分)
    7-1 兔子繁衍问题(15 分)
    1018 Public Bike Management (30分) (迪杰斯特拉+dfs)
    PAT 1014 Waiting in Line (30分) 一个简单的思路
    1010 Radix (25分)
    试题编号: 201809-4 试题名称: 再卖菜 记忆化搜索
    试题编号: 201903-3 试题名称: 损坏的RAID5
    CCF 试题编号: 201909-4 试题名称: 推荐系统
    洛谷P3809 后缀数组模板
  • 原文地址:https://www.cnblogs.com/iamconan/p/7383561.html
Copyright © 2020-2023  润新知