過程 第一次 第一次握手:建立連線時,
客戶端 傳送
syn 包(syn=j)到
伺服器 ,並進入
SYN_SENT 狀態,等待伺服器確認;SYN:同步序列編號(
Synchronize Sequence Numbers )。
第二次 第三次 完成三次握手,
客戶端 與伺服器開始傳送
數據 ,在上述過程中,還有一些重要的概念:
未連線佇列 在
三次握手協定 中,
伺服器 維護一個未連線佇列,該佇列為每個
客戶端 的SYN包(
syn =j)開設一個條目,該條目表明伺服器已收到SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連線在
伺服器 處於 Syn_RECV狀態,當伺服器收到客戶的確認包時,刪除該條目,伺服器進入ESTABLISHED狀態。
Backlog參數 表示核心為相應套接字排隊的最大連線個數。SYN-ACK重傳次數
伺服器 傳送完SYN-ACK包,如果未收到客戶確認包,伺服器進行首次重傳,等待一段時間仍未收到客戶確認包,進行第二次重傳,如果重傳次數超過系統規定的最大重傳次數,系統將該連線信息從半連線佇列中刪除。注意,每次重傳等待的時間不一定相同。
三次握手協定 《UNIX 網路編程》中指出,關於backlog參數從未有過正式的定義,BSD 4.2手冊中宣稱它的定義是:“the maximum length the queue of pending connections may grow to”,即未處理連線構成的佇列可能增長到的最大長度,POSIX規範也逐字複製該定義。不過這個定義中並沒有明確到底這個連線指的是SYN_RCVD狀態的連線,還是未由進程接受的處於ESTABLISHED狀態的連線,亦或兩者皆可。
不論這個backlog參數到底指的是哪一個,對於伺服器而言,都需要儘快的去處理已經處於ESTABLISHED狀態的連線。而僅僅對於backlog來說,我們需要取一個比較大的值以應對大量的服務請求。
半連線存活時間
是指半連線佇列的條目存活的最長時間,也即
服務 器從收到SYN包到確認這個
報文 無效的最長時間,該時間值是所有重傳請求包的最長等待時間總和。有時我們也稱半連線存活時間為Timeout時間、SYN_RECV存活時間。
TCP頭結構 面向連線的TCP三次握手是Syn Flood存在的基礎。
TCP協定頭最少20個位元組,包括以下的區域(由於翻譯不盡相同,文章中給出相應的英文單詞):
TCP 源連線埠 (Source Port):16位的源連線埠其中包含初始化通信的連線埠。源連線埠和源
IP 地址的作用是標示
報文 的返回地址。
TCP目的連線埠(Destination port): 16位的目的連線埠域定義傳輸的目的。這個連線埠指明
報文 接收計算機上的
應用程式 地址接口。
TCP 序列號 (序列碼,Sequence Number):32位的
序列號 由接收端計算機使用,重新分段的
報文 成最初形式。當SYN出現,序列碼實際上是初始序列碼(
ISN ),而第一個數
據
位元組 是ISN+1。這個
序列號 (序列碼)是可以補償傳輸中的 不一致。
TCP應答號(Acknowledgment Number): 32位的序列號由接收端計算機使用,重組分段的
報文 成最初形式。如果設定了ACK控制位,這個值表示一個準備接收的包的序列碼。
數據 偏移量(HLEN):4位包括TCP頭大小,指示何處數據開始。
TCP四次揮手結束連線 保留(Reserved): 6位值域,這些位必須是0。為了將來定義新的用途所保留。
標誌(Code Bits): 6位標誌域。表示為:緊急標誌、有意義的應答標誌、推、重置連線標誌、同步
序列號 標誌、完成傳送
數據 標誌。按照順序排列是:URG、ACK、PSH、RST、SYN、FIN。
視窗(Window): 16位,用來表示想收到的每個TCP
數據段 的大小。
校驗位(Checksum): 16位TCP頭。源機器基於
數據 內容計算一個數值,收信息機要與源機器數值結果完全一樣,從而證明數據的有效性。
優先指針(緊急,Urgent Pointer): 16位,指向後面是優先
數據 的位元組,在URG標誌設定了時才有效。如果URG標誌沒有被設定,緊急域作為填充。加快處理標示為緊急的
數據段 。
選項(Option): 長度不定,但長度必須是一個
位元組 。如果沒有選項就表示這一個位元組的域等於0。
關閉TCP連線:改進的三次握手 對於一個已經建立的連線,TCP使用改進的三次握手來釋放連線(使用一個帶有FIN附加標記的報文段)。TCP關閉連線的步驟如下:
第一步,當主機A的應用程式通知TCP數據已經傳送完畢時,TCP向主機B傳送一個帶有FIN附加標記的報文段(FIN表示英文finish)。
第二步,主機B收到這個FIN報文段之後,並不立即用FIN報文段回復主機A,而是先向主機A傳送一個確認序號ACK,同時通知自己相應的應用程式:對方要求關閉連線(先傳送ACK的目的是為了防止在這段時間內,對方重傳FIN報文段)。
第三步,主機B的應用程式告訴TCP:我要徹底的關閉連線,TCP向主機A送一個FIN報文段。
第四步,主機A收到這個FIN報文段後,向主機B傳送一個ACK表示連線徹底釋放。
標誌控制 URG:緊急標誌
緊急(The urgent pointer) 標誌有效。緊急標誌置位,
ACK:確認標誌
確認編號(Acknowledgement Number)欄有效。大多數情況下該標誌
位是置位的。TCP報頭內的確認編號欄內包含的確認編號(w+1,Figure:1)為下一個預期的序列編號,同時提示遠端系統已經成功接收所有
數據 。
TCP三次握手是Syn Flood存在的基礎 PSH:推標誌
該標誌置位時,接收端不將該
數據 進行佇列處理,而是儘可能快將數據轉由套用處理。在處理
telnet 或 rlogin 等互動模式的連線時,該標誌總是置位的。
RST:復位標誌
復位標誌有效。用於復位相應的TCP連線。
SYN:同步標誌
同步序列編號(Synchronize Sequence Numbers)欄有效。該標誌僅在三次握手建立TCP連線時有效。它提示TCP連線的
服務端 檢查序列編號,該序列編號為TCP連線初始端(一般是
客戶端 )的初始序列編號。在這裡,可以把TCP序列編號看作是一個範圍從0到4,294,967,295的32位
計數器 。通過TCP連線交換的
數據 中每一個
位元組 都經過序列編號。在TCP報頭中的序列編號欄包括了TCP分段中第一個
位元組 的序列編號。
FIN:結束標誌
帶有該標誌置位的數據包用來結束一個TCP回話,但對應連線埠仍處於開放狀態,準備接收後續數據。
分析報頭信息: TCP層接收到相應的TCP和IP報頭,將這些信息存儲到記憶體中。
檢查TCP校驗和(checksum): 標準的校驗和位於分段之中(Figure:2)。如果檢驗失敗,不返回確認,該分段丟棄,並等待
客戶端 進行重傳。
查找協定控制塊(PCB{}): TCP查找與該連線相關聯的協定控制塊。如果沒有找到,TCP將該分段丟棄並返回RST。(這就是TCP處理沒有
連線埠監聽 情況下的機制) 如果該協定控制塊存在,但狀態為關閉,
服務端 不調用connect()或listen()。該分段丟棄,但不返回RST。
客戶端 會嘗試重新建立連線請求。
建立新的socket : 當處於
監聽狀態 的socket收到該分段時,會建立一個子
socket ,同時還有socket{},tcpcb{}和pub{}建立。這時如果有錯誤發生,會通過標誌位來拆除相應的
socket 和釋放記憶體,TCP連線失敗。如果快取佇列處於填滿狀態,TCP認為有錯誤發生,所有的後續連線請求會被拒絕。這裡可以看出SYN Flood攻擊是如何起作用的。
丟棄: 如果該分段中的標誌為
RST 或
ACK ,或者沒有SYN標誌,則該分段丟棄。並釋放相應的記憶體。
數據傳輸 SND.NXT :傳送下一個
SND.UP :傳送優先指針
SND.WL2 :用於最後視窗更新的段確認號
ISS :初始傳送
序列號 三次握手 RCV.NXT :接收下一個
RCV.WND :接收下一個
RCV.UP :接收優先指針
IRS :初始接收序列號
當前段變數
SEG.ACK :段確認標記
SEG.LEN :段長
SEG.WND :段視窗
SEG.UP :段緊急指針
SEG.PRC :段優先權
CLOSED表示沒有連線,各個狀態的意義如下:
LISTEN :監聽
來自遠方 TCP連線埠的連線請求。
SYN-SENT :在傳送連線請求後等待匹配的連線請求。
SYN-RECEⅣED :在收到和傳送一個連線請求後等待對連線請求的確認。
ESTABLISHED :代表一個打開的連線,
數據 可以傳送給用戶。
FIN-WAIT-1 :等待遠程TCP的連線中斷請求,或先前的連線中斷請求的確認。
FIN-WAIT-2 :從遠程TCP等待連線中斷請求。
CLOSE-WAIT :等待從
本地用戶 發來的連線中斷請求。
CLOSING :等待遠程TCP對連線中斷的確認。
LAST-ACK :等待原來發向遠程TCP的連線中斷請求的確認。
TIME-WAIT :等待足夠的時間以確保遠程TCP接收到連線中斷請求的確認。
CLOSED :沒有任何連線狀態。
TCP連線過程是狀態的轉換,促使發生狀態轉換的是用戶調用:OPEN,SEND,RECEⅣE,CLOSE,ABORT和STATUS。傳送過來的
數據段 ,特別那些包括以下標記的數據段SYN,ACK,RST和FIN。還有逾時,上面所說的都會時TCP狀態發生變化。
序列標識 序列號
在TCP連線中傳送的位元組都有一個
序列號 。因為編了號,所以可以確認它們的收到。對
序列號 的確認是累積性的。TCP必須進行的
序列號 比較操作種類包括以下幾種:
對於傳送的
數據 TCP要接收確認,確認時必須進行的:
SEG.ACK = 接收TCP的確認,接收TCP期待的下一個
序列號 。
三次握手數據 SEG.SEQ+SEG.LEN-1 =
數據段 的最後一個
序列號 。
如果一個
數據段 的
序列號 小於等於確認號的值,那么整個數據段就被確認了。而在接收
數據 時下面的比較操作是必須的:
RCV.NXT = 期待的
序列號 和接收視窗的最低沿。
RCV.NXT+RCV.WND:1 = 最後一個
序列號 和接收視窗的最高沿。
SEG.SEQ+SEG.LEN:1 = 接收到的最後一個
序列號 。
基於三次握手的SYN洪水攻擊 基本原理 建設一個小型的模仿環境假設有3台接入
網際網路 的機器。A為攻擊者操縱的攻擊機。B為中介跳板機器(受信任的
伺服器 )。C為受害者使用的機器(多是
伺服器 ),這裡把C機器鎖定為目標機器。A機器向B機器傳送SYN包,請求建立連線,這時已經回響請求的B機器會向A機器回應SYN/ACK表明同意建立連線,當A機器接受到B機器傳送的SYN/ACK回應時,傳送應答ACK建立A機器與B機器的網路連線。這樣一個兩台機器之間的TCP通話信道就建立成功了。
三次握手協定 B終端受信任的
伺服器 向C機器發起TCP連線,A機器對
伺服器 C發起SYN信息,使C機器不能回響B機器。在同時A機器也向B機器傳送虛假的C機器回應的SYN
數據 包,接收到SYN數據包的B機器(被C機器信任)開始傳送應答連線建立的SYN/ACK數據包,這時C機器正在忙於回響以前傳送的SYN數據而無暇回應B機器,A機器的攻擊者預測出B機器包的
序列號 (TCP
序列號 預測難度有些大)假冒C機器向B機器傳送應答ACK這時攻擊者騙取B機器的信任,假冒C機器與B機器建立起TCP協定的對話連線。這個時候的C機器還是在回響攻擊者A機器傳送的
SYN 數據。
TCP協定棧的弱點 TCP連線的
資源 消耗,其中包括:數據包信息、條件狀態、
序列號 等。通過故意不完成建立連線所需要的三次握手過程,造成連線一方的
資源 耗盡。
通過攻擊者有意的不完成建立連線所需要的三次握手的全過程,從而造成了C機器的
資源 耗盡。
序列號 的可預測性,目標
主機 應答連線請求時返回的SYN/ACK的序列號時可預測的。