1. 程式人生 > >《深信服醒獅計劃網路基礎》學習筆記

《深信服醒獅計劃網路基礎》學習筆記

第一部分《網路基礎》

一、IP

1、IP資料報

這裡寫圖片描述
1)版本號:佔用4位二進位制數,表示該IP資料報使用的IP協議版本。目前Internet中使用的主要是TCP/IP協議族中版本號為4的IP協議。

2)頭長度:佔用4位二進位制位,此域指出整個報頭的長度(包括選項),該長度是以32位二進位制數為一個計數單位的,接收端通過此域可以計算出報頭在何處結束及從何處開始讀資料。普通IP資料報(沒有任何選項)該欄位的值是5(即20個位元組的長度)。

3)服務型別(TOS、type of service):佔用8位二進位制位,用於規定本資料報的處理方式。

4)總長度:佔用16位二進位制位,總長度欄位是指整個IP資料報的長度(報頭區+資料區),以位元組為單位。利用頭部長度欄位和總長度欄位就可以計算出IP資料報中資料內容的起始位置和長度。由於該欄位長度為16位二進位制數,因此理論上IP資料報最長可達65536個位元組(事實上受物理網路的限制,要比這個數值小很多)。

5)生存時間(TTL,time to live):佔用8位二進位制位,它指定了資料報可以在網路中傳輸的最長時間。實際應用中把生存時間欄位設定成了資料報可以經過的最大路由器數。TTL的初始值由源主機設定(通常為32、64、128或256),一旦經過一個處理它的路由器,它的值就減1。當該欄位為0時,資料報就丟棄,併發送ICMP報文通知源主機,因此可以防止進入一個迴圈迴路時,資料報無休止地傳輸下去。

6)上層協議標識(Protocol):佔用8位二進位制位,IP協議可以承載各種上層協議,目標端根據協議標識就可以把收到的IP資料報送到TCP或UDP等處理此報文的上層協議了。

7)校驗和:佔用16位二進位制數,用於協議頭資料有效性的校驗,可以保證IP報頭區在傳輸時的正確性和完整性。

8)源地址:佔用32位二進位制數,表示傳送端IP地址。

9)目的地址:佔用32位二進位制數,表述目的端IP地址。

2、最大傳輸單元(MTU)

1)MTU:鏈路層的特性決定了資料幀的最大長度。
2)分片:
場景:
同一個網路上的兩臺主機之間通訊時,該網路的MTU值是確定的,不存在分片問題。分片問題一般只存在於具有不同MTU值的網際網路中。
定義:
把一個數據報為了適合網路傳輸而分成多個數據報的過程稱為分片,被分片後的各個IP資料報可能經過不同的路徑到達目標主機。
3)標誌
這裡寫圖片描述
DF: 0=可以分片 1=不可以分片,出錯時傳送ICMP
MF: 0=最後一個分片 1=還有更多的分片在後面
4)片偏移
佔13位。片偏移指出:較長的分組在分片後,某片在原分組中的相對位置。也就是說,相對於使用者資料欄位的起點,該片
從何處開始。片偏移以8個位元組為偏移單位。也就是說,每個分片的長度一定是8位元組(64位)的整數倍。

3、IP分片攻擊

目標計算機在處理這些分片報文的時候,會把先到的分片報文快取起來,然後一直等待後續的分片報文,這個過程會消耗掉一部分記憶體,以及一些IP協議棧的資料結構。如果攻擊者給目標計算機只發送一片分片報文,而不傳送所有的分片報文,這樣攻擊者計算機便會一直等待(直到一個內部計時器到時),如果攻擊者傳送了大量的分片報文,就會消耗掉目標計算機的資源,而導致不能相應正常的IP報文,這也是一種DOS攻擊。

二、TCP

所提供的服務:程序到程序的通訊,基於位元組流的,面向連線的,全雙工的可靠的通訊服務

1、TCP頭部

這裡寫圖片描述

2、三次握手

這裡寫圖片描述
第一次握手:建立連線時,客戶端傳送syn包(syn=x)到伺服器,並進入SYN_SENT狀態,等待伺服器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。

第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也傳送一個SYN包(syn=y),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=y+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED(TCP連線成功)狀態,完成三次握手。

為什麼是三次握手?
一句話,主要防止已經失效的連線請求報文突然又傳送到了伺服器,從而產生錯誤。
如果使用的是兩次握手建立連線,假設有這樣一種場景,客戶端傳送了第一個請求連線並且沒有丟失,只是因為在網路結點中滯留的時間太長了,由於TCP的客戶端遲遲沒有收到確認報文,以為伺服器沒有收到,此時重新向伺服器傳送這條報文,此後客戶端和伺服器經過兩次握手完成連線,傳輸資料,然後關閉連線。此時此前滯留的那一次請求連線,網路通暢了到達了伺服器,這個報文字該是失效的,但是,兩次握手的機制將會讓客戶端和伺服器再次建立連線,這將導致不必要的錯誤和資源的浪費。
如果採用的是三次握手,就算是那一次失效的報文傳送過來了,服務端接受到了那條失效報文並且回覆了確認報文,但是客戶端不會再次發出確認。由於伺服器收不到確認,就知道客戶端並沒有請求連線。

3、四次揮手

這裡寫圖片描述
)1 為什麼TIME_WAIT狀態停留時間:2MSL?
第一,保證客戶端傳送的最後一個ACK報文能夠到達伺服器,因為這個ACK報文可能丟失,站在伺服器的角度看來,我已經發送了FIN+ACK報文請求斷開了,客戶端還沒有給我回應,應該是我傳送的請求斷開報文它沒有收到,於是伺服器又會重新發送一次,而客戶端就能在這個2MSL時間段內收到這個重傳的報文,接著給出迴應報文,並且會重啟2MSL計時器。

第二,防止類似與“三次握手”中提到了的“已經失效的連線請求報文段”出現在本連線中。客戶端傳送完最後一個確認報文後,在這個2MSL時間中,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失。這樣新的連線中不會出現舊連線的請求報文。

)2 為什麼建立連線是三次握手,關閉連線確是四次揮手呢?

建立連線的時候, 伺服器在LISTEN狀態下,收到建立連線請求的SYN報文後,把ACK和SYN放在一個報文裡傳送給客戶端。
而關閉連線時,伺服器收到對方的FIN報文時,僅僅表示對方不再發送資料了但是還能接收資料,而自己也未必全部資料都發送給對方了,所以己方可以立即關閉,也可以傳送一些資料給對方後,再發送FIN報文給對方來表示同意現在關閉連線,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。

4、TCP中的定時器

1)SYNACK定時器
TCP伺服器在收到SYN請求後傳送SYN|ACK響應,然後等待對端的ACK到來以完成三次握手。如果沒有收到ACK,TCP應該重傳SYN|ACK,這個功能由SYN-ACK定時器完成。
2)重傳定時器
為了控制丟失的報文段或丟棄的報文段,也就是對報文段確認的等待時間。當TCP傳送報文段時,就建立這個特定報文段的重傳計時器,可能發生兩種情況:若在計時器超時之前收到對報文段的確認,則撤銷計時器;若在收到對特定報文段的確認之前計時器超時,則重傳該報文,並把計時器復位。
3)保活計時器:keeplive timer
每當伺服器收到客戶的資訊,就將keeplive timer復位,超時通常設定2小時,若伺服器超過2小時還沒有收到來自客戶的資訊,就傳送探測報文段,若傳送了10個探測報文段(沒75秒傳送一個)還沒收到響應,則終止連線。
4)延遲ACK定時器
TCP延遲確認定時器是指在一個TCP連線中,當一方收到另一端的資料之後,並不是立馬返回ACK進行確認。而是等待200ms(在linux-2.6.38核心實現中應該是40ms),如果這段時間內有新的資料要發往對方,本地將ACK和資料封裝在一個數據包中一起傳送,稱作捎帶確認機制。超時後即使沒有新資料的話也要將ACK發給對方。
5)堅持計時器:persistent timer
專門為對付零視窗通知而設立的,解決ACK的丟失可能造成的死鎖問題。
6)TIME_WAIT定時器:2MSL

5、滑動視窗

1)功能:
1、保證資料的可靠傳遞:未確認的資料必須被髮送方快取起來
2、保證資料的有序傳輸:亂序的資料必須被接收方快取起來
3、提供End-to-End的流控機制:傳送方傳送太快就必須阻塞等待

TCP並不是每一個報文段都會回覆ACK的,可能會對兩個報文段傳送一個ACK,也可能會對多個報文段傳送1個ACK【累計ACK】,比如說傳送方有1/2/3 3個報文段,先發送了2,3 兩個報文段,但是接收方期望收到1報文段,這個時候2,3報文段就只能放在快取中等待報文1的空洞被填上,如果報文1,一直不來,報文2/3也將被丟棄,如果報文1來了,那麼會發送一個ACK對這3個報文進行一次確認。

一個例子來說明一下滑動視窗的原理:

  1. 假設32~45 這些資料,是上層Application傳送給TCP的,TCP將其分成四個Segment來發往internet

  2. seg1 32~34 seg3 35~36 seg3 37~41 seg4 42~45 這四個片段,依次傳送出去,此時假設接收端之接收到了seg1 seg2 seg4

  3. 此時接收端的行為是回覆一個ACK包說明已經接收到了32~36的資料,並將seg4進行快取(保證順序,產生一個儲存seg3 的hole)

  4. 傳送端收到ACK之後,就會將32~36的資料包從傳送並沒有確認切到傳送已經確認,提出視窗,這個時候視窗向右移動

  5. 假設接收端通告的Window Size仍然不變,此時視窗右移,產生一些新的空位,這些是接收端允許傳送的範疇

  6. 對於丟失的seg3,如果超過一定時間,TCP就會重新傳送(重傳機制),重傳成功會seg3 seg4一塊被確認,不成功,seg4也將被丟棄

就是不斷重複著上述的過程,隨著視窗不斷滑動,將真個資料流傳送到接收端,實際上接收端的Window Size通告也是會變化的,接收端根據這個值來確定何時及傳送多少資料,從對資料流進行流控。原理圖如下圖所示:
這裡寫圖片描述

2)症狀及改進演算法(Nagle演算法、Clark演算法)
症狀:
如果我們的應用程式一次產生1個位元組的資料,而這個1個位元組資料又以網路資料包的形式傳送到遠端伺服器,那麼就很容易導致網路由於太多的資料包而過載。比如,當用戶使用Telnet連線到遠端伺服器時,每一次擊鍵操作就會產生1個位元組資料,進而傳送出去一個數據包,所以,在典型情況下,傳送一個只擁有1個位元組有效資料的資料包,卻要發費40個位元組長包頭(即ip頭20位元組+tcp頭20位元組)的額外開銷,這種有效載荷(payload)利用率極其低下的情況被統稱之為愚蠢視窗症候群(Silly Window Syndrome)

Nagle演算法的改進在於(針對傳送端):如果傳送端欲多次傳送包含少量字元的資料包(一般情況下,後面統一稱長度小於MSS的資料包為小包,與此相對,稱長度等於MSS的資料包為大包,為了某些對比說明,還有中包,即長度比小包長,但又不足一個MSS的包),則傳送端會先將第一個小包傳送出去,而將後面到達的少量字元資料都快取起來而不立即傳送,直到收到接收端對前一個數據包報文段的ACK確認、或當前字元屬於緊急資料,或者積攢到了一定數量的資料(比如快取的字元資料已經達到資料包報文段的最大長度)等多種情況才將其組成一個較大的資料包傳送出去

Nagle演算法步驟:
1、傳送端把從應用層收到的第一個資料傳送出去。
2、傳送完第一個後,傳送端緩衝資料並等待,直到:a 收到上一次的確認 ;b 積累到MSS大小的資料。
3、重複步驟2。

Clark演算法(針對接收端)
Clark解決方法是隻要有資料到達就傳送確認,但宣佈的視窗大小為零,直到或者快取空間已能放入具有最大長度的報文段,或者快取空間的一半已經空了。

Nagle演算法與CORK演算法區別:
Nagle演算法的初衷:避免傳送大量的小包,防止小包氾濫於網路,理想情況下,對於一個TCP連線而言,網路上每次只能一個小包存在。它更多的是端到端意義上的優化。
CORK演算法的初衷:提高網路利用率,理想情況下,完全避免傳送小包,僅僅傳送滿包以及不得不發的小包。
Nagle演算法和CORK演算法著眼點不一樣,Nagle演算法主要避免網路因為太多的小包(協議頭的比例非常之大)而擁塞,而CORK演算法則是為了提高網路的利用率,使得總體上協議頭佔用的比例儘可能的小。

6、擁塞控制

為什麼需要擁塞控制?
1、流控只簡單地表明瞭接收方的處理能力,並不能代表中間網路的處理能力。
2、如果一開始把流控視窗內的資料全部發送出去。中間路由器可能一時處理不了如此多的突發流量
路由器處理不及時—>緩衝資料—>時延增大—>重傳資料—>導致更多的資料處理不及時。

1)擁塞視窗
門限值:
實際傳送視窗W=min(cwnd, rwnd)
如果接收方慢,W=rwnd
如果網路慢,那麼W=cwnd

2)慢啟動
慢啟動的演算法如下(cwnd全稱Congestion Window):

1)連線建好的開始先初始化cwnd = 1,表明可以傳一個MSS大小的資料。

2)每當收到一個ACK,cwnd++; 呈線性上升

3)每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升

4)還有一個ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免演算法”

3)擁塞避免
當cwnd >= ssthresh時,就會進入“擁塞避免演算法”。一般來說ssthresh的值是65535,單位是位元組,當cwnd達到這個值時後,演算法如下:

1)收到一個ACK時,cwnd = cwnd + 1/cwnd

2)當每過一個RTT時,cwnd = cwnd + 1

這樣就可以避免增長過快導致網路擁塞,慢慢的增加調整到網路的最佳值。很明顯,是一個線性上升的演算法。

這裡寫圖片描述

  • 乘法減小:無論在慢啟動階段還是在擁塞控制階段,只要網路出現超時,就是將cwnd置為1,ssthresh置為cwnd的一半,然後開始執行慢啟動演算法(cwnd < ssthresh)
  • 加法增大:當網路頻發出現超時情況時,ssthresh就下降的很快,為了減少注入到網路中的分組數,而加法增大是指執行擁塞避免演算法後,是擁塞視窗緩慢的增大,以防止網路過早出現擁塞。

4)快重傳
如果連續收到3個或以上的重複ACK,那麼很有可能是有資料包丟失了
當收到3個重複ACK時的措施:
1、ssthresh=min(cwnd/2, 2)
2、cwnd=ssthresh+3
3、如果再收到重複的ACK,cwnd+=1MSS
4、如果收到新資料的ACK,那麼cwnd=ssthresh,重新進入加法增大的過程

5)快恢復
1. 當傳送發連續接收到三個確認時,就執行乘法減小演算法,把慢啟動開始門限(ssthresh)減半,但是接下來並不執行慢開始演算法。
2. 此時不執行慢啟動演算法,而是把cwnd設定為ssthresh的一半, 然後執行擁塞避免演算法,使擁塞視窗緩慢增大。
這裡寫圖片描述
6)BIC演算法
思想:二分搜尋
演算法步驟:
1、如果發生丟包的時候,視窗的大小是W1,那麼要保持線路滿載卻不丟包,實際的視窗最大值應該在W1以下;
2、如果檢測到發生丟包,並且已經將視窗乘性減到了W2,那麼實際的視窗值應該在W2以上。
因此,在TCP快速恢復階段過去之後,便開始在W2~W1這個區間內進行二分搜尋,尋找視窗的實際最大值。於是定義W1為Wmax,定義W2為Wmin。每收到一個ACK的時候,便將視窗設定到Wmax和Wmin的中點,一直持續到接近Wmax。
3、當超過wmax之後,進入新的wmax探測過程。 超越Wmax之後,如何找到新的Wmax呢?也非常簡單!既然度過了Wmax都沒有丟包,說明新的Wmax還沒有達到,此時BIC採取了一種非常簡單直接的方法:按照逼近Wmax的路徑倒回去,即採用與之對稱的方案。
7)CUBIC演算法
這裡寫圖片描述
beta決定了整個曲線對稱範圍圍成區域的高度,而k則控制了從起始視窗到達丟包視窗的時間,由於k與C成反比,那麼C越大,則探測到最大視窗的時間越短,反之則越久。

三、UDP

這裡寫圖片描述
特徵:
提供給應用傳送不可靠報文的選項,通常用於多播
無需連線的概念,提供快速的資料傳送
沒有流控和擁塞控制
應用:
TFTP、SNMP、DHCP、DNS、RIP、RTP

第二部分《tcpdump的使用》

一、基本命令

-i 引數指定監聽網口
-c 引數指定監聽的資料包數量
-s 引數指定監聽資料包大小
-w 引數指定監聽資料包寫入檔案
-n:對地址以數字方式顯式,否則顯式為主機名,也就是說-n選項不做主機名解析。
-nn:除了-n的作用外,還把埠顯示為數值,否則顯示埠服務名。
-X:輸出包的頭部資料,會以16進位制和ASCII兩種方式同時輸出。
-XX:輸出包的頭部資料,會以16進位制和ASCII兩種方式同時輸出,更詳細。
-v:當分析和列印的時候,產生詳細的輸出。
-vv:產生比-v更詳細的輸出。
-vvv:產生比-vv更詳細的輸出。

tcpdump 支援的表示式:

否 : ! 或 not
與 : && 或 and
或 : || 或 or

協議 header 過濾規則:

proto[x:y] : 從第 x 個位置開始取 y 位元組, ip[2:2] 表示取 IP 首部中的第 3,4 位元組(x 從 0 開始計算);
proto[x:y] & z = 0 : proto[x:y] 的結果和 z 進行 與 運算, 匹配最終結果為 0的報文;
操作符包括: >, <, >=, <=, =, !=

UDP 過濾規則:

udp[0:2] source port
udp[2:2] destination port
udp[4:2] datagram length
udp[6:2] UDP checksum

1、如果要監聽某幾臺主機資料包 例如10.10.10.10、20.20.20.20、30.30.30.30

tcpdump host 10.10.10.10 and \(20.20.20.20 or 30.30.30.30\)

2、如果想要獲取主機210.27.48.1除了和主機210.27.48.2之外所有主機通訊的ip包

tcpdump ip host 210.27.48.1 and ! 210.27.48.2

3、如果獲取10.10.10.10:80發出去的資料包

tcpdump -i eth0 src host 10.10.10.10 and src port 80

4、如果獲取發往10.10.10.10:80的資料包

tcpdump -i eth0 dst host 10.10.10.10 and dst port 80

5、只抓取syn包

tcpdump -i eth0 tcp[13]==2

6、只抓取fin包

tcpdump -i eth2 tcp[13]==1

7、只抓取synack包

tcpdump -i eth2 tcp[13]==18

8、抓取10.10.10.10:80的syn、synack包

tcpdump -i eth2 tcp[13]==2 or tcp[13]==18 and port 80 and host 10.10.10.10

二、抓包實踐

實踐內容:ping百度域名,將百度作為遠端伺服器,模擬實踐過程如下
第一步:

ping www.baidu.com

第二步:拿到遠端伺服器IP
這裡寫圖片描述
即:112.80.248.73
第三步:開啟另一個終端,輸入:

 sudo tcpdump -S host 49.123.79.83 and 112.80.248.73 //49.123.79.83是本地IP,即:客戶端IP

結果如下:
這裡寫圖片描述