摘自:http://blog.sina.com.cn/s/blog_54b5ea250100g2r8.htmlhtml
SYN攻擊屬於DOS攻擊的一種,它利用TCP協議缺陷,經過發送大量的半鏈接請求,耗費CPU和內存資源。TCP協議創建鏈接的時候須要雙方相互確認信息,來防止鏈接被僞造和精確控制整個數據傳輸過程數據完整有效。因此TCP協議採用三次握手創建一個鏈接。
第一次握手:創建鏈接時,客戶端發送syn包到服務器,並進入SYN_SEND狀態,等待服務器確認第二次握手:服務器收到syn包,必須確認客戶的SYN 同時本身也發送一個SYN包即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
SYN攻擊利用TCP協議三次握手的原理,大量發送僞造源IP的SYN包也就是僞造第一次握手數據包,服務器每接收到一個SYN包就會爲這個鏈接信息分配核心內存並放入半鏈接隊列,若是短期內接收到的SYN太多,半鏈接隊列就會溢出,操做系統會把這個鏈接信息丟棄形成不能鏈接,當攻擊的SYN包超過半鏈接隊列的最大值時,正常的客戶發送SYN數據包請求鏈接就會被服務器丟棄,每種操做系統半鏈接隊列大小不同因此抵禦SYN攻擊的能力也不同。
每種操做系統都有方法來調整TCP模塊的半鏈接隊列最大數,例如Win2000操做系統在註冊表
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters裏 TcpMaxHalfOpen,TcpMaxHalfOpenRetried ,Linux操做系統用變量tcp_max_syn_backlog來定義半鏈接隊列的最大數。
可是每創建一個半鏈接資源就會耗費系統的核心內存,操做系統的核心內存是專門提供給系統內核使用的內存不能進行虛擬內存轉換是很是緊缺的資源windows2000 系統當物理內存是4g的時候核心內存只有不到300M,系統全部核心模塊都要使用核心內存因此能給半鏈接隊列用的核心內存很是少。Windows 2003 默認安裝狀況下,WEB SERVER的80端口每秒鐘接收5000個SYN數據包一分鐘後網站就打不開了。標準SYN數據包64字節 5000個等於 5000*64 *8(換算成bit)/1024=2500K也就是 2.5M帶寬,如此小的帶寬就可讓服務器的端口癱瘓,因爲攻擊包的源IP是僞造的很難追查到攻擊源,,因此這種攻擊很是多。linux
------------------------------------------------------------------------------------windows
tcp半開鏈接是指發送了tcp鏈接請求,等待對方應答的狀態,此時鏈接並無徹底創建起來,雙方還沒法進行通訊交互的狀態,此時就稱爲半鏈接。因爲一個完整的tcp鏈接須要通過三次握手才能完成,這裏把三次握手以前的鏈接都稱之爲半鏈接(見圖1)。
爲了便於理解,咱們把一次完整的tcp鏈接比做汽車經過一座大橋,在經過大橋以前的行程都稱之爲tcp半開鏈接。tcp半開鏈接數就是大橋的車道,因爲這個這個半鏈接數量若是設置過大,不只耗費大量系統資源,並且還可能會遭受不少ddos攻擊。所以,出於安全考慮,默認xp sp2(包括sp3)只容許同時存在10個tcp半開鏈接,也就是說這個大橋只有10個車道,破解就是經過修改tcpip.sys,拓寬這個大橋,使之擁有更多的車道,也就是增長tcp半開鏈接數安全
-------------------------------------------------------------------------------------------服務器
很遺憾,在這個文章裏面回覆的絕大部分人,可能包括我沒有看到這個以前在內,都不知道什麼是「半開鏈接」,更加不知道微軟爲何要進行限制。
因此就有諸如「2003是服務器,若是限制了基本網站就不要用了」之類好笑的觀點了。
咱們先來普及一下基本常識吧,下面的文字可能有點晦澀:
創建TCP鏈接的標準過程是這樣的:
首先,請求端(客戶端)發送一個包含SYN標誌的TCP報文,SYN即同步(Synchronize),同步報文會指明客戶端使用的端口以及TCP鏈接的初始序號;
第二步,服務器在收到客戶端的SYN報文後,將返回一個SYN+ACK的報文,表示客戶端的請求被接受,同時TCP序號被加一,ACK即確認(Acknowledgement)。
第三步,客戶端也返回一個確認報文ACK給服務器端,一樣TCP序列號被加一,到此一個TCP鏈接完成。
以上的鏈接過程在TCP協議中被稱爲三次握手(Three-way Handshake)。
問題就出在TCP鏈接的三次握手中,
假設一個用戶向服務器發送了SYN報文後忽然死機或掉線,那麼服務器在發出SYN+ACK應答報文後是沒法收到客戶端的ACK報文的(第三次握手沒法完成),
這種狀況下服務器端通常會重試(再次發送SYN+ACK給客戶端)並等待一段時間後丟棄這個未完成的鏈接。
這段時間的長度咱們稱爲SYN Timeout,通常來講這個時間是分鐘的數量級(大約爲30秒-2分鐘)。一個用戶出現異常致使服務器的一個線程等待1分鐘並非什麼很大的問題,
但若是有一個惡意的攻擊者大量模擬這種狀況,服務器端將爲了維護一個很是大的半鏈接列表而消耗很是多的資源----數以萬計的半鏈接,即便是簡單的保存並遍歷也會消耗很是多的CPU時間和內存,況且還要不斷對這個列表中的IP進行SYN+ACK的重試。
實際上若是服務器的TCP/IP棧不夠強大,最後的結果每每是堆棧溢出崩潰---即便服務器端的系統足夠強大,服務器端也將忙於處理攻擊者僞造的TCP鏈接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率很是之小)。
此時從正常客戶的角度看來,服務器失去響應,
這種狀況咱們稱做:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)。
上面的文字可能不少人看不懂,那咱們用比較簡單的例子來解釋:
1.第一次握手-----------電腦:服務器,你有陳冠希的照片嗎?
2.第二次握手-----------服務器:有,你是否是想要?
3.第三次握手-----------電腦:固然想,你傳給我。
4.正式創建鏈接,雙方開始傳輸照片。
在上面的例子中,若是電腦沒有回答服務器的問題,就是第三次握手尚未完成,這樣的鏈接就叫作「半開鏈接」。
微軟爲了防止SYN洪水攻擊,在XP SP2中,限制了最大併發半開鏈接數爲10。
也就是說,使用XP SP2的電腦,最多能夠同時向十臺服務器詢問:「服務器,你有陳冠希的照片嗎」。
若是電腦不回答服務器的發問:「有,你是否是想要?」的話,
它就不能向第十一臺服務器詢問了。
它必須先對前面十臺服務器中的隨便某一臺回答「固然想,你傳給我」,完成一次鏈接以後,才能向第十一臺服務器進行詢問。
說到這裏,你們應該明白了吧?
微軟所謂的半開鏈接數限制,只是針對發起方(也就是上面例子中的電腦)的,不是針對接受方(也就是上面例子中的服務器)!
一臺使用XP SP2的電腦,若是它是半開鏈接的發起方,它就會受到這個限制。
若是它是半開鏈接的接受方,那麼,它是不會受到這個半開鏈接數的限制的!
以上只是針對XP SP2的分析,若是是使用2003或者2008的電腦呢?
也是一樣的道理,若是2003或者2008是接受方,好比咱們常見的WEB服務器或者FTP服務器,那它們也不會受到半開鏈接數的限制!
哪怕它們的最大併發半開鏈接數一樣是10,也不會對它們的HTTP服務,或者FTP服務,有任何影響!
那麼,該回到主題了,到底2003有沒有限制最大併發半開鏈接數呢?
樓主的分析已經很清楚了:
以英文企業版Windows 2003 SP2的tcpip.sys爲例,TCPMaxHalfOpen是5000。
這很好的說明了,
微軟對英文企業版2003 SP2的最大併發半開鏈接數的限制爲5000!
咱們再想想,如今互聯網上有不少使用2003來架構的網站或者論壇,
它們的最大同時訪問量每每是用數萬爲單位來計算的,
可是用戶訪問網站或者登錄論壇卻沒有感覺到什麼影響,除非是服務器受到SYN洪水攻擊。
這不正好說明了,微軟所謂的半開鏈接數限制,只是針對發起方的嗎?
因此咱們能夠得出一個結論:
2003或者2008,一樣有半開鏈接數的限制,
只不過,只有當它們做爲鏈接的發起方,好比BT下載的客戶端,P2P網絡電視的使用者時,纔會受到這個限制;
在它們做爲鏈接的接受方,好比WEB服務器,或者FTP服務器時,是不會受到限制的。
最後再解釋一下注冊表中的TCPMaxHalfOpen相關項目的設置和用途:
首先,SynAttackProtect的鍵值,類型爲REG_DWORD,取值範圍是0,1。從WIN2003 SP1開始默認值是1。
這個值決定了系統受到SYN攻擊時採起的保護措施,包括減小系統SYN+ACK的重試的次數等。
其次,TcpMaxHalfOpen的鍵值,類型爲REG_DWORD,取值範圍是100-0xFFFF,這個值是系統容許同時打開的半鏈接。
默認狀況下WIN2K PRO和SERVER是100,ADVANCED SERVER是500,WIN2003是5000。
而後,TcpMaxHalfOpenRetried的鍵值,類型爲REG_DWORD,取值範圍是80-0xFFFF,這個值決定了在什麼狀況下系統會打開SYN攻擊保護。
默認狀況下WIN2K PRO和SERVER是80,ADVANCED SERVER是400,WIN2003是2500。
Win2003的SYN攻擊保護機制是這樣的:
正常狀況下,WIN2003對TCP鏈接的三次握手有一個常規的設置,
包括SYN Timeout時間、SYN-ACK的重試次數和SYN報文從路由器到系統再到Winsock的延時等。
這個常規設置是針對系統性能進行優化的(安全和性能每每相互矛盾),因此能夠給用戶提供方便快捷的服務。
一旦服務器受到攻擊,SYN半鏈接的數量超過TcpMaxHalfOpenRetried的設置,系統會認爲本身受到了SYN Flood攻擊。
此時,設置在SynAttackProtect鍵值中的選項開始做用,SYN Timeout時間被減短,SYN-ACK的重試次數減小,
系統也會自動對緩衝區中的報文進行延時,避免對TCP/IP堆棧形成過大的衝擊,力圖將攻擊危害減到最低。
若是攻擊強度不斷增大,超過了TcpMaxHalfOpen值,此時系統已經不能提供正常的服務了,更重要的是保證系統不會崩潰,
系統將會丟棄任何超出TcpMaxHalfOpen值範圍的SYN報文(應該是使用隨機丟包策略),保證系統的穩定性。
因此,把TcpMaxHalfOpen值改小,只是爲了增強系統對SYN洪水攻擊的防護能力;
改大,再大也超不過TCPIP.SYS的限制。
這是微軟對於「半開鏈接」接受方所採起的一種保護措施,
和對「半開鏈接」發起方所採起的最大併發鏈接數限制,
是相輔相成的。網絡