1、TCP協議簡介安全
TCP(Transmission Control Protocol 傳輸控制協議)是一種面向鏈接的、可靠的、基於字節流的傳輸層通訊協議網絡
通常問到TCP協議的時候 最多見的是TCP鏈接創建和斷開的過程,也就是三次握手和四次揮手併發
Tcp報文格式socket
ACK:確認序號有效。blog
RST:重置鏈接。隊列
SYN:發起一個新鏈接。資源
FIN:釋放一個鏈接。開發
(1)第一次握手:Client將標誌位SYN置爲1,隨機產生一個值seq=J,並將該數據包發送給Server,Client進入SYN_SENT狀態,等待Server確認。
(2)第二次握手:Server收到數據包後由標誌位SYN=1知道Client請求創建鏈接,Server將標誌位SYN和ACK都置爲1,ack=J+1,隨機產生一個值seq=K,並將該數據包發送給Client以確認鏈接請求,Server進入SYN_RCVD狀態。
(3)第三次握手:Client收到確認後,檢查ack是否爲J+1,ACK是否爲1,若是正確則將標誌位ACK置爲1,ack=K+1,並將該數據包發送給Server,Server檢查ack是否爲K+1,ACK是否爲1,若是正確則鏈接創建成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間能夠開始傳輸數據了。get
SYN攻擊就是Client在短期內僞造大量不存在的IP地址,並向Server不斷地發送SYN包,Server回覆確認包,並等待Client的確認,因爲源地址是不存在的,所以,Server須要不斷重發直至超時,這些僞造的SYN包將長時間佔用未鏈接隊列,致使正常的SYN請求由於隊列滿而被丟棄,從而引發網絡堵塞甚至系統癱瘓。it
(1) 第一次揮手:Client發送一個FIN,用來關閉Client到Server的數據傳送,Client進入FIN_WAIT_1狀態。
(2) 第二次揮手:Server收到FIN後,發送一個ACK給Client,確認序號爲收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
(3) 第三次揮手:Server發送一個FIN,用來關閉Server到Client的數據傳送,Server進入LAST_ACK狀態。
(4) 第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接着發送一個ACK給Server,確認序號爲收到序號+1,Server進入CLOSED狀態,完成四次揮手,而client進入TIME_WAIT狀態。
上面是一方主動關閉,另外一方被動關閉的狀況,實際中還會出現同時發起主動關閉的狀況,具體流程以下圖:
三次握手:兩次握手可能由於丟包而出現死鎖,假設在兩次握手場景中,C向S發送請求,S收到併發送確認請求給C,這時候S認爲鏈接已經創建,並開始發送數據給C,可是那個確認請求丟包了,C不認爲請求創建了,C固然會拒絕接受S發送來的數據,而且再去請求鏈接。S在發出的數據超時後,重複發送一樣的數據。這樣就造成了死鎖。最後回答握手固然能夠四次五次一直握下去,但三次已經夠了。
四次揮手:關閉鏈接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你全部的數據都所有發送給對方了,因此你能夠未必會立刻會關閉SOCKET,也即你可能還須要發送一些數據給對方以後,再發送FIN報文給對方來表示你贊成如今能夠關閉鏈接了,因此它這裏的ACK報文和FIN報文多數狀況下都是分開發送的。
TCP提供的是面向鏈接的、可靠的數據流傳輸,而UDP提供的是非面向鏈接的、不可靠的數據流傳輸。簡單的說,TCP注重數據安全,而UDP數據傳輸快點,但安全性一
1可靠地實現TCP全雙工鏈接的終止
TCP協議在關閉鏈接的四次握手過程當中,最終的ACK是由主動關閉鏈接的一端(後面統稱A端)發出的,若是這個ACK丟失,對方(後面統稱B端)將重發出最終的FIN,所以A端必須維護狀態信息(TIME_WAIT)容許它重發最終的ACK。若是A端不維持TIME_WAIT狀態,而是處於CLOSED 狀態,那麼A端將響應RST分節,B端收到後將此分節解釋成一個錯誤
2容許老的重複分節在網絡中消逝
在關閉「前一個鏈接」以後,立刻又從新創建起一個相同的IP和端口之間的「新鏈接」,「前一個鏈接」的迷途重複分組在「前一個鏈接」終止後到達,而被「新鏈接」收到了。爲了不這個狀況,TCP協議不容許處於TIME_WAIT狀態的鏈接啓動一個新的可用鏈接,由於TIME_WAIT狀態持續2MSL(最大報文段生存時間),就能夠保證當成功創建一個新TCP鏈接的時候,來自舊鏈接重複分組已經在網絡中消逝。
緣由:對於基於TCP的HTTP協議,關閉TCP鏈接的是Server端,這樣,Server端會進入TIME_WAIT狀態,可想而知,對於訪問量大的Web Server,會存在大量的TIME_WAIT狀態。
解決辦法:
1開啓socket重用,容許將TIME_WAIT的socket從新用於TCP鏈接
2開啓快速回收。
主要緣由是某種狀況下對方關閉了socket連接,可是我方忙與讀或者寫,沒有關閉鏈接。或者程序壓根就忘記了這個時候須要關閉鏈接,因而這個資源就一直被程序佔着。
解決辦法: 具體問題具體解決,總結一句話就是在處理資源時必定要記住本身申請的資源要記得主動釋放。