計算機網路學得不好,首先先放個OSI七層網絡模型吧
在協議的控制下,上層對下層進行調用,下層對上層進行服務, 上下層間用交換原語交換信息。這樣可以提高傳輸速率,並且保證數據安全,所以說其實每一層都有存在的必要
但是現在互聯網上大家都有TCP/IP協議,可以說是某種黑話,他封裝了前三層
每一層也有不同的協議
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協議發送時,用sendto函數最大能發送數據的長度為:65535- IP頭(20) - UDP頭(8)=65507字節。用sendto函數發送數據時,如果發送數據長度大於該值,則函數會返回錯誤。
用TCP協議發送時,由於TCP是數據流協議,因此不存在包大小的限制(暫不考慮緩沖區的大小),這是指在用send函數時,數據長度參數不受限制。而實際上,所指定的這段數據並不一定會一次性發送出去,如果這段數據比較長,會被分段發送,如果比較短,可能會等待和下一次數據一起發送。
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。