前言
TCP/IP(Transmission Control Protocol/Internet Protocol) 是能夠在多個(gè)不同網(wǎng)絡(luò)間實(shí)現(xiàn)信息傳輸?shù)膮f(xié)議簇。
TCP(傳輸控制協(xié)議)
- TCP 用于從應(yīng)用程序到網(wǎng)絡(luò)的數(shù)據(jù)傳輸控制。
- TCP 負(fù)責(zé)在數(shù)據(jù)傳送之前將它們分割為 IP 包,然后在它們到達(dá)的時(shí)候?qū)⑺鼈冎亟M。
IP(網(wǎng)際協(xié)議)
- IP 負(fù)責(zé)計(jì)算機(jī)之間的通信。
- IP 負(fù)責(zé)在因特網(wǎng)上發(fā)送和接收數(shù)據(jù)包
TCP 報(bào)文

- 16位源端口號(hào):16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是標(biāo)識(shí)報(bào)文的返回地址
- 16位目的端口號(hào):16位的目的端口域定義傳輸?shù)哪康摹?strong>這個(gè)端口指明報(bào)文接收計(jì)算機(jī)上的應(yīng)用程序地址接口
- 32位序號(hào):32位的序列號(hào)由接收端計(jì)算機(jī)使用,重新分段的報(bào)文成最初形式。當(dāng)SYN出現(xiàn),序列碼實(shí)際上是初始序列碼(Initial Sequence Number,ISN),而第一個(gè)數(shù)據(jù)字節(jié)是ISN+1。這個(gè)序列號(hào)(序列碼)可用來(lái)補(bǔ)償傳輸中的不一致。
- 32位確認(rèn)序號(hào):32位的序列號(hào)由接收端計(jì)算機(jī)使用,重組分段的報(bào)文成最初形式。如果設(shè)置了ACK控制位,這個(gè)值表示一個(gè)準(zhǔn)備接收的包的序列碼
- 4位首部長(zhǎng)度:4位包括TCP頭大小,指示何處數(shù)據(jù)開(kāi)始
- 保留(6位):6位值域,這些位必須是0。為了將來(lái)定義新的用途而保留
-
標(biāo)志:6位標(biāo)志域
- URG:緊急指針(urgent pointer)有效
- ACK:確認(rèn)序號(hào)有效
- PSH:接收方應(yīng)該盡快將這個(gè)報(bào)文交給應(yīng)用層
- RST:重置連接
- SYN:發(fā)起一個(gè)新連接
- FIN:釋放一個(gè)連接
- 16位窗口大小:用來(lái)表示想收到的每個(gè)TCP數(shù)據(jù)段的大小。TCP的流量控制由連接的每一端通過(guò)聲明的窗口大小來(lái)提供。窗口大小為字節(jié)數(shù),起始于確認(rèn)序號(hào)字段指明的值,這個(gè)值是接收端正期望接收的字節(jié)。窗口大小是一個(gè)16字節(jié)字段,因而窗口大小最大為65535字節(jié)
- 16位校驗(yàn)和:16位TCP頭。源機(jī)器基于數(shù)據(jù)內(nèi)容計(jì)算一個(gè)數(shù)值,收信息機(jī)要與源機(jī)器數(shù)值 結(jié)果完全一樣,從而證明數(shù)據(jù)的有效性。檢驗(yàn)和覆蓋了整個(gè)的TCP報(bào)文段:這是一個(gè)強(qiáng)制性的字段,一定是由發(fā)送端計(jì)算和存儲(chǔ),并由接收端進(jìn)行驗(yàn)證的
- 16位緊急指針:指向后面是優(yōu)先數(shù)據(jù)的字節(jié),在URG標(biāo)志設(shè)置了時(shí)才有效。如果URG標(biāo)志沒(méi)有被設(shè)置,緊急域作為填充。加快處理標(biāo)示為緊急的數(shù)據(jù)段
- 選項(xiàng):長(zhǎng)度不定,但長(zhǎng)度必須為1個(gè)字節(jié)。如果沒(méi)有選項(xiàng)就表示這個(gè)1字節(jié)的域等于0
- 數(shù)據(jù):該TCP協(xié)議包負(fù)載的數(shù)據(jù)
三次握手
建立一個(gè)TCP連接時(shí),需要客戶端和服務(wù)端總共發(fā)送3個(gè)包以確認(rèn)連接的建立。
進(jìn)行三次握手的主要作用就是為了:確認(rèn)雙方的接收能力和發(fā)送能力是否正常、指定自己的初始化序列號(hào)為后面的可靠性傳送做準(zhǔn)備。
三次握手流程

- 第一次握手:Client將標(biāo)志位SYN置為1,隨機(jī)產(chǎn)生一個(gè)值seq=X,并將該數(shù)據(jù)包發(fā)送給Server,Client進(jìn)入SYN_SENT狀態(tài),等待Server確認(rèn)

- 第二次握手:server收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道Client請(qǐng)求建立連接,Server將標(biāo)志位SYN和ACK都置為1,ack=X+1,隨機(jī)產(chǎn)生一個(gè)值seq=Y,并將該數(shù)據(jù)包發(fā)送給Client以確認(rèn)連接請(qǐng)求,Server進(jìn)入SYN_RCVD狀態(tài)

- 第三次握手:Client收到確認(rèn)后,檢查ack是否為Y+1,ACK是否為1,如果正確則將標(biāo)志位ACK置為1,ack=Y+1,并將該數(shù)據(jù)包發(fā)送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連接建立成功,Client和Server進(jìn)入ESTABLISHED狀態(tài),完成三次握手

1. 為什么需要三次握手?
需要三次握手才能確認(rèn)雙方的接收與發(fā)送能力是否正常。
2. 半連接隊(duì)列
服務(wù)器第一次收到客戶端的 SYN 之后,就會(huì)處于 SYN_RCVD 狀態(tài),此時(shí)雙方還沒(méi)有完全建立其連接,服務(wù)器會(huì)把此種狀態(tài)下請(qǐng)求連接放在一個(gè)隊(duì)列里,稱之為半連接隊(duì)列。
3. ISN(Initial Sequence Number)是固定的嗎?
ISN 是動(dòng)態(tài)生成的:三次握手的其中一個(gè)重要功能是客戶端和服務(wù)端交換 ISN(Initial Sequence Number),以便讓對(duì)方知道接下來(lái)接收數(shù)據(jù)的時(shí)候如何按序列號(hào)組裝數(shù)據(jù)。如果 ISN 是固定的,攻擊者很容易猜出后續(xù)的確認(rèn)號(hào)。
4. 三次握手過(guò)程中可以攜帶數(shù)據(jù)嗎?
第一次、第二次握手不可以攜帶數(shù)據(jù),第三次可以。
5. SYN攻擊
服務(wù)器端的資源分配是在二次握手時(shí)分配的,而客戶端的資源是在完成三次握手時(shí)分配的。
SYN攻擊:Client在短時(shí)間內(nèi)偽造大量不存在的IP地址,并向Server不斷地發(fā)送SYN包,Server則回復(fù)確認(rèn)包,并等待Client確認(rèn),由于源地址不存在,因此Server需要不斷重發(fā)直至超時(shí),這些偽造的SYN包將長(zhǎng)時(shí)間占用未連接隊(duì)列,導(dǎo)致正常的SYN請(qǐng)求因?yàn)殛?duì)列滿而被丟棄,從而引起網(wǎng)絡(luò)擁塞甚至系統(tǒng)癱瘓。SYN 攻擊是一種典型的 DoS/DDoS 攻擊。
防御
- 縮短超時(shí)(SYN Timeout)時(shí)間
- 增加最大半連接數(shù)
- 過(guò)濾網(wǎng)關(guān)防護(hù)
- SYN cookies技術(shù)
四次揮手
斷開(kāi)一個(gè)TCP連接時(shí),需要客戶端和服務(wù)端總共發(fā)送4個(gè)包以確認(rèn)連接的斷開(kāi)。
這是因?yàn)橛蒚CP的半關(guān)閉(half-close)造成的:TCP提供了連接的一端在結(jié)束它的發(fā)送后還能接收來(lái)自另一端數(shù)據(jù)的能力。
四次揮手流程

- 第一次揮手:Client發(fā)送連接釋放報(bào)文(FIN=1,序號(hào)seq=u),并停止再發(fā)送數(shù)據(jù),Client進(jìn)入FIN_WAIT狀態(tài),等待服務(wù)端的確認(rèn)
- 第二次揮手:Server收到連接釋放報(bào)文后,發(fā)出確認(rèn)報(bào)文段(ACK=1,確認(rèn)號(hào)ack=u+1,序號(hào)seq=v),Server進(jìn)入CLOSE_WAIT狀態(tài),此時(shí)的TCP處于半關(guān)閉狀態(tài)
- 第三次揮手:Server端傳輸完數(shù)據(jù)或者要斷開(kāi)連接,Server發(fā)送連接釋放報(bào)文(FIN=1,ACK=1,確認(rèn)號(hào)ack=u+1,序號(hào)seq=w),Server進(jìn)入LAST_ACK狀態(tài),等待客戶端的確認(rèn)
- 第四次揮手:Client收到釋放報(bào)文后,發(fā)出確認(rèn)報(bào)文段(ACK=1,seq=u+1,ack=w+1),Client進(jìn)入TIME_WAIT狀態(tài),此時(shí)TCP未釋放掉,需要經(jīng)過(guò)時(shí)間等待計(jì)時(shí)器設(shè)置的時(shí)間2MSL后,客戶端才進(jìn)入CLOSED狀態(tài)
1. 揮手為什么需要四次?
因?yàn)門(mén)CP的半關(guān)閉,客戶端節(jié)數(shù)發(fā)送后仍然可以接受數(shù)據(jù),確保服務(wù)端的數(shù)據(jù)完全傳輸完成。
2. 四次揮手釋放連接時(shí),等待2MSL的意義
MSL是Maximum Segment Lifetime的英文縮寫(xiě),可譯為“最長(zhǎng)報(bào)文段壽命”,它是任何報(bào)文在網(wǎng)絡(luò)上存在的最長(zhǎng)時(shí)間,超過(guò)這個(gè)時(shí)間報(bào)文將被丟棄。
為了保證客戶端發(fā)送的最后一個(gè)ACK報(bào)文段能夠到達(dá)服務(wù)器。
SYN 相當(dāng)于是詢問(wèn),ACK 相當(dāng)于是確認(rèn)