圖片來源自網絡:
- 第一次握手:建立連接時,客戶端發送SYN包(seq=x)到服務器,並進入SYN_SEND狀態,等待服務器確認;
- 發送同步信號SYN=1,以及選擇一個初始的字節序號(任意一個正整數值)。
- 客戶端的進程進入SYN-SENT的同步已發送狀態。
- 發送的報文段又稱爲SYN報文段,是不能攜帶數據的,但需要消耗一個序號。
- 第二次握手:服務器收到SYN包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(seq=y),即SYN + ACK包,此時服務器進入SYN_RECV狀態。
- 發送確認連接,同步信號SYN=1,確認信號ACK=1,確認號ack=x+1,然後爲自己的緩存初始化一個序號seq=y
- 然後服務器端就會進入一個SYN-RCVD同步收到狀態
- 這段報文同樣不能攜帶數據,但需要消耗一個序號
- 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
- 客戶端還需要回復一個確認服務器確認的迴應報文,確認信號ACK=1,確認號ack=y+1,自身序號seq = x+1
- 這個報文段可攜帶數據,也可不攜帶,如果不攜帶就不需要消耗序號
- 然後進入數據傳送過程
- 爲什麼需要三次握手才能建立起連接
- 爲了初始化Sequence Number的初始值,來確保接收到的數據,沒有因網絡問題而亂序。
- 第三次握手主要目的是告知服務器,客戶端已接收到服務端的Sequence Number
- 首次握手的隱患---SYN超時
- Server收到Client的SYN,回覆SYN-ACK的時候未收到ACK確認
- Server不斷重試直至超時,Linux默認重試5次,重試時間從1秒開始,每次都翻倍,1+2+4+8+16=31秒,再等待32未迴應,判斷超時。因此Linux默認等待63秒才斷開連接
- 這裏會造成一個安全隱患,不斷觸發連接,耗盡連接請求隊列資源,讓正常的連接隊列無法連接。
- 針對SYN Flood的防護措施
- SYN隊列滿後,通過tcp_syncookies參數回發SYN Cookie,服務端通過原地址端口、目標地址端口、時間戳打造出一個特殊的Sequence Number回發回去,簡稱tcp_syncookies。
- 若爲正常連接則Client會回發SYN Cookie,直接建立連接
- 建立連接後,Client出現故障怎麼辦
- 保活機制
- 向對方發送保活探測報文,如果未收到相應則繼續發送
- 嘗試次數打到保活探測數仍未收到響應則中斷連接
- 保活機制