天天看點

TCP/IP協定解析

1. TCP-IP四層網絡模型

當應用程式用TCP傳送資料時,資料被送入協定棧中,然後逐個通過每一層直到被當作一串比特流送入網絡。當目的主機收到以太網資料幀時,資料就開始從協定棧中由底向上升,同時去掉各層協定加上的封包首部。每層協定盒都要去檢查封包首部中的協定辨別,以确定接收資料的上層協定。

TCP/IP協定解析

 

應用層的資料傳到傳輸層,在傳輸層會加上tcp頭資訊,其中會攜帶接收端主機端口資訊,到達接收端後将封包交給指定端口的程序處理;

在網絡層會增加IP頭,其中包含IP位址資訊,接收端收到後,會判斷IP位址是不是自己,如果不是就轉發。

鍊路層會添加mac頭,指定要發送給的主機mac。

2. TCP和UDP

IP 協定

TCP 和 UDP都是使用IP作為網絡層協定。IP 協定提供了資料封包處理和分發服務,每個 IP 封包包含一個目的位址的字段;但IP協定可能會發生封包丢失、封包順序打亂,重複發送的情況,是以 IP 協定是一個不可靠的協定。

IP 協定層之上的傳輸層,提供了兩種可以選擇的協定:TCP、UPD。這兩種協定都是建立在 IP 層所提供的服務基礎上。

TCP/IP

TCP協定能夠檢測和恢複IP層提供的主機到主機的通信中可能發生的封包丢失、重複及其他錯誤。TCP 提供了一個可信賴的位元組流通道。TCP協定是一種面向連接配接的協定,在使用 TCP進行通信之前,兩個應用程式之間會建立一個TCP連接配接。

UDP/IP

UDP 協定沒有對IP層産生的錯誤進行修複,而是簡單的擴充了IP協定“盡力而為”的資料封包服務,使他能夠在應用程式之間工作,而不是在主機之間工作,是以使用 UDP協定必須要考慮到封包丢失,順序混亂的問題。

那麼TCP是如何做到可靠傳輸的呢?答案是三次握手與四次揮手。

TCP三向交握與四次揮手

1)TCP三向交握

TCP協定在傳輸之前,需要通過三次握手建立一個連接配接,所謂的三次握手,就是在建立 TCP 連結時,需要用戶端和服務端總共發送 3個包來确認連接配接的建立。

第一次握手:用戶端A将标志位SYN置為1,随機産生一個值為seq=J(J的取值範圍為=1234567)的資料包到伺服器,用戶端A進入SYN_SENT狀态,等待服務端B确認;

第二次握手:服務端B收到資料包後由标志位SYN=1知道用戶端A請求建立連接配接,服務端B将标志位SYN和ACK都置為1,ack=J+1,随機産生一個值seq=K,并将該資料包發送給用戶端A以确認連接配接請求,服務端B進入SYN_REVD狀态。

第三次握手:用戶端A收到确認後,檢查ack是否為J+1,ACK是否為1,如果正确則将标志位ACK置為1,ack=K+1,并将該資料包發送給服務端B,服務端B檢查ack是否為K+1,ACK是否為1,如果正确則連接配接建立成功,用戶端A和服務端B進入ESTABLISHED狀态。

TCP/IP協定解析

完成了三次握手,随後用戶端A與服務端B之間可以開始傳輸資料了。

為什需要三次握手?

三次握手是為了防止對已失效的連接配接請求封包段資訊建立連接配接。例如client發出的第一個連接配接請求,但是在某個網絡結點長時間的滞留了,以緻延誤到連接配接釋放以後的某個時間才到達server。這是一個早已失效的封包段,但server收到此失效的連接配接請求封包段後,就誤認為是client再次發出的一個新的連接配接請求。于是就向client發出确認封包段,同意建立連接配接。

如果是二次握手的話,這時候server會建立新的ESTABLISHED的連接配接,并等待接收資料。由于現在client并沒有發出建立連接配接的請求,是以不會理睬server的确認,也不會向server發送資料。但server一直等待client發來資料。這樣,server的很多資源就浪費掉了。

采用“三次握手”可以防止上述現象。因為client不會向server的确認發出回報,是以server就不會建立ESTABLISHED連接配接。主要目的防止server端一直等待,浪費資源。

SYN攻擊

TCP的幾個相關概念

未連接配接隊列:在三次握手協定中,伺服器維護一個未連接配接隊列,該隊列為每個用戶端的SYN包(syn=j)開設一個條目,該條目表明伺服器已收到SYN包,并向客戶發出确認,正在等待客戶的确認包。這些條目所辨別的連接配接在伺服器處于Syn_RECV狀态,當伺服器收到客戶的确認包時,删除該條目,伺服器進入ESTABLISHED狀态。

SYN-ACK重傳次數:伺服器發送完SYN-ACK包,如果未收到客戶确認包,伺服器進行首次重傳,等待一段時間仍未收到客戶确認包,進行第二次重傳,如果重傳次數超過系統規定的最大重傳次數,系統将該連接配接資訊從半連接配接隊列中删除。

半連接配接存活時間:是指半連接配接隊列的條目存活的最長時間,也即服務從收到SYN包到确認這個封包無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。也稱為Timeout時間、SYN_RECV存活時間。

SYN攻擊原理

SYN攻擊屬于DOS攻擊的一種,配合IP欺騙,SYN攻擊能達到很好的效果,通常,用戶端在短時間内僞造大量不存在的IP位址,向伺服器發送大量的半連接配接請求,耗費server端CPU和記憶體資源,而伺服器一直到逾時,才将此條目從未連接配接隊列删除。這些僞造的SYN包将長時間占用未連接配接隊列,正常的SYN請求被丢棄,目标系統運作緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。

檢測SYN攻擊

檢測SYN攻擊非常的友善,當你在伺服器上看到大量的半連接配接狀态時,特别是源IP位址是随機的,基本上可以斷定這是一次SYN攻擊。我們使用系統自帶的netstat 工具來檢測SYN攻擊:

root@VM000000587:~# netstat -n -p TCP |grep SYN
tcp        0      0 192.168.163.167:8001    20.3.197.159:48472      SYN_RECV    -               
tcp        0      0 192.168.163.167:8001    20.3.197.159:48474      SYN_RECV    -           

2)TCP四次揮手

第一次揮手:Client發送一個FIN,用來關閉Client到Server的資料傳送,Client進入FIN_WAIT_1狀态。

第二次揮手:Server收到FIN後,發送一個ACK給Client,确認序号為收到序号+1(與SYN相同,一個FIN占用一個序号),Server進入CLOSE_WAIT狀态。

第三次揮手:Server發送一個FIN,用來關閉Server到Client的資料傳送,Server進入LAST_ACK狀态。

第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀态,接着發送一個ACK給Server,确認序号為收到序号+1,Server進入CLOSED狀态,完成四次揮手。

TCP/IP協定解析
為什麼建立連接配接是三次握手,而關閉連接配接卻是四次揮手呢?

這是因為在建立連接配接時,服務端收到建立連接配接請求的SYN封包後,把ACK和SYN放在一個封包裡發送給了用戶端。

而關閉連接配接時,當收到用戶端的FIN封包時,僅表示用戶端不再發送資料了但是還能接收資料,此時服務端可能還有業務資料還要發送給用戶端。是以,己方ACK和FIN一般都會分開發送(ack表示确認收到請求,FIN表示結束發送封包)。

滑動視窗

數建立可靠連接配接以後,就可以進行資料傳輸了。在通信過程中,最重要的是資料包,即協定傳輸的資料。為了避免資料擁堵接收方無法全部接收而造成的丢包,需要對發方進行流量控制,而通過滑動視窗機制可以實作流量控制。

滑動視窗協定

發送和接受方都會維護一個資料幀的序列,這個序列被稱作視窗。發送方的視窗大小由接受方确定,目的在于控制發送速度,以免接受方的緩存不夠大而導緻溢出,同時控制流量也可以避免網絡擁塞。

TCP/IP協定解析

上面圖中上邊為發送方,下邊為接收方,視窗大小為5,資料幀共20位,這是資料發送前發送方告訴接收方的資料長度。發送方發送0号資料幀,接受方接受0号後,接收方的視窗向右移動1位,然後給發送方成功回報,發送方收到回報後,視窗也向右移動一位。

如果沒有收到回報,發送方視窗不能滑動。如果超過指定時間仍然沒有收到回報,例如0号資料幀,發送方會再次發送0号資料,直至收到回報,視窗才能向下滑動。

視窗大小代表能同時發送的資料幀數,即發送方可以不等待回報而連續發送的最大幀數,本例中發送方最多能一次發送5個資料幀。同時發送5個時,例如0,1,2,3,4,如果1,2,3,4号資料幀都收到了成功回報,但0号未收到,此時接收方視窗不可滑動,直至0号收到成功回報。

同理,如果接收方收到1,2,3,4,但是沒有收到0号資料幀,此時也是不能向下滑動的,直至收到0号。

繼續閱讀