一、TCP標(biāo)志位
在講TCP三次握手和四次揮手之前其兴,先說一下TCP標(biāo)志位顶瞒,方便后續(xù)的理解。
簡單來說元旬,TCP標(biāo)志位的值代表了當(dāng)前請求的目的榴徐。
標(biāo)志位一共有6種,分別是:
- SYN(synchronous): 發(fā)送/同步標(biāo)志匀归,用來建立連接坑资,和下面的第二個標(biāo)志位ACK搭配使用。連接開始時穆端,SYN=1袱贮,ACK=0,代表連接開始但是未獲得響應(yīng)体啰。當(dāng)連接被響應(yīng)的時候攒巍,標(biāo)志位會發(fā)生變化,其中ACK會置為1荒勇,代表確認(rèn)收到連接請求柒莉,此時的標(biāo)志位變成了 SYN=1,ACK=1枕屉。
- ACK(acknowledgement):確認(rèn)標(biāo)志常柄,表示確認(rèn)收到請求。
- PSH(push) :表示推送操作搀擂,就是指數(shù)據(jù)包到達(dá)接收端以后西潘,不對其進(jìn)行隊(duì)列處理,而是盡可能的將數(shù)據(jù)交給應(yīng)用程序處理哨颂;
- FIN(finish):結(jié)束標(biāo)志喷市,用于結(jié)束一個TCP會話;
- RST(reset):重置復(fù)位標(biāo)志威恼,用于復(fù)位對應(yīng)的TCP連接品姓。
- URG(urgent):緊急標(biāo)志,用于保證TCP連接不被中斷箫措,并且督促中間層設(shè)備盡快處理腹备。
此外,還有兩個序號:
- Sequence number :順序號斤蔓,發(fā)送數(shù)據(jù)包中的第一個字節(jié)的序列號植酥,一般為小寫的seq。
- Acknowledge number:確認(rèn)號,響應(yīng)前面的seq友驮,值為seq+1漂羊,可以理解為期望下次發(fā)出的序列號為seq+1;
二卸留、TCP三次握手
1.TCP三次握手概述
所謂三次握手(Three-way Handshake)走越,是指建立一個TCP連接時,需要客戶端和服務(wù)器總共發(fā)送3個包耻瑟。 三次握手的目的是連接服務(wù)器指定端口旨指,建立TCP連接,并同步連接雙方的順序號和確認(rèn)號并交換 TCP信息
2.圖解TCP三次握手
- 第一次握手:客戶端Client發(fā)送位碼為SYN=1,隨機(jī)產(chǎn)生seq=x的數(shù)據(jù)包到服務(wù)器匆赃,服務(wù)器Server由SYN=1知道淤毛,客戶端Client要求建立聯(lián)機(jī);
- 第二次握手:服務(wù)器Server收到請求后要確認(rèn)聯(lián)機(jī)信息算柳,向客戶端Client發(fā)送ack=(客戶端Client請求連接時的seq)+1低淡,SYN=1,ACK=1瞬项,產(chǎn)生seq=y的包,代表接收到連接請求并且向客戶端再次確認(rèn)蔗蹋;
- 第三次握手:客戶端Client收到后檢查ack是否正確,即第一次發(fā)送的seq+1囱淋,以及位碼ACK是否為1猪杭,代表收到了服務(wù)器端發(fā)過來的確認(rèn)信息。之后客戶端Client會再向服務(wù)器發(fā)送ack=(服務(wù)器Server的seq+1)妥衣,ACK=1皂吮,服務(wù)器Server收到后確認(rèn)ack 值與ACK=1,連接建立成功税手。
3.針對TCP連接的安全問題:SYN攻擊
- 危害:SYN攻擊屬于DOS攻擊的一種蜂筹,它利用TCP協(xié)議缺陷,通過發(fā)送大量的半連接請求芦倒,耗費(fèi)CPU和內(nèi)存資源艺挪。SYN攻擊除了能影響主機(jī)外,還可以危害路由器兵扬、防火墻等網(wǎng)絡(luò)系統(tǒng)麻裳,事實(shí)上SYN攻擊并不管目標(biāo)是什么系統(tǒng),只要這些系統(tǒng)打開TCP服務(wù)就可以實(shí)施器钟。
- 原理:在三次握手過程中津坑,服務(wù)器發(fā)送SYN-ACK(確認(rèn)收到客戶端請求的連接)之后,收到客戶端的ACK(第三個包)之前的TCP連接稱為半連接(half-open connect).此時服務(wù)器處于SYN_RECV(等待客戶端相應(yīng))狀態(tài)傲霸,如果接收到客戶端的ACK国瓮,則TCP連接成功,如果未接受到,則會重發(fā)請求直至成功乃摹。SYN攻擊就是 攻擊客戶端 在短時間內(nèi)偽造大量不存在的IP地址,向服務(wù)器不斷地發(fā)送SYN包跟衅,服務(wù)器回復(fù)確認(rèn)包孵睬,并等待客戶的確認(rèn),由于源地址是不存在的伶跷,服務(wù)器需要不斷的重發(fā)直 至超時掰读,這些偽造的SYN包將長時間占用未連接隊(duì)列,影響了正常的SYN叭莫,目標(biāo)系統(tǒng)運(yùn)行緩慢蹈集,嚴(yán)重者引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓。
- 檢測:檢測SYN攻擊非常的方便雇初,當(dāng)在服務(wù)器上看到大量的半連接狀態(tài)時拢肆,特別是源IP地址是隨機(jī)的,基本上可以斷定這是一次SYN攻擊靖诗。
- 防范:主要有兩大類郭怪,一類是通過防火墻、路由器等過濾網(wǎng)關(guān)防護(hù)刊橘,另一類是通過加固TCP/IP協(xié)議棧防范.但必須清楚的是鄙才,SYN攻擊不能完全被阻止,我們所做的是盡可能的減輕SYN攻擊的危害促绵,除非將TCP協(xié)議重新設(shè)計攒庵。
過濾網(wǎng)關(guān)防護(hù):
- 網(wǎng)關(guān)超時設(shè)置
- SYN網(wǎng)關(guān)
- SYN代理
加固TCP/IP協(xié)議棧:
- SynAttackProtect機(jī)制
- SYN cookies技術(shù)
- 增加最大半連接數(shù)
- 縮短超時時間
三、圖解TCP四次揮手
- 客戶端Client進(jìn)程發(fā)出連接釋放報文败晴,并且停止發(fā)送數(shù)據(jù)浓冒。其中FIN=1,順序號為seq=m(等于前面已經(jīng)傳送過來的數(shù)據(jù)的最后一個字節(jié)的序號加1)位衩,此時裆蒸,客戶端Client進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài)。 TCP規(guī)定糖驴,F(xiàn)IN報文段即使不攜帶數(shù)據(jù)僚祷,也要消耗一個序號。
- 服務(wù)器Server收到連接釋放報文贮缕,發(fā)出確認(rèn)報文辙谜,ACK=1,ack=m+1感昼,并且?guī)献约旱捻樞蛱杝eq=n装哆,此時,服務(wù)器Server就進(jìn)入了CLOSE-WAIT(關(guān)閉等待)狀態(tài)。TCP服務(wù)器通知高層的應(yīng)用進(jìn)程蜕琴,客戶端Client向服務(wù)器的方向就釋放了萍桌,這時候處于半關(guān)閉狀態(tài),即客戶端Client已經(jīng)沒有數(shù)據(jù)要發(fā)送了凌简,但是服務(wù)器Server若發(fā)送數(shù)據(jù)上炎,客戶端Client依然要接受。這個狀態(tài)還要持續(xù)一段時間雏搂,也就是整個CLOSE-WAIT狀態(tài)持續(xù)的時間藕施。
- 客戶端Client收到服務(wù)器Server的確認(rèn)信息后,此時凸郑,客戶端Client就進(jìn)入FIN-WAIT-2(終止等待2)狀態(tài)裳食,等待服務(wù)器Server發(fā)送連接釋放報文(在這之前還需要接受服務(wù)器Server發(fā)送的最后的數(shù)據(jù))。
- 服務(wù)器Server將最后的數(shù)據(jù)發(fā)送完畢后芙沥,就向客戶端發(fā)送連接釋放報文诲祸,F(xiàn)IN=1,ack=m+1憨愉,由于在半關(guān)閉狀態(tài)烦绳,服務(wù)器Server很可能又發(fā)送了一些數(shù)據(jù),假定此時的順序號為seq=p配紫,此時径密,服務(wù)器Server就進(jìn)入了LAST-ACK(最后確認(rèn))狀態(tài),等待客戶端Client的確認(rèn)躺孝。
- 客戶端Client收到服務(wù)器Server的連接釋放報文后享扔,必須發(fā)出確認(rèn),ACK=1植袍,ack=p+1惧眠,而自己的順序號是seq=m+1,此時于个,客戶端Client就進(jìn)入了TIME-WAIT(時間等待)狀態(tài)氛魁。注意此時TCP連接還沒有釋放,必須經(jīng)過2*MSL(最長報文段壽命)的時間后厅篓,當(dāng)客戶端Client撤銷相應(yīng)的TCB(保護(hù)程序)后秀存,才進(jìn)入CLOSED狀態(tài)。
- 服務(wù)器Server只要收到了客戶端Client發(fā)出的確認(rèn)羽氮,立即進(jìn)入CLOSED狀態(tài)或链。同樣,撤銷TCB后档押,就結(jié)束了這次的TCP連接澳盐∑泶浚可以看到,服務(wù)器Server結(jié)束TCP連接的時間要比客戶端Client早一些叼耙。
四腕窥、常見面試題
1.為什么連接的時候是三次握手,關(guān)閉的時候卻是四次握手旬蟋?
答:因?yàn)楫?dāng)客戶端發(fā)起關(guān)閉連接的請求時油昂,發(fā)出的FIN,僅代表客戶端沒有需要發(fā)送給服務(wù)器端的數(shù)據(jù)了倾贰。而如果服務(wù)器端如果仍有數(shù)據(jù)需要發(fā)送給客戶端的話,響應(yīng)報文ACK和結(jié)束報文FIN則就不能同時發(fā)送給客戶端了拦惋。此時匆浙,服務(wù)器端會先返回一個響應(yīng)報文,代表接收到了客戶端發(fā)出的FIN請求厕妖,而后在數(shù)據(jù)傳輸完了之后首尼,再發(fā)出FIN請求,表示服務(wù)器端已經(jīng)準(zhǔn)備好斷開連接了言秸。所以關(guān)閉連接的時候是四次握手软能。
2.為什么TIME_WAIT狀態(tài)需要經(jīng)過2MSL(最大報文段生存時間)才能返回到CLOSE狀態(tài)?
答:按照前面所說举畸,當(dāng)四個報文全部發(fā)送完畢后查排,理論上就算是結(jié)束了。但是實(shí)際情況往往不會那么可靠抄沮,比如最后一條報文發(fā)出后丟失了跋核,那么服務(wù)器端就不會接收到這一報文,每隔一段時間叛买,服務(wù)器端會再次發(fā)出FIN報文砂代,此時如果客戶端已經(jīng)斷開了,那么就無法響應(yīng)服務(wù)器的二次請求率挣,這樣服務(wù)器會繼續(xù)發(fā)出FIN報文刻伊,從而變成了死循環(huán)。所以需要設(shè)置一個時間段椒功,如果在這個時間段內(nèi)接收到了服務(wù)器端的再次請求捶箱,則代表客戶端發(fā)出的ACK報文沒有接收成功。反之蛾茉,則代表服務(wù)器端成功接收響應(yīng)報文讼呢,客戶端進(jìn)入CLOSED狀態(tài),此次連接成功關(guān)閉谦炬。而這個時間悦屏,就規(guī)定為了2MSL节沦,即客戶端發(fā)出ACK報文到服務(wù)器端的最大時間 + 服務(wù)器沒有接收到ACK報文再次發(fā)出FIN的最大時間 = 2MSL
3.為什么不能用兩次握手進(jìn)行連接?
答:三次握手有兩個重要的功能础爬,一是要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作且雙方都知道彼此已準(zhǔn)備好甫贯,二要允許雙方就初始順序號進(jìn)行協(xié)商,這個順序號在握手過程中被發(fā)送和確認(rèn)看蚜。如果改為了兩次握手叫搁,是有可能發(fā)生死鎖的。在兩次握手的設(shè)定下供炎,服務(wù)器端在成功接受客戶端的連接請求SYN后渴逻,向客戶端發(fā)出ACK確定報文時,如果因?yàn)榫W(wǎng)絡(luò)原因客戶端沒有接收到音诫,則會一直等待服務(wù)器端的ACK報文惨奕,而服務(wù)器端則認(rèn)為連接成功建立了,便開始向客戶端發(fā)送數(shù)據(jù)竭钝。但是客戶端因?yàn)闆]有收到服務(wù)器端的ACK報文梨撞,且不知道服務(wù)器的順序號seq,則會認(rèn)為連接未成功建立香罐,忽略服務(wù)器發(fā)出的任何數(shù)據(jù)卧波。如此客戶端一直等待服務(wù)器端的ACK報文,而服務(wù)器端因?yàn)榭蛻舳艘恢睕]有接收數(shù)據(jù)庇茫,而不斷地重復(fù)發(fā)送數(shù)據(jù)港粱,從而造成死鎖。
4.如果已經(jīng)建立了連接港令,但是客戶端突然出現(xiàn)故障了怎么辦啥容?
答:TCP還設(shè)有一個保活計時器顷霹,顯然咪惠,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去淋淀,白白浪費(fèi)資源遥昧。服務(wù)器每收到一次客戶端的請求后都會重新復(fù)位這個計時器,時間通常是設(shè)置為2小時朵纷,若兩小時還沒有收到客戶端的任何數(shù)據(jù)炭臭,服務(wù)器就會發(fā)送一個探測報文段,以后每隔75秒鐘發(fā)送一次袍辞。若一連發(fā)送10個探測報文仍然沒反應(yīng)鞋仍,服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接搅吁。