TCP/IP協議學習


計算機網路學得不好,首先先放個OSI七層網絡模型吧

在協議的控制下,上層對下層進行調用,下層對上層進行服務, 上下層間用交換原語交換信息。這樣可以提高傳輸速率,並且保證數據安全,所以說其實每一層都有存在的必要

但是現在互聯網上大家都有TCP/IP協議,可以說是某種黑話,他封裝了前三層

每一層也有不同的協議

 

在網絡通信的過程中,將發出數據的主機稱為源主機,接收數據的主機稱為目的主機。當源主機發出數據時,數據在源主機中從上層向下層傳送。源主機中的應用進程先將數據交給應用層,應用層加上必要的控制信息就成了報文流,向下傳給傳輸層。傳輸層將收到的數據單元加上本層的控制信息,形成報文段、數據報,再交給網際層。網際層加上本層的控制信息,形成IP數據報,傳給網絡接口層。網絡接口層將網際層交下來的IP數據報組裝成幀,並以比特流的形式傳給網絡硬件(即物理層),數據就離開源主機。
通過網絡傳輸,數據到達目的主機后,按照與源主機相反的過程,在目的主機中從下層向上層進行拆包傳送。首先由網絡接口層接收數據,依次剝離原來加上的控制信息,最后將源主機中的應用進程發送的數據交給目的主機的應用進程。
TCP/IP協議的基本傳輸單位是數據報(Datagram),TCP協議負責把數據分成若干個數據報,並給每個數據報加上報頭,報頭上有編號,以保證目的主機能將數據還原為原來的格式。IP協議在每個報頭上再加上接收端主機IP地址,這樣數據能找到自己要去的地方。如果傳輸過程中出現數據失真、數據丟失等情況,TCP協議會自動請求重新傳輸數據,並重組數據報。可以說,IP協議保證數據的傳輸,TCP協議保證數據傳輸的質量。
TCP/IP協議數據在傳輸時每通過一層就要在數據上加個報頭,其中的數據供接收端同一層協議使用,而在接收端,每經過一層要把用過的報頭去掉,這樣可以保證傳輸數據的一致性。
 
UDP 包的大小就應該是 1500 - IP頭(20) - UDP頭(8) = 1472(Bytes)
TCP 包的大小就應該是 1500 - IP頭(20) - TCP頭(20) = 1460 (Bytes)

 

標志位字段(U、A、P、R、S、F):占6比特。各比特的含義如下:  

URG:緊急指針(urgent pointer)有效。

ACK:確認序號有效。

PSH:接收方應該盡快將這個報文段交給應用層。

RST:重建連接。

SYN:發起一個連接。

FIN:釋放一個連接。

 

窗口大小字段:占16比特。此字段用來進行流量控制。單位為字節數,這個值是本機期望一次接收的字節數。

TCP校驗和字段:占16比特。對整個TCP報文段,即TCP頭部和TCP數據進行校驗和計算,並由目標端進行驗證。

緊急指針字段:占16比特。它是一個偏移量,和序號字段中的值相加表示緊急數據最后一個字節的序號。

選項字段:占32比特。可能包括"窗口擴大因子"、"時間戳"等選項。

 
 
 
在用UDP局域網通信時,經常發生“Hello World”來進行測試,但是“Hello World”並不滿足最小有效數據(64-46)的要求,為什么小於18個字節,對方仍然可用收到呢?因為在鏈路層的MAC子層中會進行數據補齊,不足18個字節的用0補齊。但當服務器在公網,客戶端在內網,發生小於18個字節的數據,就會出現接收端收不到數據的情況。
 

用UDP協議發送時,用sendto函數最大能發送數據的長度為:65535- IP頭(20) - UDP頭(8)=65507字節。用sendto函數發送數據時,如果發送數據長度大於該值,則函數會返回錯誤。  

用TCP協議發送時,由於TCP是數據流協議,因此不存在包大小的限制(暫不考慮緩沖區的大小),這是指在用send函數時,數據長度參數不受限制。而實際上,所指定的這段數據並不一定會一次性發送出去,如果這段數據比較長,會被分段發送,如果比較短,可能會等待和下一次數據一起發送。

 
RPC(Remote Procedure Call)—遠程過程調用,它是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分布式多程序在內的應用程序更加容易。
 

ISN

三次握手的一個重要功能是客戶端和服務端交換ISN(Initial Sequence Number), 以便讓對方知道接下來接收數據的時候如何按序列號組裝數據。

如果ISN是固定的,攻擊者很容易猜出后續的確認號。

ISN = M + F(localhost, localport, remotehost, remoteport)

M是一個計時器,每隔4毫秒加1。 F是一個Hash算法,根據源IP、目的IP、源端口、目的端口生成一個隨機數值。要保證hash算法不能被外部輕易推算得出。

其實3次握手的目的並不只是讓通信雙方都了解到一個連接正在建立,還在於利用數據包的選項來傳輸特殊的信息,交換初始序列號ISN。

3次握手是指發送了3個報文段,4次揮手是指發送了4個報文段。注意,SYN和FIN段都是會利用重傳進行可靠傳輸的。

 

序列號回繞

因為ISN是隨機的,所以序列號容易就會超過2^31-1. 而tcp對於丟包和亂序等問題的判斷都是依賴於序列號大小比較的。此時就出現了所謂的tcp序列號回繞(sequence wraparound)問題。怎么解決?

/* * The next routines deal with comparing 32 bit unsigned ints * and worry about wraparound (automatic with unsigned arithmetic). */ static inline int before(__u32 seq1, __u32 seq2) { return (__s32)(seq1-seq2) < 0; } #define after(seq2, seq1) before(seq1, seq2)

上述代碼是內核中的解決回繞問題代碼。s32是有符號整型的意思,而u32則是無符號整型。序列號發生回繞后,序列號變小,相減之后,把結果變成有符號數了,因此結果成了負數。

假設seq1=255, seq2=1(發生了回繞)。
seq1 = 1111 1111 seq2 = 0000 0001
我們希望比較結果是
 seq1 - seq2=
 1111 1111
-0000 0001
-----------
 1111 1110

由於我們將結果轉化成了有符號數,由於最高位是1,因此結果是一個負數,負數的絕對值為
 0000 0001 + 1 = 0000 0010 = 2

因此seq1 - seq2 < 0

syn flood攻擊

最基本的DoS攻擊就是利用合理的服務請求來占用過多的服務資源,從而使合法用戶無法得到服務的響應。syn flood屬於Dos攻擊的一種。

如果惡意的向某個服務器端口發送大量的SYN包,則可以使服務器打開大量的半開連接,分配TCB(Transmission Control Block), 從而消耗大量的服務器資源,同時也使得正常的連接請求無法被相應。當開放了一個TCP端口后,該端口就處於Listening狀態,不停地監視發到該端口的Syn報文,一 旦接收到Client發來的Syn報文,就需要為該請求分配一個TCB,通常一個TCB至少需要280個字節,在某些操作系統中TCB甚至需要1300個字節,並返回一個SYN ACK命令,立即轉為SYN-RECEIVED即半開連接狀態。系統會為此耗盡資源。

常見的防攻擊方法有:

無效連接的監視釋放

監視系統的半開連接和不活動連接,當達到一定閾值時拆除這些連接,從而釋放系統資源。這種方法對於所有的連接一視同仁,而且由於SYN Flood造成的半開連接數量很大,正常連接請求也被淹沒在其中被這種方式誤釋放掉,因此這種方法屬於入門級的SYN Flood方法。

延緩TCB分配方法

消耗服務器資源主要是因為當SYN數據報文一到達,系統立即分配TCB,從而占用了資源。而SYN Flood由於很難建立起正常連接,因此,當正常連接建立起來后再分配TCB則可以有效地減輕服務器資源的消耗。常見的方法是使用Syn Cache和Syn Cookie技術。

Syn Cache技術

系統在收到一個SYN報文時,在一個專用HASH表中保存這種半連接信息,直到收到正確的回應ACK報文再分配TCB。這個開銷遠小於TCB的開銷。當然還需要保存序列號。

Syn Cookie技術

Syn Cookie技術則完全不使用任何存儲資源,這種方法比較巧妙,它使用一種特殊的算法生成Sequence Number,這種算法考慮到了對方的IP、端口、己方IP、端口的固定信息,以及對方無法知道而己方比較固定的一些信息,如MSS(Maximum Segment Size,最大報文段大小,指的是TCP報文的最大數據報長度,其中不包括TCP首部長度。)、時間等,在收到對方 的ACK報文后,重新計算一遍,看其是否與對方回應報文中的(Sequence Number-1)相同,從而決定是否分配TCB資源。

使用SYN Proxy防火牆

一種方式是防止牆dqywb連接的有效性后,防火牆才會向內部服務器發起SYN請求。防火牆代服務器發出的SYN ACK包使用的序列號為c, 而真正的服務器回應的序列號為c', 這樣,在每個數據報文經過防火牆的時候進行序列號的修改。另一種方式是防火牆確定了連接的安全后,會發出一個safe reset命令,client會進行重新連接,這時出現的syn報文會直接放行。這樣不需要修改序列號了。但是,client需要發起兩次握手過程,因此建立連接的時間將會延長。

 

看到有人說,只看到過TCP狀態位為 ’FIN +ACK’,但從來沒有看過狀態位只有 ‘FIN’,你應該怎樣給他解釋?

RFC793明確規定,除了第一個握手報文SYN除外,其它所有報文必須將ACK = 1。

 

滑動窗口功能:確認、 差錯控制流量控制

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM