kernel: possible SYN flooding on port 80. Sending cookies.

kernel: possible SYN flooding on port 80. Sending cookies.

 

以上是系統日誌中的信息,可能是遭到SYN洪水***(SYN Flood)。

 

那什麼是SYN Flood呢?

 

SYN Flood***是一種典型的拒絕服務型(Denial of Service)***。所謂拒絕服務型***就是通過進行***,使受害主機或網絡不能夠良好的提供服務(就是使服務器不能響應其他的訪問請求),從而間接達到***的目的。

 

SYN Flood***利用的是IPv4中TCP協議的三次握手(Three-Way Handshake)過程進行的***。大家知道協議規定,如果一端想向另一端發起TCP連接,它需要首先發送TCP SYN 包到對方,對方收到後發送一個TCP SYN+ACK包回來,發起方再發送TCP ACK包回去,這樣三次握手就結束了。我們把TCP連接的發起方叫作"TCP客戶機(TCP Client)",TCP連接的接收方叫作"TCP服務器(TCP Server)"。值得注意的是在TCP服務器收到TCP SYN request包時,在發送TCP SYN+ACK包回TCP客戶機前,TCP服務器要先分配好一個數據區專門服務於這個即將形成的TCP連接。一般把收到SYN包而還未收到ACK包時的連 接狀態成爲半開連接(Half-open Connection)。

 

在 最常見的SYN Flood***中,***者在短時間內發送大量的TCP SYN包給受害者,這時***者是TCP客戶機,受害者是TCP服務器。根據上面的描述,受害者會爲每個TCP SYN包分配一個特定的數據區,只要這些SYN包具有不同的源地址(這一點對於***者來說是很容易僞造的)。這將給TCP服務器系統造成很大的系統負擔, 最終導致系統不能正常工作。

 

 

那又爲什麼發送cookie呢?這個cookie是什麼呢?

 

這 個cookie是指SYN Cookie。在目前以IPv4爲支撐的網絡協議上搭建的網絡環境中,SYN Flood是一種非常危險而常見的DoS***方式。到目前爲止,能夠有效防範SYN Flood***的手段並不多,而SYN Cookie就是其中最著名的一種。SYN Cookie原理由D. J. Bernstain和 Eric Schenk發明。在很多操作系統上都有各種各樣的實現。其中包括Linux。

 

 

SYN Cookie原理

 

SYN Cookie是對TCP服務器端的三次握手協議作一些修改,專門用來防範SYN Flood***的一種手段。它的原理是,在TCP服務器收到TCP SYN包並返回TCP SYN+ACK包時,不分配一個專門的數據區,而是根據這個SYN包計算出一個cookie值。在收到TCP ACK包時,TCP服務器在根據那個cookie值檢查這個TCP ACK包的合法性。如果合法,再分配專門的數據區進行處理未來的TCP連接。

 

從上面的介紹可以看出,SYN Cookie的原理比較簡單。到實際的應用中,它有多種不同的實現方式。

 

 

打 開或關閉SYN Cookie功能,可以設置/proc/sys/net/ipv4/tcp_syncookies的值(或在/etc/sysctl.conf中 net.ipv4.tcp_syncookies的值),值爲0關閉SYN Cookie功能,值爲1打開SYN Cookie功能。

 

如果系統資源還沒問題的話,應該多數不是受到SYN Flood***,而是併發連接過多。如果日誌裏有很多這樣的警告信息,並且是因爲服務器負載過高而產生的,應該調整以下幾個參數,直到這個警告消失:

 

tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow,這三個文件都是基於/proc/sys/net/ipv4目錄下

 

tcp_max_syn_backlog變量告訴你在內存中可以緩存多少個SYN請求。該變量需要打開tcp_syncookies纔有效。如果服務器負載很高,可以嘗試提高該變量的值。

 

tcp_synack_retries變 量用於TCP三次握手機制中第二次握手,當收到客戶端發來的SYN連接請求後,服務端將回復SYN+ACK包,這時服務端處於SYN_RCVD狀態,並等 待客戶端發來的回覆ACK包。如果服務端沒有收到客戶端的ACK包,會重新發送SYN+ACK包,直到收到客戶端的ACK包。該變量設置發送 SYN+ACK包的次數,超過這個次數,服務端將放棄連接。默認值是5。

 

tcp_abort_on_overflow變 量的值是個布爾值,默認值爲0(FALSE關閉)。如果開啓,當服務端接收新連接的速度變慢時,服務端會發送RST包(reset包)給客戶端,令客戶端 重新連接。這意味着如果突然發生溢出,將重獲連接。僅當你真的確定不能通過調整監聽進程使接收連接的速度變快,可以啓用該選項。該選項會影響到客戶的連 接。

 


一般情況下,只增加tcp_max_syn_backlog的值就可以解決問題。例如執行命令:

 

#echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog

 

 

 

 


順便說一下SYN Cookie防火牆

 


SYN Cookie Firewall

 

從 上面的介紹可以看到,Linux內核中的SYN Cookie機制主要的功能是防止本機遭受SYN Flood***的,但是在很多情況下,僅僅實現這樣的SYN Cookie機制是不夠的。如果我們要考慮的是一個網關模式的防火牆,它不僅要保護本機免受各種網絡***,還要保護它後面的所有對外有開放TCP端口的主 機免受這些***。比如一個局域網中有個服務器開放了FTP服務給外界,這個服務器主機就有可能遭受到來自互聯網上的SYN Flood***。而這時的防火牆會將所有的***SYN包轉發給受害主機。

 

一種杜絕這種情況的方法是SYN Cookie Firewall。它是SYN Cookie的一種擴展形式。總的來說,它是利用原來SYN Cookie的原理在內網和外網之間實現TCP三次握手過程的代理(proxy)的機制。

 

爲了方便描述,我們假定一個外在的TCP客戶機C希望通過防火牆F連接到局域網中的一個TCP服務器S。

 

在 防火牆收到來自外網的SYN包時,它並不直接進行轉發,而是緩存在本地,再按照原來SYN Cookie的機制製作好一個針對這個SYN包的SYN+ACK包,注意,這個SYN+ACK包中的ack順序號爲特製的cookie值c,更重要的是這 個包的的源地址被僞造成了S的地址(爲了描述方便,我們這裏暫時不考慮NAT等其他因素)。這樣C會接收到這個SYN+ACK包,並認爲是從S反饋回來 的。於是C再響應一個ACK包,並認爲與S的TCP連接已經建立起來。這時防火牆F收到這個ACK包,按照前面的描述的SYN Cookie原理來檢查這個ACK中的ack順序號。如果認爲合法,F將本地緩存的來自C的SYN包發送給S,這時S會響應一個SYN+ACK包到C,其 中也攜帶一個seq號, 我們設爲c`。當然這個包不會到達C,而是由防火牆F截取,F根據這個包中的序列號等信息,造一個ACK包響應到S。這時的情況是:C認爲自己已經與S建 立了TCP連接;S認爲自己與C建立了TCP連接。以後的TCP數據內容可以直接穿過防火牆F,在S和C之間交互。

 

 

根 據SYN Cookie Firewall的工作原理,它相當於在TCP Server與TCP Client之間實現了對三次握手協議的代理。第一次"三次握手"在TCP Client與防火牆之間進行,第二次"三次握手"在防火牆與TCP Server之間。在第一次"三次握手"時使用前面介紹的SYN Cookie流程。有一個問題在進行兩次"三次握手"時出現了:如圖所示,進行第一次"三次握手"後,TCP Client認爲後續數據包的seq值從c+1開始,而進行第二次"三次握手"後,TCP Server認爲後續發來的數據包的seq值從c`+1開始, c是cookie,c`是TCP Server隨機產生的。c和c`幾乎不可能相等,也就是說在完成上面的兩個"三次握手"後,如果不進行其他操作,後續從TCP Client到TCP Server的數據包都將被認爲順序號不對而被丟掉。一種補救方法就是在防火牆本地保存一個值δ

 

δ = |c - c`|

 

利用這個差值,在每個數據包經過防火牆時,將其seq值修改一下,這樣,後續的數據流量可以完美地在TCP Server和TCP Client之間傳輸了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章