TCP協議的通訊方式
一、TCP三次握手
傳輸控制協議(Transport Control Protocol)是一種面向連接的,可靠的傳輸層協議。面向連接是指一次正常的TCP傳輸需要通過在TCP客戶端和TCP服務端建立特定的虛電路連接來完成,該過程通常被稱為“三次握手”。可靠性可以通過很多種方法來提供保證,在這里我們關心的是數據序列和確認。TCP通過數據分段(Segment)中的序列號保證所有傳輸的數據可以在遠端按照正常的次序進行重組,而且通過確認保證數據傳輸的完整性。要通過TCP傳輸數據,必須在兩端主機之間建立連接。舉例說明,TCP客戶端需要和TCP服務端建立連接,過程如下所示:
在第一步中,客戶端向服務端提出連接請求。這時TCP SYN標志置位。客戶端告訴服務端序列號區域合法,需要檢查。客戶端在TCP報頭的序列號區中插入自己的ISN。服務端收到該TCP分段后,在第二步以自己的ISN回應(SYN標志置位),同時確認收到客戶端的第一個TCP分段(ACK標志置位)。在第三步中,客戶端確認收到服務端的ISN(ACK標志置位)。到此為止建立完整的TCP連接,開始全雙工模式的數據傳輸過程。
二、TCP標志
這里有必要介紹一下TCP分段中的標志(Flag)置位情況。如下圖所示。
*SYN:同步標志
同步序列編號(Synchronize Sequence Numbers)欄有效。該標志僅在三次握手建立TCP連接時有效。它提示TCP連接的服務端檢查序列編號,該序列編號為TCP連接初始端(一般是客戶端)的初始序列編號。在這里,可以把TCP序列編號看作是一個范圍從0到4,294,967,295的32位計數器。通過TCP連接交換的數據中每一個字節都經過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個字節的序列編號。
*ACK:確認標志
確認編號(Acknowledgement Number)欄有效。大多數情況下該標志位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure-1)為下一個預期的序列編號,同時提示遠端系統已經成功接收所有數據。
*RST:復位標志
復位標志有效。用于復位相應的TCP連接。
*URG:緊急標志
緊急(The urgent pointer) 標志有效。緊急標志置位,
*PSH:推標志
該標志置位時,接收端不將該數據進行隊列處理,而是盡可能快將數據轉由應用處理。在處理 telnet 或 rlogin 等交互模式的連接時,該標志總是置位的。
*FIN:結束標志
帶有該標志置位的數據包用來結束一個TCP回話,但對應端口仍處于開放狀態,準備接收后續數據。#p#
三、TCP端口
為了能夠支持同時發生的并行訪問請求,TCP提供一種叫做“端口”的用戶接口。端口是操作系統核心用來識別不同的網絡回話過程。這是一個嚴格的傳輸層定義。通過TCP端口和IP地址的配合使用,可以提供到達終端的通訊手段。實際上,在任一時刻的互聯網絡連接可以由4個數字進行描述: 來源IP地址和來源端口,目的IP地址和目的端口。位于不同系統平臺,用來提供服務的一端通過標準的端口提供相應服務。舉例來說,標準的TELNET守護進程(telnet daemon)通過監聽TCP 23端口,準備接收用戶端的連接請求。
四、TCP緩存(TCP Backlog)
通常情況下,操作系統會使用一塊限定的內存來處理TCP連接請求。每當用戶端發送的SYN標志置位連接請求到服務端的一個合法端口(提供TCP服務的一端監聽該端口)時,處理所有連接請求的內存使用量必須進行限定。如果不進行限定,系統會因處理大量的TCP連接請求而耗盡內存,這在某種程度上可以說是一種簡單的DoS攻擊。這塊經過限定的,用于處理TCP連接的內存稱為TCP緩存(TCP Backlog),它實際上是用于處理進站(inbound)連接請求的一個隊列。該隊列保存那些處于半開放(half-open)狀態的TCP連接項目,和已建立完整連接但仍未由應用程序通過accept()調用提取的項目。如果這個緩存隊列被填滿,除非可以及時處理隊列中的項目,否則任何其它新的TCP連接請求會被丟棄。
一般情況下,該緩存隊列的容量很小。原因很簡單,在正常的情況下TCP可以很好的處理連接請求。如果當緩存隊列填滿的時候新的客戶端連接請求被丟棄,客戶端只需要簡單的重新發送連接請求,服務端有時間清空緩存隊列以相應新的連接請求。
在現實環境中,不同操作系統支持TCP緩沖隊列有所不同。在BSD結構的系統中,如下所示:
五、TCP進站(Inbound)處理過程
為了更好的講述TCP SYN Flood的攻擊過程,我們先來介紹一下正常情況下,TCP進站處理的過程。
服務端處于監聽狀態,客戶端用于建立連接請求的數據包(IP packet)按照TCP/IP協議堆棧組合成為TCP處理的分段(segment)。
分析報頭信息: TCP層接收到相應的TCP和IP報頭,將這些信息存儲到內存中。
檢查TCP校驗和(checksum):標準的校驗和位于分段之中(Figure-2)。如果檢驗失敗,不返回確認,該分段丟棄,并等待客戶端進行重傳。
查找協議控制塊(PCB{}):TCP查找與該連接相關聯的協議控制塊。如果沒有找到,TCP將該分段丟棄并返回RST。(這就是TCP處理沒有端口監聽情況下的機制) 如果該協議控制塊存在,但狀態為關閉,服務端不調用connect()或listen()。該分段丟棄,但不返回RST。客戶端會嘗試重新建立連接請求。
建立新的socket:當處于監聽狀態的socket收到該分段時,會建立一個子socket,同時還有socket{},tcpcb{}和pcb{}建立。這時如果有錯誤發生,會通過標志位來拆除相應的socket和釋放內存,TCP連接失敗。如果緩存隊列處于填滿狀態,TCP認為有錯誤發生,所有的后續連接請求會被拒絕。這里可以看出SYN Flood攻擊是如何起作用的。
丟棄:如果該分段中的標志為RST或ACK,或者沒有SYN標志,則該分段丟棄。并釋放相應的內存。
【編輯推薦】