04.12 「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

問題

  1. TCP三次握手的過程是怎麼樣的?

  2. TCP為什麼要三次握手,而不是二次?

  3. 什麼是半連接/syn攻擊?

解析

  • TCP三次握手

「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

來自《計算機網絡》謝希仁著

起初,服務器和客戶端都為CLOSED狀態。在通信開始前,雙方創建各自的傳輸控制塊,服務器進入LISTEN狀態,監聽客戶端發來的連接請求。

第一次握手

客戶端向服務端發送連接請求報文段。該報文段的頭部中SYN=1,ACK=0,seq=x。請求發送後,客戶端便進入SYN-SENT狀態。為防止黑客攻擊,初始序號seq是客戶端隨機產生的一個值x。

注:這裡解釋下什麼是SYN,ACK,seq,ack

「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

  1. 序號:Sequence Number,簡寫為seq.序號字段的值則指的是本報文段所發送的數據(TCP數據部分)的第一個字節的序號。TCP字節流中,每一個字節都要按順序編號。

  2. 確認號:Acknowledgement Number,簡寫為ack,是期望收到對方的下一個報文段的數據(TCP數據部分)的第一個字節的序號。 不要和ACK混起來,兩個不一樣。

  3. 標誌位:共6個,即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:

    (A)URG:緊急指針(urgent pointer)有效。

    (B)ACK:確認序號有效。

    (C)PSH:接收方應該儘快將這個報文交給應用層。

    (D)RST:重置連接。

    (E)SYN:發起一個新連接。

    (F)FIN:釋放一個連接。

「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

第二次握手

服務端收到連接請求報文段後,如果同意連接,則會發送一個應答:SYN=1,ACK=1,seq=y,ack=x+1。

該應答發送完成後便進入SYN-RCVD狀態。

注:ack=x+1,加1是因為SYN和FIN都會佔一個序號,第一次握手時SYN=1,所以這裡要加1。意思是期待收到客戶端的下一個數據序號為x+1。seq=y是服務端隨機生成的一個值y。

「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

第三次握手

當客戶端收到連接同意的應答後,還要向服務端發送一個確認報文段,表示:服務端發來的連接同意應答已經成功收到。該報文段的頭部為:ACK=1,seq=x+1,ack=y+1。

客戶端發完這個報文段後便進入ESTABLISHED狀態,服務端收到這個應答後也進入ESTABLISHED狀態,此時連接的建立完成!

注:ack=y+1,,加1是因為第二次握手時SYN=1,所以這裡要加1,意思是期待收到服務端的下一個數據序號為y+1。這裡seq=x+1,由於第二次握手ACK=1狀態可以帶數據,第三次握手則seq=x+1,如果有帶那就不是這個值了。

「面試題」TCP為什麼要三次握手?什麼是syn攻擊?

上圖是有帶數據的情況

為什麼是三次握手呢?

如果兩次握手就建立連接,可能導致下面的情況:

客戶端A給服務端B發送請求,由於某種原因,這個請求信號Ⅰ阻塞在某個路由處(但沒有失敗),而客戶端A以為請求信號發送失敗,所以重新發了一個請求信號Ⅱ。

服務端B收到了這個請求信號Ⅱ,回了ACK、Seq和ACK number,客戶端A接受到ACK、Seq和ACK number後,連接建立,進行通信,傳輸數據,通信完畢後斷開。

結果這時候第一次發送的請求連接信號Ⅰ傳到了服務端B,服務端B以為客戶端A又請求了一次新的連接,所以回ACK、Seq和ACK number,但由於客戶端A並沒有請求新的連接,會無視服務端B這一次的ACK、Seq和ACK number。此時對服務端B來講,連接已經建立了,其為此次連接分配的資源會一直等待下去。

而多了第三次握手,只有服務端B接收到客戶端A的ACK、Seq number、ACK number後,對服務端B才意味著連接建立。即如果超過了等待的時間,服務端B還未收到相應的ACK等信號,就會釋放之前為其分配的資源。

半連接/syn攻擊

在三次握手過程中,服務器發送SYN-ACK之後,收到客戶端的ACK之前的TCP連接稱為半連接(half-open connect).此時服務器處於Syn_RECV狀態.當收到ACK後,服務器轉入ESTABLISHED狀態.

Syn攻擊就是 攻擊客戶端 在短時間內偽造大量不存在的IP地址,向服務器不斷地發送syn包,服務器回覆確認包,並等待客戶的確認,由於源地址是不存在的,服務器需要不斷的重發直 至超時,這些偽造的SYN包將長時間佔用未連接隊列,正常的SYN請求被丟棄,目標系統運行緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。

Syn攻擊是一個典型的DDOS攻擊。檢測SYN攻擊非常的方便,當你在服務器上看到大量的半連接狀態時,特別是源IP地址是隨機的,基本上可以斷定這是一次SYN攻擊.在Linux下可以如下命令檢測是否被Syn攻擊:

netstat -n -p TCP | grep SYN_RECV



分享到:


相關文章: