建連接時SYN超時問題
如果 server 端因為某種情況沒有收到 client 回來的 ACK,那么,這個連接處還處于一個未建立的狀態(tài)。于是,server端如果在一定時間內(nèi)沒有收到,則 server 端的 TCP 會重發(fā) SYN_ACK。
在Linux下,默認重試次數(shù)為5次,重試的間隔時間從1s開始每次都翻倍,5次的重試時間間隔為1s, 2s, 4s, 8s, 16s,總共31s,第5次發(fā)出后還要等32s都知道第5次也超時了。如果第五次重傳之后,還未收到客戶端的 ACK,server 端的 TCP 才會把斷開這個連接。
關(guān)于SYN Flood攻擊
攻擊者短時間偽造不同 IP 地址的 SYN 報文,服務(wù)端每接收到一個 SYN 報文,就進入SYN_RCVD 狀態(tài),但服務(wù)端發(fā)送出去的 ACK + SYN 報文,無法得到未知 IP 主機的 ACK 應(yīng)答,久而久之就會占滿服務(wù)端的 SYN 接收隊列(未連接隊列),使得服務(wù)器不能為正常用戶服務(wù)。
避免方式
設(shè)置 tcp_syncookies = 1。當 SYN 隊列滿了后,TCP 會通過源地址端口、目標地址端口和時間戳打造出一個特別的 Sequence Number 發(fā)回去(又叫cookie)。
如果是攻擊者則不會有響應(yīng),如果是正常連接,則會把這個 SYN Cookie 發(fā)回來,然后服務(wù)端可以通過 cookie 建連接。
設(shè)置 netdev_max_backlog 的值,確定鏈接隊列的大小。當網(wǎng)卡接收數(shù)據(jù)包的速度大于內(nèi)核處理的速度時,會有一個隊列保存這些數(shù)據(jù)包。
通過設(shè)置 netdev_max_backlog 的值,確定 SYN_RCVD 狀態(tài)連接的最大個數(shù)。
通過設(shè)置 tcp_abort_on_overflow 的值。當超出處理能時,對新的 SYN 直接回報 RST,丟棄連接。
斷開連接中的異常
從上面的描述可以知道,TIME_WAIT 是個很重要的狀態(tài),但是如果在大并發(fā)的短鏈接下,TIME_WAIT 就會太多。TIME_WAIT過多會占用大量的內(nèi)存資源和端口資源。
優(yōu)化法一:tcp_tw_reuse
設(shè)置tcp_tw_reuse = 1,則可以復(fù)用處于 TIME_WAIT 的 socket 為新的連接所用。
有一點需要注意的是,tcp_tw_reuse 功能只能用客戶端(連接發(fā)起方),因為開啟了該功能,在調(diào)用 connect() 函數(shù)時,內(nèi)核會隨機找一個 time_wait 狀態(tài)超過 1 秒的連接給新的連接復(fù)用。
使用 tcp_timestamps = 1 選項,還有一個前提,需要打開對 TCP 時間戳的支持,即這個時間戳的字段是在 TCP 頭部的「選項」里,用于記錄 TCP 發(fā)送方的當前時間戳和從對端接收到的最新時間戳。
由于引入了時間戳,我們在前面提到的 2MSL 問題就不復(fù)存在了,因為重復(fù)的數(shù)據(jù)包會因為時間戳過期被自然丟棄。
優(yōu)化法二:tcp_max_tw_buckets
這個值默認為 18000,當系統(tǒng)中處于 TIME_WAIT 的連接一旦超過這個值時,系統(tǒng)就會將后面的 TIME_WAIT 連接狀態(tài)重置。
這個方法過于暴力,而且治標不治本,帶來的問題遠比解決的問題多,不推薦使用。
-
網(wǎng)絡(luò)
+關(guān)注
關(guān)注
14文章
7570瀏覽量
88823 -
TCP
+關(guān)注
關(guān)注
8文章
1356瀏覽量
79095 -
連接
+關(guān)注
關(guān)注
2文章
95瀏覽量
20976 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7015
發(fā)布評論請先 登錄
相關(guān)推薦
評論