linux內核tcp調優規範與方案

一、TCP經常使用內核參數優化
上一篇咱們介紹了服務器上有大量的TIME_WAIT等待,可能形成的危害,以及給web服務器帶來負擔。如何解決這個問題呢,其實,解決思路很簡單,就是讓服務器可以快速回收和重用那些TIME_WAIT的資源便可。這就是對tcp調優。
在linux系統上,對tcp調優主要是經過調整Linux內核參數來實現的,其實主要是對/proc文件系統進行設置,/proc文件系統是一種內核和內核模塊用來向進程(process) 發送信息的機制(因此叫作/proc)。經過這個僞文件系統咱們能夠和內核內部數據結構進行交互,在運行中改變內核參數。 與其餘文件系統不一樣,/proc存在於內存之中而不是硬盤上。proc文件系統以文件的形式向用戶空間提供了訪問接口,這些接口能夠用於在運行時獲取相關信息或者修改參數配置,於是它是很是方便的一個接口。
/proc目錄下存放着大多數的內核參數,而且能夠在系統運行的同時進行更改, 可是,從新啓動機器後就會失效,怎麼解決呢,咱們能夠經過將更改的內核參數寫入 /etc/sysctl.conf文件中實現永久更改,在/etc/sysctl.conf文件中添加或者修改如何設置:
#對於一個新建鏈接,內核要發送多少個SYN鏈接請求才決定放棄,不該該大於255,默認值是5,這裏設置爲2.
net.ipv4.tcp_syn_retries=2
#表示當keepalive啓用的時候,TCP發送keepalive消息的頻度。缺省是7200秒,改成300秒
net.ipv4.tcp_keepalive_time=300
#表示孤兒socket廢棄前重試的次數,重負載web服務器建議調小。
net.ipv4.tcp_orphan_retries=1
#表示若是套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
net.ipv4.tcp_fin_timeout=30
#表示SYN隊列的長度,默認爲1024,加大隊列長度爲8192,能夠容納更多等待鏈接的網絡鏈接數。
net.ipv4.tcp_max_syn_backlog = 8192 (注意:這個隊列大小除了系統設置外,程序裏面也要設置)
#表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少許SYN攻 擊,默認爲0,表示關閉
net.ipv4.tcp_syncookies = 1
#表示開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉
net.ipv4.tcp_tw_reuse = 1
#表示開啓TCP鏈接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉
net.ipv4.tcp_tw_recycle = 1
修改完以後執行/sbin/sysctl -p讓參數生效。
其實TIME-WAIT的問題仍是比較好處理的,能夠經過調節服務器參數實現,有時候還會出現CLOSE_WAIT不少的狀況,CLOSE_WAIT是在對方關閉鏈接以後服務器程序本身沒有進一步發出ACK信號。換句話說,就是在對方鏈接關閉以後,程序裏沒有檢測到,或者程序壓根就忘記了這個時候須要關閉鏈接,因而這個資源就一直被程序佔着。因此解決CLOSE_WAIT過多的方法還須要檢查程序,檢查代碼,由於問題很大程度上出在服務器程序中。
到此爲止,TCP優化到一段落。linux

二、TCP洪水攻 擊(SYN Flood)的診斷和處理
SYN Flood是當前最流行的DoS(拒絕服務)與DDoS(分佈式拒絕服務)的方式之一,這是一種利用TCP協議缺陷,發送大量僞造的TCP鏈接請求,經常使用假冒的IP或IP號段發來海量的請求鏈接第一個握手包(SYN包),被攻 擊服務器迴應第二個握手包(SYN+ACK包),由於對方是假冒IP,對方永遠收不到包且不會迴應第三個握手包。致使被攻 擊服務器保持大量SYN_RECV狀態的「半鏈接」,而且會重試默認5次迴應第二個握手包,直到塞滿TCP等待鏈接隊列,資源耗盡(CPU滿負荷或內存不足),讓正常的業務請求鏈接不進來。
那麼如何診斷SYN Flood問題呢,通常狀況下若是發現網站打開緩慢、CPU負載高、ssh登錄慢甚至登錄不上,同時在系統日誌中發現以下信息:
[root@test ~]# tail -f /var/log/messages
Mar 12 02:38:03 test kernel: possible SYN flooding on port 80. Sending cookies.
Mar 12 02:39:04 test kernel: possible SYN flooding on port 80. Sending cookies.
Mar 12 02:40:04 test kernel: possible SYN flooding on port 80. Sending cookies.
若是出現相似這種狀況,那可能就是遭遇了TCP洪水***。web

此時,經過以下命令檢查TCP鏈接狀態:
[root@localhost ~]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIMEWAIT 7807
FINWAIT1 59
ESTABLISHED 8112
FINWAIT2 809
SYNRECV 198098
CLOSING 27
LASTACK 36
檢查發現,SYNRECV鏈接數會很是多。
針對這個問題,首先要作應急處理,那就是找到請求數請最多的IP地址,查找攻 擊來源,使用以下命令組合:
[root@localhost ~]# netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n3
36.171.242
149.130.152
149.130.18
查到可疑的IP後,利用iptables臨時封掉最大嫌疑攻 擊的IP或IP號段。
接着,還須要調整系統內核參數,來抵擋這種攻 擊,根據上面對SYN Flood攻 擊的特色,咱們只需修改操做系統內核參數便可有效緩解。主要參數以下:
net.ipv4.tcpsyncookies = 1
net.ipv4.tcpmaxsynbacklog = 81920
net.ipv4.tcpsynackretries = 2
三個參數的含義分別爲啓用SYN Cookie、設置SYN最大隊列長度以及設置SYN+ACK最大重試次數。
SYN Cookie的做用是緩解服務器資源壓力。啓用以前,服務器在接到SYN數據包後,會當即分配存儲空間,並隨機化一個數字做爲SYN號發送SYN+ACK數據包。而後保存鏈接的狀態信息等待客戶端確認。而在啓用SYN Cookie以後,服務器再也不立刻分配存儲空間,並且經過基於時間種子的隨機數算法設置一個SYN號,替代徹底隨機的SYN號。發送完SYN+ACK確認報文以後,清空資源不保存任何狀態信息。直到服務器接到客戶端的最終ACK包。同時,經過Cookie檢驗算法鑑定是否與發出去的SYN+ACK報文序列號匹配,匹配則經過完成握手,失敗則丟棄。
tcpmaxsynbacklog則是使用服務器的內存資源,換取更大的等待隊列長度,讓攻 擊數據包不至於佔滿全部鏈接而致使正經常使用戶沒法完成握手。
net.ipv4.tcpsynackretries是下降服務器SYN+ACK報文重試次數(默認是5次),儘快釋放等待資源。
這三種措施與攻 擊的三種危害一一對應,完徹底全是對症下藥。但這些措施也是雙刃劍,設置過大可能消耗服務器更多的內存資源,甚至影響正經常使用戶創建TCP鏈接,所以,須要評估服務器硬件資源和大小謹慎設置。算法

相關文章
相關標籤/搜索