說明: 通常情況下:一個(gè)正常的TCP連接褐隆,都會(huì)有三個(gè)階段:1才写、TCP三次握手;2回挽、數(shù)據(jù)傳送;3、TCP四次揮手
里面的幾個(gè)概念:
- SYN: (同步序列編號(hào),Synchronize Sequence Numbers)
- ACK: (確認(rèn)編號(hào),Acknowledgement Number)
- FIN: (結(jié)束標(biāo)志,FINish)
TCP三次握手(創(chuàng)建 OPEN)
- 客戶端發(fā)起一個(gè)和服務(wù)創(chuàng)建TCP鏈接的請(qǐng)求缨历,這里是SYN(J)
- 服務(wù)端接受到客戶端的創(chuàng)建請(qǐng)求后以蕴,返回兩個(gè)信息: SYN(K) + ACK(J+1)
- 客戶端在接受到服務(wù)端的ACK信息校驗(yàn)成功后(J與J+1),返回一個(gè)信息:ACK(K+1)
- 服務(wù)端這時(shí)接受到客戶端的ACK信息校驗(yàn)成功后(K與K+1)辛孵,不再返回信息丛肮,后面進(jìn)入數(shù)據(jù)通訊階段
數(shù)據(jù)通訊
- 客戶端/服務(wù)端 read/write數(shù)據(jù)包
TCP四次握手(關(guān)閉 finish)
- 客戶端發(fā)起關(guān)閉請(qǐng)求,發(fā)送一個(gè)信息:FIN(M)
- 服務(wù)端接受到信息后魄缚,首先返回ACK(M+1),表明自己已經(jīng)收到消息宝与。
- 服務(wù)端在準(zhǔn)備好關(guān)閉之前,最后發(fā)送給客戶端一個(gè) FIN(N)消息冶匹,詢問客戶端是否準(zhǔn)備好關(guān)閉了
- 客戶端接受到服務(wù)端發(fā)送的消息后习劫,返回一個(gè)確認(rèn)信息: ACK(N+1)
- 最后,服務(wù)端和客戶端在雙方都得到確認(rèn)時(shí)嚼隘,各自關(guān)閉或者回收對(duì)應(yīng)的TCP鏈接诽里。
詳細(xì)的狀態(tài)說明(以及l(fā)inux相關(guān)參數(shù)調(diào)整)
- SYN_SEND
- 客戶端嘗試鏈接服務(wù)端,通過open方法飞蛹。也就是TCP三次握手中的第1步之后,注意是客戶端狀態(tài)
- sysctl -w net.ipv4.tcp_syn_retries = 2 ,做為客戶端可以設(shè)置SYN包的重試次數(shù)谤狡,默認(rèn)5次(大約180s)引用校長(zhǎng)的話:僅僅重試2次灸眼,現(xiàn)代網(wǎng)絡(luò)夠了
- SYN_RECEIVED
- 服務(wù)接受創(chuàng)建請(qǐng)求的SYN后,也就是TCP三次握手中的第2步墓懂,發(fā)送ACK數(shù)據(jù)包之前
- 注意是服務(wù)端狀態(tài),一般15個(gè)左右正常焰宣,如果很大,懷疑遭受SYN_FLOOD攻擊
- sysctl -w net.ipv4.tcp_max_syn_backlog=4096 , 設(shè)置該狀態(tài)的等待隊(duì)列數(shù)拒贱,默認(rèn)1024宛徊,調(diào)大后可適當(dāng)防止syn-flood,可參見man 7 tcp
- sysctl -w net.ipv4.tcp_syncookies=1 , 打開syncookie逻澳,在syn backlog隊(duì)列不足的時(shí)候,提供一種機(jī)制臨時(shí)將syn鏈接換出
- sysctl -w net.ipv4.tcp_synack_retries = 2 ,做為服務(wù)端返回ACK包的重試次數(shù)暖呕,默認(rèn)5次(大約180s)引用校長(zhǎng)的話:僅僅重試2次斜做,現(xiàn)代網(wǎng)絡(luò)夠了
- ESTABLISHED
客戶端接受到服務(wù)端的ACK包后的狀態(tài),服務(wù)端在發(fā)出ACK在一定時(shí)間后即為ESTABLISHED
sysctl -w net.ipv4.tcp_keepalive_time = 1200 湾揽,默認(rèn)為7200秒(2小時(shí))瓤逼,系統(tǒng)針對(duì)空閑鏈接會(huì)進(jìn)行心跳檢查,如果超過 net.ipv4.tcp_keepalive_probes *net.ipv4.tcp_keepalive_intvl = 默認(rèn)11分库物,終止對(duì)應(yīng)的tcp鏈接霸旗,可適當(dāng)調(diào)整心跳檢查頻率
目前線上的監(jiān)控 waring:600 , critial : 800
- FIN_WAIT1
- 主動(dòng)關(guān)閉的一方,在發(fā)出FIN請(qǐng)求之后戚揭,也就是在TCP四次握手的第1步
- CLOSE_WAIT
- 被動(dòng)關(guān)閉的一方诱告,在接受到客戶端的FIN后,也就是在TCP四次握手的第2步
- FIN_WAIT2
- 主動(dòng)關(guān)閉的一方民晒,在接受到被動(dòng)關(guān)閉一方的ACK后精居,也就是TCP四次握手的第2步
- sysctl -w net.ipv4.tcp_fin_timeout=30, 可以設(shè)定被動(dòng)關(guān)閉方返回FIN后的超時(shí)時(shí)間,有效回收鏈接潜必,避免syn-flood.
- LASK_ACK
- 被動(dòng)關(guān)閉的一方靴姿,在發(fā)送ACK后一段時(shí)間后(確保客戶端已收到)磁滚,再發(fā)起一個(gè)FIN請(qǐng)求佛吓。也就是TCP四次握手的第3步
- TIME_WAIT
- 主動(dòng)關(guān)閉的一方,在收到被動(dòng)關(guān)閉的FIN包后垂攘,發(fā)送ACK维雇。也就是TCP四次握手的第4步
- sysctl -w net.ipv4.tcp_tw_recycle = 1 , 打開快速回收TIME_WAIT,Enabling this option - is not recommended since this causes problems when working with NAT (Network Address Translation)
- sysctl -w net.ipv4.tcp_tw_reuse =1, 快速回收并重用TIME_WAIT的鏈接, 貌似和tw_recycle有沖突搜贤,不能重用就回收?
- net.ipv4.tcp_max_tw_buckets: 處于time_wait狀態(tài)的最多鏈接數(shù)谆沃,默認(rèn)為180000.
相關(guān)說明
- 主動(dòng)關(guān)閉方在接收到被動(dòng)關(guān)閉方的FIN請(qǐng)求后,發(fā)送成功給對(duì)方一個(gè)ACK后,將自己的狀態(tài)由FIN_WAIT2修改為TIME_WAIT仪芒,而必須再等2倍的MSL(Maximum Segment Lifetime,MSL是一個(gè)數(shù)據(jù)報(bào)在internetwork中能存在的時(shí)間)時(shí)間之后雙方才能把狀態(tài) 都改為CLOSED以關(guān)閉連接唁影。目前RHEL里保持TIME_WAIT狀態(tài)的時(shí)間為60秒
- keepAlive策略可以有效的避免進(jìn)行三次握手和四次關(guān)閉的動(dòng)作