免費網(wǎng)站建設(shè)哪個好 - 百度百度新聞排行榜
SYN 攻擊方式最直接的表現(xiàn)就會把 TCP 半連接隊列打滿,這樣當(dāng) TCP 半連接隊列滿了,后續(xù)再在收到 SYN 報文就會丟棄,導(dǎo)致客戶端無法和服務(wù)端建立連接。
避免 SYN 攻擊方式,可以有以下四種方法:
- 調(diào)大 netdev_max_backlog;
- 增大 TCP 半連接隊列;
- 開啟 tcp_syncookies;
- 減少 SYN+ACK 重傳次數(shù)
?方式一:調(diào)大 netdev_max_backlog
當(dāng)網(wǎng)卡接收數(shù)據(jù)包的速度大于內(nèi)核處理的速度時,會有一個隊列保存這些數(shù)據(jù)包??刂圃撽犃械淖畲笾等缦聟?shù),默認(rèn)值是 1000,我們要適當(dāng)調(diào)大該參數(shù)的值,比如設(shè)置為 10000?
方式二:增大 TCP 半連接隊列
增大 TCP 半連接隊列,要同時增大下面這三個參數(shù):
- 增大 net.ipv4.tcp_max_syn_backlog
- 增大 listen() 函數(shù)中的 backlog
- 增大 net.core.somaxconn
具體為什么是三個參數(shù)決定 TCP 半連接隊列的大小,可以看這篇:可以看這篇:TCP 半連接隊列和全連接隊列滿了會發(fā)生什么?又該如何應(yīng)對?
方式三:開啟 net.ipv4.tcp_syncookies
開啟 syncookies 功能就可以在不使用 SYN 半連接隊列的情況下成功建立連接,相當(dāng)于繞過了 SYN 半連接來建立連接。
具體過程:
- 當(dāng) 「 SYN 隊列」?jié)M之后,后續(xù)服務(wù)端收到 SYN 包,不會丟棄,而是根據(jù)算法,計算出一個?
cookie
?值;- 將 cookie 值放到第二次握手報文的「序列號」里,然后服務(wù)端回第二次握手給客戶端;
- 服務(wù)端接收到客戶端的應(yīng)答報文時,服務(wù)端會檢查這個 ACK 包的合法性。如果合法,將該連接對象放入到「 Accept 隊列」。
- 最后應(yīng)用程序通過調(diào)用?
accpet()
?接口,從「 Accept 隊列」取出的連接。可以看到,當(dāng)開啟了 tcp_syncookies 了,即使受到 SYN 攻擊而導(dǎo)致 SYN 隊列滿時,也能保證正常的連接成功建立。
net.ipv4.tcp_syncookies 參數(shù)主要有以下三個值:
- 0 值,表示關(guān)閉該功能;
- 1 值,表示僅當(dāng) SYN 半連接隊列放不下時,再啟用它;
- 2 值,表示無條件開啟功能;
那么在應(yīng)對 SYN 攻擊時,只需要設(shè)置為 1 即可。
?
?
方式四:減少 SYN+ACK 重傳次數(shù)
當(dāng)服務(wù)端受到 SYN 攻擊時,就會有大量處于 SYN_REVC 狀態(tài)的 TCP 連接,處于這個狀態(tài)的 TCP 會重傳 SYN+ACK ,當(dāng)重傳超過次數(shù)達到上限后,就會斷開連接。
那么針對 SYN 攻擊的場景,我們可以減少 SYN-ACK 的重傳次數(shù),以加快處于 SYN_REVC 狀態(tài)的 TCP 連接斷開。
SYN-ACK 報文的最大重傳次數(shù)由?tcp_synack_retries
內(nèi)核參數(shù)決定(默認(rèn)值是 5 次),比如將 tcp_synack_retries 減少到 2 次:
?
為什么揮手需要四次?
再來回顧下四次揮手雙方發(fā)?FIN
?包的過程,就能理解為什么需要四次了。
- 關(guān)閉連接時,客戶端向服務(wù)端發(fā)送?
FIN
?時,僅僅表示客戶端不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)。 - 服務(wù)端收到客戶端的?
FIN
?報文時,先回一個?ACK
?應(yīng)答報文,而服務(wù)端可能還有數(shù)據(jù)需要處理和發(fā)送,等服務(wù)端不再發(fā)送數(shù)據(jù)時,才發(fā)送?FIN
?報文給客戶端來表示同意現(xiàn)在關(guān)閉連接。 - 從上面過程可知,服務(wù)端通常需要等待完成數(shù)據(jù)的發(fā)送和處理,所以服務(wù)端的?
ACK
?和?FIN
?一般都會分開發(fā)送,因此是需要四次揮手。 - 4.1 TCP 三次握手與四次揮手面試題 | 小林coding
#第二次揮手丟失了,會發(fā)生什么?
當(dāng)服務(wù)端收到客戶端的第一次揮手后,就會先回一個 ACK 確認(rèn)報文,此時服務(wù)端的連接進入到?CLOSE_WAIT
?狀態(tài)。
在前面我們也提了,ACK 報文是不會重傳的,所以如果服務(wù)端的第二次揮手丟失了,客戶端就會觸發(fā)超時重傳機制,重傳 FIN 報文,直到收到服務(wù)端的第二次揮手,或者達到最大的重傳次數(shù)。
舉個例子,假設(shè) tcp_orphan_retries 參數(shù)值為 2,當(dāng)?shù)诙螕]手一直丟失時,發(fā)生的過程如下圖:
?
對于 close 函數(shù)關(guān)閉的連接,由于無法再發(fā)送和接收數(shù)據(jù),所以FIN_WAIT2
?狀態(tài)不可以持續(xù)太久,而?tcp_fin_timeout
?控制了這個狀態(tài)下連接的持續(xù)時長,默認(rèn)值是 60 秒。?
但是注意,如果主動關(guān)閉方使用 shutdown 函數(shù)關(guān)閉連接,指定了只關(guān)閉發(fā)送方向,而接收方向并沒有關(guān)閉,那么意味著主動關(guān)閉方還是可以接收數(shù)據(jù)的。
如果主動關(guān)閉方一直沒收到第三次揮手,那么主動關(guān)閉方的連接將會一直處于?FIN_WAIT2
?狀態(tài)(tcp_fin_timeout
?無法控制 shutdown 關(guān)閉的連接)。如下圖:
?