1、TCP客户端要连接到TCP服务器,需要经过三个过程:
以下是通过 Wireshark 抓取的三次握手数据包
No Time Source Destination Protocal Length Info
505244 28619.472565 192.168.123.41 192.168.123.25 TCP 58 13537 → 9999 [SYN] Seq=0 Win=5840 Len=0 MSS=1440 505303 28627.965458 192.168.123.25 192.168.123.41 TCP 58 9999 → 13537 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 505304 28627.967863 192.168.123.41 192.168.123.25 TCP 54 13537 → 9999 [ACK] Seq=1 Ack=1 Win=5840 Len=0
知识预备:
数据包:包括报头和数据
win:表示本机还有多少容量可以存储对方发来的数据(不包括报头),每个数据包都包含此值
len:表示本机发送的这个数据包包含几个字节数据(不包括报头)
MSS:全称为最大报文段长度,只在 SYN 包出现,表示本机接收一个数据包能接受的数据字节数(不包括报头),以后客户端和服务器发送的数据大小不能超过对方的MSS
seq、ack:通过这两个值可以判断接收到的数据包是否是本机发送数据包的应答包
第一次握手:建立连接时,客户端发送:SYN(也就是SYN位置一),seq=x(x为任意数,一般为0) 到服务器,并进入SYN_SEND状态,等待服务器进行确认。(只有标志位 SYN 置一表示此包是客户端发起的第一次握手)
第二次握手:服务器收到第一次握手包后,服务器发送:ACK,SYN,seq=y(y为任意数,一般为0),ack=x+1到客户端。(ACK置一,SYN置一表示此包是服务器发起的第二次握手)
第三次握手:客户端收到服务器端的SYN+ACK包,然后向服务器端发送确认包:ACK, seq=x+1,ack=y+1, 客户端发完进入ESTABLISHED状态,服务器端接收到进入ESTABLISHED状态,完成三次握手。
需要三次握手的原因:
1、为了确保客户端和服务端都能接收和发送数据。(客户端收到第二个握手数据包表明客户端可以发送数据给服务器,并且可以接收服务器的数据;服务器收到第三个握手数据包表明服务器可以接收客户端的数据,并且可以发送数据给客户端)
2、客户端发送第一次握手报文给服务器,此报文在网络的某个节点滞留时间比较长,长到客户端通过再次握手已经和服务器建立连接并且通信结束断开连接了,如果服务器只接收到第一次握手报文就和客户端建立连接,前面描述的情况服务器就会以为有客户端和它建立连接,实则不然。
三次握手流程图
一个数据包的组成
确定包类型:
URG------紧急指针
ACK------确认包
PSH------接收方应该尽快将这个报文段交给应用层
RST------重建连接
SYN------同步包,用来发起一个连接
FIN-------发端应用层不再发送数据包
应用层如何发起三次握手
2、验证TCP三次握手
通过抓包软件获得三次握手这三个包的数据,当然如果每个包抓的彻底一点,不仅包括传输层(如:TCP)数据,还包括网际层(如:IP)和网络接口层;包的协议类型还分ethernet(有线网络)和802.11(无线网路)之分。
3、DOS之SYN FLOOD进攻
原理:
问题就出在TCP连接的三次握手中,假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒 -2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的进攻者大量模拟这种情况,服务器端将为了维护一个非常大的半连接队列(SYN队列)而消耗非常 多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最 后的结果往往是堆栈溢出崩溃---即使服务器端的系统足够强大,服务器端也将忙于处理进攻者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从 正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYN Flood进攻(SYN洪水进攻)。
防范:
第一种是缩短SYN Timeout时间
第二种方法是设置SYN Cookie,就是给每一个请求连接的IP地址分配一个Cookie,如果短时间内连续受到某个IP的重复SYN报文,就认定是受到了进攻,以后从这个IP地址来的包会被一概丢弃。
4、MSS
TCP在三次握手中,每一方都会通告其期望收到的MSS(MSS只出现在SYN数据包中,表示本机接收一个数据包能接受的数据字节数(不包括报头)),在一个TCP连接上允许各种长度报文段的传输,因此连接的两端利用MSS选项来协商报文段中最大数据长度是必要的。例如在一个小型系统中由于空间限制,TCP仅能提供较小的接受缓冲区。它与其他系统通信时,就必需互相协商一个合适的MSS,使对端发出的报文段中的数据能够存入其接受缓冲器。由于TCP连接的各个端点可能存在的差异,在一个TCP连接的两个数据流方向上常常可能采用不同的MSS值。
进行MSS协商的另一个好处是能够提高网络带宽的利用率。在一个局域网中进行通信的两个节点可以选择一个比较大的MSS,使得报文段封装成IP分组时能够充分利用网络的带宽。但是实际上在一般的Intenet 环境中,为连接选择一个合适的MSS是相当困难的。这是因为MSS的取值过大或过小都会影响网络和TCP的性能。如果报文段太小,将会大大降低网络的利用率(报头占总发送字节数大)。但如果报文段太大也可能影响网性能。这是由于长IP分组在网络中传输时往往需要被分片传输。分片和重组的过程自然将带来一定的网络处理开销。而且IP分组被分片后独立传输,任何一个分片出现错误或丢失都将导致整个分组被丢弃,这也意味着整个报文段丢失,TCP只能对整个IP分组进行确认和重传。由于在IP通信子网中分组丢失的概率总是存在的,因此MSS的增加所导致的分片将会使报文段成功达到目的端的概率下降,从而影响TCP的性能和和降低网络的吞吐率。