網頁設計

當前位置 /首頁/設計製作/網頁設計/列表

TCP洪水攻擊SYN Flood的診斷和處理

SYN Flood是當前最流行的DoS(拒絕服務攻擊)與DDoS(分散式拒絕服務攻擊)的方式之一,這是一種利用TCP協議缺陷,傳送大量偽造的TCP連線請求,常用假冒的IP或IP號段發來海量的請求連線的第一個握手包(SYN包),被攻擊伺服器迴應第二個握手包(SYN+ACK包),因為對方是假冒IP,對方永遠收不到包且不會迴應第三個握手包。導致被攻擊伺服器保持大量SYN_RECV狀態的“半連線”,並且會重試預設5次迴應第二個握手包,塞滿TCP等待連線佇列,資源耗盡(CPU滿負荷或記憶體不足),讓正常的業務請求連線不進來。關於TCP洪水攻擊SYN Flood詳細的原理,網上有很多介紹,應對辦法也很多,但大部分沒什麼效果,這裡介紹我們是如何診斷和應對的。

TCP洪水攻擊SYN Flood的診斷和處理

  診斷

我們看到業務曲線大跌時,檢查機器和DNS,發現只是對外的web機響應慢、CPU負載高、ssh登陸慢甚至有些機器登陸不上,檢查系統syslog:

# tail -f /var/log/messages

Apr 18 11:21:56 web5 kernel: possible SYN flooding on port 80. Sending cookies.

檢查連線數增多,並且SYN_RECV 連線特別多:

# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

TIME_WAIT 16855

CLOSE_WAIT 21

SYN_SENT 99

FIN_WAIT1 229

FIN_WAIT2 113

ESTABLISHED 8358

SYN_RECV 48965

CLOSING 3

LAST_ACK 313

根據經驗,正常時檢查連線數如下:

# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

TIME_WAIT 42349

CLOSE_WAIT 1

SYN_SENT 4

FIN_WAIT1 298

FIN_WAIT2 33

ESTABLISHED 12775

SYN_RECV 259

CLOSING 6

LAST_ACK 432

以上就是TCP洪水攻擊的兩大特徵。執行netstat -na>指定檔案,保留罪證。

  應急處理

根據netstat檢視到的對方IP特徵:

# netstat -na |grep SYN_RECV|more

利用iptables臨時封掉最大嫌疑攻擊的IP或IP號段,例如對方假冒173.*.*.*號段來攻擊,短期禁用173.*.*.*這個大號段(要確認小心不要封掉自己的本地IP了!)

# iptables -A INPUT -s -p tcp –dport 80 -j DROP

再分析剛才保留的罪證,分析業務,用iptables解封正常173.*.*.*號段內正常的ip和子網段。這樣應急處理很容易誤傷,甚至可能因為封錯了導致ssh登陸不了伺服器,並不是理想方式。

使用F5擋攻擊

應急處理畢竟太被動,因為本機房的F5比較空閒,運維利用F5來擋攻擊,採用方式:讓客戶端先和F5三次握手,連線建立之後F5才轉發到後端業務伺服器。後來被攻擊時F5上看到的現象:

?

1、連線數比平時多了500萬,攻擊停止後恢復。

2、修改F5上我們業務的VS模式後,F5的消耗比平時多7%,攻擊停止後恢復。

3、用F5擋效果明顯,後來因攻擊無效後,使用者很少來攻擊了,畢竟攻擊也是有成本的。

  調整系統引數擋攻擊

沒有F5這種高階且昂貴的裝置怎麼辦?我測試過以下引數組合能明顯減小影響,準備以後不用F5抗攻擊。

第一個引數tcp_synack_retries = 0是關鍵,表示迴應第二個握手包(SYN+ACK包)給客戶端IP後,如果收不到第三次握手包(ACK包)後,不進行重試,加快回收“半連線”,不要耗光資源。

不修改這個引數,模擬攻擊,10秒後被攻擊的80埠即無法服務,機器難以ssh登入; 用命令netstat -na |grep SYN_RECV檢測“半連線”hold住180秒;

修改這個引數為0,再模擬攻擊,持續10分鐘後被攻擊的80埠都可以服務,響應稍慢些而已,只是ssh有時也登入不上;檢測“半連線”只hold住3秒即釋放掉。

修改這個引數為0的副作用:網路狀況很差時,如果對方沒收到第二個握手包,可能連線伺服器失敗,但對於一般網站,使用者重新整理一次頁面即可。這些可以在高峰期或網路狀況不好時tcpdump抓包驗證下。

根據以前的抓包經驗,這種情況很少,但為了保險起見,可以只在被tcp洪水攻擊時臨時啟用這個引數。

tcp_synack_retries預設為5,表示重發5次,每次等待30~40秒,即“半連線”預設hold住大約180秒。詳細解釋:

The tcp_synack_retries setting tells the kernel how many times to retransmit the SYN,ACK reply to

an SYN request. In other words, this tells the system how many times to try to establish a passive

TCP connection that was started by another host.

This variable takes an integer value, but should under no circumstances be larger than 255 for the

same reasons as for the tcp_syn_retries variable. Each retransmission will take aproximately 30-40

seconds. The default value of the tcp_synack_retries variable is 5, and hence the default timeout

of passive TCP connections is aproximately 180 seconds.

之所以可以把tcp_synack_retries改為0,因為客戶端還有tcp_syn_retries引數,預設是5,即使伺服器端沒有重發SYN+ACK包,客戶端也會重發SYN握手包。詳細解釋:

The tcp_syn_retries variable tells the kernel how many times to try to retransmit the initial SYN

packet for an active TCP connection attempt.

This variable takes an integer value, but should not be set higher than 255 since each

retransmission will consume huge amounts of time as well as some amounts of bandwidth. Each

connection retransmission takes aproximately 30-40 seconds. The default setting is 5, which

would lead to an aproximate of 180 seconds delay before the connection times out.

第二個引數_max_syn_backlog = 200000也重要,具體多少數值受限於記憶體。

以下配置,第一段引數是最重要的,第二段引數是輔助的,其餘引數是其他作用的:

# vi /etc/

使配置生效:

# sysctl -p

注意,以下引數面對外網時,不要開啟。因為副作用很明顯,具體原因請google,如果已開啟請顯式改為0,然後執行sysctl -p關閉。因為經過試驗,大量TIME_WAIT狀態的連線對系統沒太大影響:

為了處理大量連線,還需改大另一個引數:

# vi /etc/security/

在底下新增一行表示允許每個使用者都最大可開啟409600個檔案控制代碼(包括連線):

* – nofile 409600

參考資料

檔案控制代碼不要超過系統限制/usr/include/linux/fs.h,相關連結:

#define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */

TAG標籤:診斷 Flood 洪水 SYN TCP #