kernel: possible SYN flooding on port 80. Sending cookies. php
以上是系統日誌中的信息,多是遭到SYN洪水攻擊(SYN Flood)。 linux
那什麼是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)。 cookie
在 最多見的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。 tcp
SYN Cookie原理 spa
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
修改方法:/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之間傳輸了。