亚洲欧美中文字幕专区,日韩免费在线播放,777免费视频,欧美手机看片,色cccwww在线播放,欧美亚洲另类自拍偷在线拍,欧美无限看

當前位置:首頁 -> 焦點新聞

SYN Cookie原理及其在Linux內(nèi)核中的實現(xiàn)

2005/1/7 10:10:15       
 
魏晉偉
2004-9-23
   在目前以IPv4為支撐的網(wǎng)絡協(xié)議上搭建的網(wǎng)絡環(huán)境中,SYN Flood是一種非常危險而常見的DoS攻擊方式。到目前為止,能夠有效防范SYN Flood攻擊的手段并不多,而SYN Cookie就是其中最著名的一種。

概述
    在目前以IPv4為支撐的網(wǎng)絡協(xié)議上搭建的網(wǎng)絡環(huán)境中,SYN Flood是一種非常危險而常見的DoS攻擊方式。到目前為止,能夠有效防范SYN Flood攻擊的手段并不多,而SYN Cookie就是其中最著名的一種。SYN Cookie原理由D. J. Bernstain和 Eric Schenk發(fā)明。在很多操作系統(tǒng)上都有各種各樣的實現(xiàn)。其中包括Linux。本文就分別介紹一下SYN Flood攻擊和SYN Cookie的原理,更重要的是介紹Linux內(nèi)核中實現(xiàn)SYN Cookie的方式。最后,本文給出一種增強目前Linux中SYN Cookie功能的想法。

    一 SYN Flood攻擊
    SYN Flood攻擊是一種典型的拒絕服務型(Denial of Service)攻擊。所謂拒絕服務型攻擊就是通過進行攻擊,使受害主機或網(wǎng)絡不能夠良好的提供服務,從而間接達到攻擊的目的。

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

    在最常見的SYN Flood攻擊中,攻擊者在短時間內(nèi)發(fā)送大量的TCP SYN包給受害者,這時攻擊者是TCP客戶機,受害者是TCP服務器。根據(jù)上面的描述,受害者會為每個TCP SYN包分配一個特定的數(shù)據(jù)區(qū),只要這些SYN包具有不同的源地址(這一點對于攻擊者來說是很容易偽造的)。這將給TCP服務器系統(tǒng)造成很大的系統(tǒng)負擔,最終導致系統(tǒng)不能正常工作。

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

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

    三 Linux內(nèi)核中的SYN Cookie實現(xiàn)
    Linux內(nèi)核中對SYN Flood有很好的防護。以下的討論都是針對Linux2.4.20內(nèi)核進行的。在每一個sock都有一個tcp_opt即這個sock的TCP選項。在tcp_opt其中有一個tcp_listen_opt,這里存儲的是這個sock在LISTEN狀態(tài)下時保存的一些選項,其中有一個open_request結(jié)構的數(shù)組,數(shù)組長度為TCP_SYNQ_HSIZE(512)。所有這些表示在一個sock,最多可以同時開啟512個半開連接(這是在不考慮其他約束條件時的最大值,實際情況中不會達到這個值)。當這個數(shù)組滿了時,新來的open_request會頂替掉一個老的open_request。這樣,即使沒有啟動SYN Cookie,也能夠在SYN Flood發(fā)生時保護系統(tǒng)免于癱瘓。問題是這種處理方法會在面對SYN Flood攻擊時丟掉正常的TCP連接請求。SYN Cookie的作用恰恰是保證在面對SYN Flood攻擊時,一方面能夠拒絕非法的TCP連接請求,一方面正常連接可以被建立。

    Linux內(nèi)核對TCP流程的處理主要在tcp_ipv4.c文件中的函數(shù)實現(xiàn)。具體的,當處理TCP SYN包時,系統(tǒng)進入tcp_v4_conn_request函數(shù)。其中調(diào)用cookie_v4_init_sequence生成一個ISN(Initial Sequence Number)。Linux內(nèi)核把它作為SYN Cookie流程中的cookie。

    cookie_v4_init_sequence函數(shù)在syncookies.c文件中定義,它又調(diào)用random.c文件中的secure_tcp_syn_cookie函數(shù)。cookie的實質(zhì)計算是在這個函數(shù)中進行的。

    在random.c文件里給出secure_tcp_syn_cookie函數(shù)的定義之前給出兩個宏,它們的定義分別為

    #define COOKIEBITS 24
    #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)   

    COOKIEBITS表示cookie的比特長度;COOKIEMASK是一個COOKIEBITS長的比特串,所有比特都是1。

    還有兩個比特串,被定義成一個__u32的二維數(shù)組

    static __u32 syncookie_secret[2][16-3+HASH_BUFFER_SIZE];
   
    其中所有的比特值在secure_tcp_syn_cookie中被隨機的賦予,用get_random_bytes函數(shù)。它們成為制作cookie的密鑰。這兩個被隨機產(chǎn)生的比特串是整個SYN Cookie實現(xiàn)方案的關鍵。另外還有一個開關syncookie_init控制對這兩個密鑰的改動。

    還需要指出,在文件syncookies.c中定義有一個__u16組成的表static __u16 const msstab[],這個表中保存的是一些可能的MSS(Maximum Segment Size)值。

    secure_tcp_syn_cookie函數(shù)的返回值就是計算得到的ISN值,即cookie。為了描述方便,我們給出如下定義:

    tmp1 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[0]
    tmp2 := saddr + daddr + ((sport<<16)+dport) + syncookie_secret[1]
    tmp11 := HASH_TRANSFORM(tmp1[16], tmp1)
    tmp22 := HASH_TRANSFORM(tmp2[16], tmp2)
    A := tmp11[0][17]
    B := tmp22[1][17]
 
    sseq := ntohl(skb->h.th->seq) 這里的skb是攜帶TCP SYN的那個skb
    count1 := jiffies/(HZ*60) 當前時間的分鐘值
    data1 := msstab

    從前往后最后一個小于skb中攜帶的MSS值的值的索引(值得注意的是兩個密鑰在第一次被初始化后,就不會再有改動,直到系統(tǒng)重新啟動。因此可以認為它是一個常值。)

    有了上面的定義我們可以得到cookie等于

    isn := A+sseq + (count1<<COOKIEBITS) + (B+data1)&COOKIEMASK
        
    這個isn被賦予返回的TCP SYN+ACK包中,作為其中的ISN值。這就是cookie 的產(chǎn)生過程。在這個過程中,沒有在本地為這個連接請求分配任何存儲空間。

    在TCP服務器收到TCP ACK包時,相應的要進行SYN Cookie的檢查。這個檢查過程在函數(shù)tcp_v4_hnd_req中的cookie_v4_check函數(shù)開始。cookie_v4_check調(diào)用cookie_check函數(shù),cookie_check函數(shù)調(diào)用check_tcp_syn_cookie函數(shù)。

    check_tcp_syn_cookie函數(shù)在random.c中定義,是與前面介紹的
    secure_tcp_syn_cookie函數(shù)對應的函數(shù),檢查從TCP ACK中提取出的ISN值。

    在check_tcp_syn_cookie中假定ISN的值如下

    isn := A+sseq + (count2<<COOKIEBITS) + (B+data2)&COOKIEMASK

    這里的A、B都是根據(jù)當前這個skb中的地址信息和syncookie_secret算出來的;sseq是根據(jù)這個skb中的seq值算出的。

    有了上面這些值,TCP服務器就可以反算出count2和data2。理論上來說,只要這個isn是原來那個isn,應該有

    count2 == count1 
    data2 == data1

    但是這種結(jié)論僅僅是一個理論情況。因為在TCP服務器端并沒有保存原來的count1和data1,因此不能直接進行比較。TCP服務器采取的方法是:

    1)計算出當前的分鐘值

    count3 := jiffies/(HZ*60)

    用count3與count2比較,如果差值超過COUNTER_TRIES(4)分鐘,則認為這 個ACK包不合法。

    2)看data2是不是一個合法的msstab的索引,也就是說是不是小于NUM_MSS, 即(sizeof(msstab)/sizeof(msstab[0]) - 1)。如果小于,則認為這個ACK 合法,否則認為非法。

    上面介紹的就是Linux內(nèi)核Linux2.4.20中對SYN Cookie的實現(xiàn)方式。下面討論一下它的合理性。希望得到的結(jié)論是這種方案可以有效的實現(xiàn)一般TCP的連接,同時可以防止SYN Flood攻擊。

    從上面的介紹來說,合法的TCP連接請求一定可以通過SYN Cookie流程。 另一方面我們看SYN Cookie在系統(tǒng)受到各種SYN Flood攻擊時會采取的行為。 最一般的SYN Flood攻擊方式是攻擊者作為TCP客戶機發(fā)送大量TCP SYN包而不再發(fā)送其他的包。這時SYN Cookie會為每個SYN包計算出相應的ISN值,并返回SYN+ACK包,而在本地將不分配任何存儲空間,因此不會被成功攻擊。

    根據(jù)SYN Cookie的原理,攻擊者有可能直接發(fā)送大量ACK包。這時SYN Cookie提取出每個包的isn值,并假定它有下面的格式

    isn := A+sseq + (count<<COOKIEBITS) + (B+data)&COOKIEMASK

    反算出count和data。

    因為攻擊者并不知道這里的A和B,因此經(jīng)過反算出的count和data幾乎不可能都合理,因此TCP服務器也幾乎不可能為這些ACK包分配存儲空間,這也就說明了SYN Cookie達到起到了抵擋SYN Flood攻擊的作用。

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

    一種杜絕這種情況的方法是SYN Cookie Firewall。它是SYN Cookie的一種擴展形式?偟膩碚f,它是利用原來SYN Cookie的原理在內(nèi)網(wǎng)和外網(wǎng)之間實現(xiàn)TCP三次握手過程的代理(proxy)的機制。

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

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


    上圖是SYN Cookie Firewall的工作原理,它相當于在TCP Server與TCP Client之間實現(xiàn)了對三次握手協(xié)議的代理。第一次"三次握手"在TCP Client與防火墻之間進行,第二次"三次握手"在防火墻與TCP Server之間。在第一次"三次握手"時使用前面介紹的SYN Cookie流程。有一個問題在進行兩次"三次握手"時出現(xiàn)了:如圖所示,進行第一次"三次握手"后,TCP Client認為后續(xù)數(shù)據(jù)包的seq值從c+1開始,而進行第二次"三次握手"后,TCP Server認為后續(xù)發(fā)來的數(shù)據(jù)包的seq值從c`+1開始, c是cookie,c`是TCP Server隨機產(chǎn)生的。c和c`幾乎不可能相等,也就是說在完成上面的兩個"三次握手"后,如果不進行其他操作,后續(xù)從TCP Client到TCP Server的數(shù)據(jù)包都將被認為順序號不對而被丟掉。一種補救方法就是在防火墻本地保存一個值δ
    δ = |c - c`|
    利用這個差值,在每個數(shù)據(jù)包經(jīng)過防火墻時,將其seq值修改一下,這樣,后續(xù)的數(shù)據(jù)流量可以完美地在TCP Server和TCP Client之間傳輸了。

    總結(jié)
    現(xiàn)在普遍使用的IPv4協(xié)議帶有很多安全上的問題,其中面對SYN Flood攻擊的軟弱就是一點。在不改變TCP三次握手流程的情況下,TCP Server幾乎不可能有效的防范SYN Flood的攻擊。要保證完全防范SYN Flood,必須修改三次握手協(xié)議。SYN Cookie是一種很有效的方法。它的思想比較簡單,主要是如何具體的實現(xiàn),Linux系統(tǒng)也提供了一種實現(xiàn)。

  

煤炭網(wǎng)版權與免責聲明:

凡本網(wǎng)注明"來源:煤炭網(wǎng)m.jingweixianlan.com "的所有文字、圖片和音視頻稿件,版權均為"煤炭網(wǎng)m.jingweixianlan.com "獨家所有,任何媒體、網(wǎng)站或個人在轉(zhuǎn)載使用時必須注明"來源:煤炭網(wǎng)m.jingweixianlan.com ",違反者本網(wǎng)將依法追究責任。

本網(wǎng)轉(zhuǎn)載并注明其他來源的稿件,是本著為讀者傳遞更多信息的目的,并不意味著本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載使用時,必須保留本網(wǎng)注明的稿件來源,禁止擅自篡改稿件來源,并自負版權等法律責任。違反者本網(wǎng)也將依法追究責任。 如本網(wǎng)轉(zhuǎn)載稿件涉及版權等問題,請作者在兩周內(nèi)盡快來電或來函聯(lián)系。

  • 用手機也能做煤炭生意啦!
  • 中煤遠大:煤炭貿(mào)易也有了“支付寶”
  • 中煤開啟煤炭出口貿(mào)易人民幣結(jié)算新時代
  • 下半年煤炭市場依然嚴峻
市場動態(tài)

網(wǎng)站技術運營:北京真石數(shù)字科技股份有限公司、喀什中煤遠大供應鏈管理有限公司、喀什煤網(wǎng)數(shù)字科技有限公司

總部地址:北京市豐臺區(qū)總部基地航豐路中航榮豐1層

京ICP備18023690號-1      京公網(wǎng)安備 11010602010109號


關注中煤遠大微信
跟蹤最新行業(yè)資訊