【TCP/IP】TCP连接的建立与终止

        TCP是一个面向连接的协议。无论哪一方想另一方发送数据之前,都必须现在双方之间建立一条连接。这种两端间连接的建立与无连接协议如UDP不同。一端使用UDP想另一端发送数据报时,无需任何预先的握手。

 

连接建立与终止的时间系列

【TCP/IP】TCP连接的建立与终止

       发送第一个SYN的一端将执行主动打开(active open)。接收这个SYN并发回下个一SYN的另一端执行被动打开(passive open)

        建立一个连接需要三次握手,而终止一个连接要经过四次握手。这由TCP的半关闭(half-close)造成的。既然一个TCP连接时全双工,因此每个方向必须单独的进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向连接。当一端收到一个FIN,它必须通知应用层另一端已经终止了那个方向的数据传送。发送FIN通常是应用层进行关闭的结果。

        收到一个FIN只意味着在这一方向上没有数据流动,一个TCP连接在收到一个FIN后任能发送数据。而这对利用半关闭的应用来说是可能的,尽管在实际应用中只有很少的TCP应用程序这样做。

        首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭。

        发送FIN将导致应用程序关闭它们的连接,这些FIN的ACK是由TCP软件自动产生的。

       当一端为建立连接发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN。RFC 793 【Postel 1981c】指出ISN可看作时一个32比特的计数器,每4ms加1.这样选择序号的目的在于防止网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它作错误的解释。

       初始化***(ISN),在开机的时候,它就有一个函数,每个操作系统不一样,来不断的增加初始***的值。因为它的最大值为2的32次方,所以当达到最大值后,会又从0开始计数。

       当在T1时间客户端要向服务器建立TCP,发送三次握手,就需要发一个SYN包。这时客户端就会截取T1时间的ISN作为SYN包的***,当服务器收到SYN包,在T2时间要回送SYN,ACK的时候,它就会截取T2时间的ISN作为SYN的***。ACK***为T1时间的ISN+1.

  

       ASA的一个功能,随机初始化***扰乱。为什么需要扰乱初始化***,

1.    一台PC它的ISN有自己的增长规律,如果它在ASA里面,有些攻击者他会不断的去连接PC,PC这时候就会不断的回复SYN,ACK。攻击者就能得到不同节点时间段的ISN,然后用这些不同时间段的ISN来计算出PC的ISN增长规律,通过判断ISN增长规律,攻击者就有可能判断出你的操作系统。

2.     一台PC和某个主机已经建立了TCP连接,攻击者想做一个会话劫持,它需要伪装PC的IP地址、端口号、协议号。这些伪装了还是不行,还得知道你的***在什么范围。所以攻击者这时候也会通过多次探测来猜测ISN的增长规律,当得到ISN的增长规律会就会把PC干掉,攻击者自己连接到相应的主机。

 

        所以ASA就要防止这些攻击者通过多次试探来获取PC的ISN增长规律,因为一旦PC的ISN增长规律被获取后,攻击者就可以对我的操作系统进行判断,而且还有可能造成更严重的会话劫持。所以ASA会对初始化***进行扰乱。

        当PC在T1时刻发送SYN的时候,经过ASA,ASA会把T1时刻的ISN随机加一个数发走,在T2时刻发送SYN的时候,经过ASA,ASA又会把T2时刻的ISN随机加一个会减去一个数发走。由于ASA总是会在ISN的数上随机加上一个或者减去一个数,这样的话,攻击者在看你的ISN的时候就会觉得没有规律可寻。

 

2MSL等待时间

        TIMA_WAIT状态也称为2MSL等待状态,每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它时任何报文段被丢弃前在网络内的最长时间。

           RFC 793【Postel 1981c】指出MSL为2分钟。然而,现实中的常用值是30秒,1分钟,或2分钟。

        对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防止这个ACK丢失(另一端超时并重发最后的FIN)。

        这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用

       在连接处于2MSL等待时,任何迟到的报文段将被丢弃。因为处于2MSL等待时,由该插口对定义的连接在这段时间内不能再被使用。如果使用这个插口对建立新的连接,在收到来自这个插口对的包时,就会不知道,这个包是老的发的还是新的发的。

平静时间的概念

       对于来自某个连接的较早替身的迟到报文段,23MSL等待课防止将它解释成使用相同插口对的新连接的一部分。但这只有在处于2MSL等待连接中的主机处于正常工作状态时才有效。

       如果使用处于2MSL等待端口的主机出现故障,它会在MSL秒内重新启动,并立即使用故障前仍处于2MSL的插口对来建立一个新的链接吗?如果这样,在故障前从这个连接发出而迟到的报文段会被错误地当作属于重启后新连接的报文段。无论如何选择重启后新连接的初始序号,都会发生这种情况

       为了防止这种情况,RFC 793指出TCP在重启后的MSL秒内不能建立任何连接。这就称为平静时间。

       只有极少的现实版遵守这一原则,因为大多数主机重启的时间都比MSL秒要长。

 

FIN_WAIT_2状态

       在FIN_WAIT_2状态我们已经发送除了FIN,并且另一端也已对它进行确认。除非我们在实行半关闭,否则将等待另一端的应用层意识到它已收到一个文件结束符说明,并向我们发送一个FIN来关闭另一方向的连接。只有当另一端的进程完成这个关闭,我们这段才会从FIN_WAIT_2状态进入TIME_WAIT状态

       这意味着我们这端可能永远保持这个状态。另一端也将处于CLOSE_WAIT状态,并一直保持这个状态直到应用层决定进行关闭。

在ASA中,ASA认为这样会消耗客户端资源。ASA发现只要有一边做了FIN,并在一定时间内,远端并没有再来发送一个FIN来进行关闭的话,那么ASA将发送一个RST置位把客户端的资源给释放掉。

 

 

复位报文段

       无论何时一个报文段发往基准的连接出现错误,TCP都会发出一个复位报文段。当telnet一个远端主机没有开放的端口时,TCP就会发出一个复位报文段来断开这个请求,而UDP是发送一个ICMP端口不可达差错。

 

异常终止一个连接

       终止一个连接的正常方式是一方发送FIN。有时这也称为有序释放

       有可能发送一个复位报文段而不是FIN来中途释放一个连接。有时称这为异常释放

       异常终止一个连接对应用程序来说有两个优点

(1)    丢弃任何待发送数据并立即发送复位报文段;

(2)    RST的接收方会区分另一端执行的是异常关闭还是正常关闭。

应用程序使用的API必须提*生异常关闭而不是正常关闭的手段。

 

检查半打开连接

        如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的TCP连接称为半打开的(Half-Open)。任何一端的主机异常都可能导致发生这种情况。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。

        半打开连接的另一个常见原因是当客户主机突然掉电而不是正常的结束客户应用程序后再关机。此时如果服务器又重新启动,它将丢失复位前连接的所有信息,因此它不知道数据报文段中提到的连接。此时TCP处理的原则是接收方发送RST置位作为应答。

同时打开

        两个应用程序同时彼此执行主动打开的情况是可能的,TCP特意设计可以处理同时打开,对于同时打开它仅建立一条连接而不是两条连接。

        同时打开时,两端几乎同时发送SYN,并进入SYN_SENT状态。当每一端收到SYN时,状态变为SYN_RCVD,同时它们都再发SYN并对收到的SYN进行确认。当双方都收到SYN相应的ACK时,状态都变迁为ESTABLISH。

        一个同时打开的连接需要交换4个报文段,比正常的三次握手多1个,

【TCP/IP】TCP连接的建立与终止

同时关闭

        双方同时执行主动关闭是可能的,TCP协议也允许这样的同时关闭。

        当应用层发出关闭命令时,两端均从ESTABLISH变为FIN_WAIT1,这将导致双方各发送一个FIN,两个FIN经过网络传送后分别到达另一端。收到FIN后,状态由FIN_WAIT1变迁到CLOSING,并发达最后的ACK,状态变化为TIME_WAIT。

【TCP/IP】TCP连接的建立与终止