Syn攻擊是最多見又最容易被利用的一種攻擊手法,利用TCP協議的缺陷,發送大量僞造TCP鏈接請求,經常使用假冒的IP發來海量的SYN包,被攻擊的服務器迴應SYN+ACK,由於對方是假冒的IP,永遠收不到包而且不會迴應,致使被攻擊服務器保持大量SYN_RECV狀態的半鏈接,而且會重試默認5次迴應握手包,塞滿TCP等待鏈接隊列,資源耗盡,讓正常的業務請求鏈接不進來。數據庫
Syn攻擊常見於應用服務器,而數據庫服務器在內網中,應該很難碰到相似的攻擊,但有時候應用程序若是和數據庫建連姿式不正確,在數據庫端,也會被認爲是Syn攻擊,並拒絕鏈接創建。緩存
數據庫突發的拒絕連接,應用報錯,出問題的時間點上,數據庫服務器的操做系統日誌裏,即/var/log/messages,可看到以下報錯信息:
服務器
kernel: possible SYN flooding on port 3306. Sending cookies.
出問題的點上,從數據庫的監控指標來看,Threads Connected 這個指標有增加。這個也是很明顯,由於對數據庫來講,Syn Flooding就是應用程序突發的對數據庫發起建連,操做系統處理不過來,因此報Syn Flooding, 從數據庫的性能指標來看,鏈接數確定是會有一個突發的增加。應對方案就是須要分析這些突發的增加是怎麼來的,削峯填谷,讓鏈接更平穩。cookie
在數據庫服務端,作以下調整:這個調整的意思是說:增長TCP半鏈接的緩衝,默認值是2048,咱們調整到8192,讓系統的抗突發壓力增大一些。Tcp_syn_retires和Tcp_synack_retires默認是5,也就是服務器端要發送五次包,纔會終止重試,咱們把這個參數調整爲2. 只重試一次,讓出錯的包儘可能提前出錯,以減小緩存的鏈接數。tcp
echo 8192 > /proc/sys/net/ipv4/tcp_max_syn_backlog echo 2 > /proc/sys/net/ipv4/tcp_syn_retries echo 2 > /proc/sys/net/ipv4/tcp_synack_retries
這個參數調整,即時生效,無需重啓。固然服務器重啓後,這些參數也會回退到默認值。經此調整,數據庫端的抗壓能力獲得增強,但並無徹底解決問題。性能
咱們在客戶端也作相應調整:操作系統
爲減小數據庫的鏈接數壓力,一般咱們建議鏈接池作以下配置:線程
testWhileIdle="false"。空閒時不檢測鏈接串健康 minIdle="0"。鏈接池裏面空閒鏈接的最小個數 maxAge="30000"。一個連接超過多少毫秒就能夠回收掉。 initialSize="1"。鏈接池裏面初始鏈接的最小個數 timeBetweenEvictionRunsMillis="5000"。回收線程的運行間隔(毫秒)
對於如今的場景,咱們建議調高minIdle這個參數,從0調整到5. 讓鏈接池平時有5個空閒鏈接存在,這樣,發起對數據庫請求的時候,會先使用這5個空閒鏈接。達到削峯填谷的做用。固然,反作用就是數據庫平時的鏈接數會增加。具體調整到多少合適,須要結合實際的數據庫鏈接負載狀況。對於.NET程序,也有相應的鏈接池參數能夠調整:能夠適當修改minPoolSize這個參數,也調整到5.日誌
經此調整,基本上大部分的數據庫Syn Flooding問題都能解決。code
固然,這些都是調優的手段,只能是微微的改善系統。提升抗壓能力。最終的分析,仍是要看鏈接壓力從何而來。以及爲什麼須要突發創建大量鏈接到數據庫。對於此種突發場景,用數據庫是否合適。替代方案是前面用Redis加一層緩衝。避免突發的對數據庫發起建連請求。這個就涉及到應用的改造了。