• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    SDN架構(gòu)下ARP攻擊的解決方案及示例

    2022-01-19 12:10:22徐大偉祝烈煌厙怡婕
    關(guān)鍵詞:終端機(jī)鏈路層表項(xiàng)

    徐大偉, 戴 鋮, 祝烈煌, 厙怡婕

    (1. 北京理工大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院, 北京 100081; 2. 長春大學(xué) 網(wǎng)絡(luò)安全學(xué)院, 吉林 長春 130022)

    人們的生活與網(wǎng)絡(luò)的聯(lián)系越來越緊密,然而由于傳統(tǒng)網(wǎng)絡(luò)架構(gòu)的控制層與轉(zhuǎn)發(fā)層緊耦合,各個設(shè)備呈分布式管理,網(wǎng)絡(luò)行業(yè)的創(chuàng)新十分困難[1]。因此,SDN架構(gòu)應(yīng)運(yùn)而生,這是一個控制層與數(shù)據(jù)層松耦合、管理式集中的架構(gòu),并且由于SDN可編程的特點(diǎn),更有利于推進(jìn)網(wǎng)絡(luò)行業(yè)的創(chuàng)新。

    但是SDN下的ARP攻擊仍然存在,并且在這種新型網(wǎng)絡(luò)架構(gòu)[2]中,所面臨的風(fēng)險形勢更加嚴(yán)峻[3]。因?yàn)镾DN架構(gòu)下的ARP攻擊不僅會攻擊終端機(jī),而且會攻擊控制器的節(jié)點(diǎn)。但是在已有的網(wǎng)絡(luò)中提出解決方案無法防止SDN中控制層遭受攻擊的風(fēng)險[4-6]。而且現(xiàn)有的SDN架構(gòu)下防止ARP攻擊的方案極少并且都有缺陷,文獻(xiàn)[7]中方案不能自動判斷ARP攻擊[7],文獻(xiàn)[8]中方案無法防止攻擊者2次接入網(wǎng)絡(luò)的攻擊[8],因此,提出一種新架構(gòu)下的解決方案極為重要。

    本文闡釋了SDN網(wǎng)絡(luò)的架構(gòu)構(gòu)成,并將ARP攻擊劃分為2種方式,而本文所提方案解決了SDN架構(gòu)下這2種ARP攻擊方式的攻擊問題,基于控制器和終端機(jī)編寫了兩段程序,在虛假的ARP數(shù)據(jù)包到達(dá)目標(biāo)終端機(jī)之前被控制器檢測出并丟棄,同時控制器不會被ARP攻擊所欺騙。本文最大的創(chuàng)新在于使用了RSA非對稱密鑰算法對終端機(jī)進(jìn)行驗(yàn)證,并且使用Montgomery算法[9]對RSA進(jìn)行優(yōu)化,使得即使素數(shù)P、Q非常大也可以正常運(yùn)行。

    1 SDN架構(gòu)與ARP欺騙

    1.1 SDN架構(gòu)

    軟件定義網(wǎng)絡(luò)(Software Defined Networking,縮寫為“SDN”)是美國斯坦福大學(xué)Nick McKeown教授團(tuán)隊(duì)提出的一種新型網(wǎng)絡(luò)創(chuàng)新架構(gòu)[10],它將網(wǎng)絡(luò)的控制平面和數(shù)據(jù)平面解耦分離[11],是實(shí)現(xiàn)高帶寬、動態(tài)網(wǎng)絡(luò)的理想架構(gòu),有利于網(wǎng)絡(luò)行業(yè)的創(chuàng)新。

    SDN的基本思想是路由控制平面和數(shù)據(jù)轉(zhuǎn)發(fā)平面互相分離,數(shù)據(jù)平面更為通用,不再關(guān)注網(wǎng)絡(luò)協(xié)議的轉(zhuǎn)發(fā),只需要接收控制平面的命令并進(jìn)行轉(zhuǎn)發(fā)[12];路由轉(zhuǎn)發(fā)平面被從各個設(shè)備中剝離到一個統(tǒng)一的外部控制器,控制器掌握著所有網(wǎng)絡(luò)的信息[13-14],需要接收數(shù)據(jù)層面發(fā)送的消息,并指引數(shù)據(jù)平面進(jìn)行消息的轉(zhuǎn)路徑發(fā)送。SDN對整個網(wǎng)絡(luò)的資源的調(diào)度和管控性是傳統(tǒng)網(wǎng)絡(luò)不能相比的。

    SDN架構(gòu)按層次結(jié)構(gòu)劃分,如圖1所示,包含5個層次,即應(yīng)用程序?qū)?、北向接口層、控制層、南向接口層和?shù)據(jù)層[15-16]。

    SDN應(yīng)用程序?qū)又饕删W(wǎng)絡(luò)管理員或其他網(wǎng)絡(luò)研究人員用來部署一些網(wǎng)絡(luò)應(yīng)用程序,例如,負(fù)載均衡和訪問控制等[14]。北向接口層為其上層提供網(wǎng)絡(luò)的籠統(tǒng)視圖,使用戶有機(jī)會根據(jù)自己的需求開發(fā)適當(dāng)?shù)膽?yīng)用程序,根據(jù)網(wǎng)絡(luò)條件規(guī)劃資源??刂茖佑煽刂破鹘M成[17],主要有3個任務(wù):①將SDN最上層的需求轉(zhuǎn)交到軟件定義網(wǎng)絡(luò)的交換機(jī);②為軟件定義網(wǎng)絡(luò)應(yīng)用提供底層網(wǎng)絡(luò)的視圖;③對轉(zhuǎn)發(fā)層面進(jìn)行轉(zhuǎn)發(fā)的調(diào)節(jié)、自定義管理。南向接口層有如下功能:控制傳輸、查詢設(shè)備性能、報告統(tǒng)計和通知事件等,可以理解為數(shù)據(jù)平面的一個編程接口。數(shù)據(jù)層主要功能是執(zhí)行來自控制層的流規(guī)則,并應(yīng)答控制器的指令[18-19]。

    圖1 SDN架構(gòu)層次[1]Fig.1 SDN architecture levels

    1.2 OpenFlow協(xié)議

    OpenFlow協(xié)議是SDN架構(gòu)南向接口協(xié)議標(biāo)準(zhǔn),該協(xié)議定義了交換機(jī)傳輸計劃的某些功能組件[20],定義了交換機(jī)的工作機(jī)制和交換機(jī)的管控機(jī)制,同時也定義了控制器和交換機(jī)在通信過程中的消息格式和類型[21]。

    流在協(xié)議中的定義是一個報文的集合,即在某一個時間段內(nèi),經(jīng)過某一網(wǎng)絡(luò),具有相同屬性,并按照一定次序發(fā)送的報文的集合[22]。其中流表是OpenFlow協(xié)議交換機(jī)中的轉(zhuǎn)發(fā)表[23]。協(xié)議交換機(jī)中的流表項(xiàng)等效于在傳統(tǒng)網(wǎng)絡(luò)中集成所有級別的網(wǎng)絡(luò)配置信息,因此,在轉(zhuǎn)發(fā)數(shù)據(jù)時使用更多樣的規(guī)則。

    OpenFlow交換機(jī)的數(shù)據(jù)包處理流程為:數(shù)據(jù)包進(jìn)入交換機(jī),交換機(jī)中的協(xié)議解析模塊解析數(shù)據(jù)包包頭域,然后將解析后的結(jié)果與對應(yīng)的流表進(jìn)行匹配[24]。到了流表內(nèi)部,解析后的結(jié)果與每個流表項(xiàng)進(jìn)行比較,如果匹配成功,則根據(jù)表項(xiàng)上的動作進(jìn)行處理,否則丟棄或轉(zhuǎn)發(fā)給控制器以請求指令[25-26]。

    1.3 SDN架構(gòu)下的ARP攻擊形式

    (1)攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊

    攻擊者在TCP/IP的網(wǎng)絡(luò)層面,竊取合法用戶的終端機(jī)的IP地址或者M(jìn)AC地址[24],使其他終端機(jī)和控制層面錯誤地將攻擊者的IP地址誤判為對應(yīng)合法終端機(jī)的MAC地址,或者錯誤地將攻擊者的MAC地址誤認(rèn)為對應(yīng)的合法終端機(jī)的IP地址[27-28]。

    (2)攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊

    攻擊者在網(wǎng)絡(luò)層和鏈路層同時竊取合法用戶終端機(jī)的IP地址和MAC地址,以欺騙控制層面產(chǎn)生錯誤的MAC地址、IP地址與接入位置映射信息[29]。

    這2種攻擊形式在傳統(tǒng)的ARP攻擊解決方案中并沒有進(jìn)行劃分,只有在文獻(xiàn)[3]中對這2種形式有具體的區(qū)分。

    2 方案設(shè)計

    2.1 方案設(shè)計思路

    方案設(shè)計思路如圖2所示。終端機(jī)在接入網(wǎng)絡(luò),獲得IP地址之后需要向控制器注冊驗(yàn)證信息,其中包括終端機(jī)的MAC地址和RSA公鑰。同時控制器會將IP地址、MAC地址和接入端口號等做成驗(yàn)證信息表項(xiàng),放在以交換機(jī)身份ID為索引的信息表中。在通信中,終端機(jī)發(fā)出ARP Request包[30],到達(dá)交換機(jī)后找不到對應(yīng)流,就會把該數(shù)據(jù)包上發(fā)控制器??刂破鲝腜acket_in消息中獲得ARP數(shù)據(jù)包[31]之后,將該包的IP地址、MAC地址映射與終端機(jī)的信息表項(xiàng)進(jìn)行比對,如果映射對應(yīng)不正確,則向DHCP服務(wù)器請求最新映射,如果還匹配不成功,則向管理員上報ARP攻擊;如果對應(yīng)成功則再將收到該數(shù)據(jù)包時的端口與匹配成功的表項(xiàng)對比,如果端口也匹配成功則代替目標(biāo)終端機(jī)回答該ARP報文,如果端口匹配不成功,則記錄此次ARP請求的目標(biāo)地址并以該報文MAC地址對應(yīng)的公鑰加密一條隨機(jī)消息發(fā)回該終端機(jī),如果該終端機(jī)的MAC地址真實(shí),將會回答出正確的信息,交換機(jī)會將請求的IP地址所對應(yīng)的MAC地址通過消息返回給終端機(jī),并且更新該終端機(jī)的信息。

    圖2 方案設(shè)計基本思路Fig.2 Basic idea of scheme design

    總之,本方案中,需要每個終端機(jī)向控制器注冊信息,而控制器代替目標(biāo)機(jī)回復(fù)ARP請求,并且只有通過驗(yàn)證的ARP請求才能收到回復(fù)。

    2.2 詳細(xì)方案

    本文所提方案要求控制器端擁有檢測ARP消息正確與否的能力,同時也需要終端機(jī)擁有檢測到控制器發(fā)送的驗(yàn)證信息并恢復(fù)的能力。方案主要包括2個主要階段:驗(yàn)證信息交換階段和通信中攻擊防御階段。

    (1)驗(yàn)證信息交換階段主要分為5個步驟

    步驟1:終端機(jī)生成RSA公鑰和私鑰。每個終端機(jī)有屬于自己的2個大素數(shù)P,Q,這2個大素數(shù)為自己的特征值,終端機(jī)利用自己的特征值計算出公鑰和私鑰,將公鑰存在本地,RSA算法流程圖如圖3所示。

    圖3 RSA算法流程圖Fig.3 RSA algorithm flow chart

    步驟2:終端機(jī)與控制器交換公私鑰及其它信息。終端機(jī)通過一個ARP消息向控制器發(fā)送注冊消息,包括自身的IP地址、MAC地址和最初接入端口以及自己的公鑰,其中終端機(jī)公鑰封裝在ARP消息的payload域中。帶有payload域的ARP消息如圖4所示。

    圖4 帶有payload域的ARP消息Fig.4 ARP message with payload field

    步驟3:控制器為終端機(jī)建立驗(yàn)證信息表??刂破魇盏浇K端機(jī)的公鑰和其它信息之后,在該終端機(jī)的交換機(jī)ID表項(xiàng)中創(chuàng)建一個驗(yàn)證信息表,如圖5所示,包括交換機(jī)身份ID、終端機(jī)的IP地址和MAC地址、初始接入端口、終端機(jī)的公鑰和為該終端機(jī)分配的密鑰對中的私鑰。

    圖5 終端機(jī)驗(yàn)證信息表項(xiàng)Fig.5 Terminal verification information table entry

    步驟4:控制器給每個終端機(jī)分配特征值并生成RSA公鑰和私鑰??刂破飨纫宰陨硖卣髦惦S機(jī)生成一對公鑰和私鑰,將私鑰存入對應(yīng)終端機(jī)的驗(yàn)證信息表項(xiàng)中。

    步驟5:控制器向終端機(jī)分發(fā)RSA公鑰??刂破鲗⑸傻拿荑€對中的公鑰封裝在ARP的payload域并發(fā)送給對應(yīng)終端機(jī),終端機(jī)收到后將此公鑰存在本地,此步驟的目的是為了防止驗(yàn)證過程中中間人竊取驗(yàn)證的信息。

    (2)攻擊防御階段主要分為3個步驟

    步驟1:驗(yàn)證源地址對應(yīng)信息。當(dāng)控制器收到ARP請求包時,依照源MAC地址找尋對應(yīng)的表項(xiàng),如果交換機(jī)身份ID、MAC地址和IP地址、連接端口都相同的話,則以ARP Reply消息回復(fù)此數(shù)據(jù)包;如果MAC地址和IP地址映射不正確,則要繼續(xù)驗(yàn)證,如果驗(yàn)證無法通過,則將此報告給管理人員,類型是攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊;如果MAC地址和IP地址的映射正確,但是與交換機(jī)的連接端口不正確,則需要進(jìn)一步驗(yàn)證;如果找不到該對應(yīng)的表項(xiàng),說明該終端機(jī)未向控制器注冊信息,需要注冊后才能通信。

    當(dāng)MAC地址和IP地址映射不正確時,首先將此次ARP請求的目的IP地址記錄在對應(yīng)的表項(xiàng)預(yù)留處,之后DHCP服務(wù)器請求該MAC地址最新對應(yīng)的IP地址,并修改驗(yàn)證表項(xiàng),然后再與此次ARP 請求報文的IP-MAC映射進(jìn)行比對,如果匹配不成功,則向管理員上報ARP攻擊,類型為攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊,并刪去預(yù)留的IP地址;如果匹配成功,以表項(xiàng)中預(yù)留的IP地址和此IP地址對應(yīng)的MAC地址為源地址向請求終端機(jī)回復(fù)ARP Reply,同時也刪去預(yù)留的IP地址。

    步驟2:查驗(yàn)源MAC地址是否合法。如果可以查到MAC地址對應(yīng)的表項(xiàng),則直接比對交換機(jī)身份ID、MAC地址、IP地址和連接端口等信息即可驗(yàn)證身份。如果MAC地址和IP地址映射正確,但是接入端口不正確時,則隨機(jī)地生成一條信息,并以終端機(jī)對應(yīng)的RSA公鑰對信息進(jìn)行加密,發(fā)送給終端機(jī),此時如果終端機(jī)能回復(fù)正確的消息,則更新終端機(jī)驗(yàn)證信息表中終端機(jī)的位置,并且以表項(xiàng)中預(yù)留的IP地址和此IP地址對應(yīng)的MAC地址為源地址向請求終端機(jī)回復(fù)ARP Reply,并刪去預(yù)留的IP地址;如果源終端機(jī)不能回復(fù)正確的消息,或者等待超時后,直接刪去預(yù)留的IP地址。則向管理人員上報ARP攻擊,類型為攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊。

    步驟3:驗(yàn)證目的終端機(jī)是否離開。當(dāng)終端機(jī)通過驗(yàn)證后,控制器向目標(biāo)終端機(jī)的IP地址發(fā)送一個帶有驗(yàn)證消息的數(shù)據(jù)包,如果目的終端機(jī)能回復(fù)正確的消息,并且接入端口等信息沒有變化,就說明目的終端機(jī)沒有移動;如果目的終端機(jī)能通過驗(yàn)證,但是接入端口等消息已經(jīng)發(fā)送了變化,則修改終端機(jī)驗(yàn)證信息表;如果目的終端機(jī)不能通過驗(yàn)證,說明終端機(jī)已經(jīng)離開,則等待目的終端機(jī)重新注冊。

    2.3 方案的有效性

    (1)對于“攻擊者在網(wǎng)絡(luò)層或鏈路層”的ARP攻擊

    這種ARP攻擊的特性是IP地址和MAC地址的映射關(guān)系一定不真實(shí)。本方案中,如果終端機(jī)要發(fā)送ARP請求數(shù)據(jù)包,必須先在控制器處注冊驗(yàn)證信息。在通信過程中,終端機(jī)發(fā)起ARP請求,控制器接收之后會將ARP數(shù)據(jù)包的源IP地址和MAC地址與注冊時的映射比較,如果映射不正確,則向DHCP服務(wù)器申請最新映射并比較,如果源終端機(jī)無法通過控制器的驗(yàn)證,則被判定為攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊。

    (2)對于“攻擊者同時利用網(wǎng)絡(luò)層和鏈路層”的ARP攻擊

    這種ARP攻擊的特性是ARP數(shù)據(jù)包中的MAC地址與終端機(jī)本身的MAC地址不同。在本方案中,控制器通過交換機(jī)上傳的Packet_in報文中終端機(jī)的連接端口與驗(yàn)證信息表中連接端口比較,然后向源終端機(jī)發(fā)送驗(yàn)證消息,如果其可以通過驗(yàn)證,則更新源終端機(jī)對應(yīng)MAC地址的表項(xiàng),如果沒有通過驗(yàn)證,則被判定為攻擊者,同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊。

    3 核心代碼

    3.1 RSA加密部分

    該部分代碼在控制器安全模塊和終端機(jī)的防御模塊中都需要使用,用于生成屬于自己的公鑰與私鑰,并發(fā)給對方。

    (1)計算最大公約數(shù)

    ∥ 尋找num1、num2的最大公約數(shù)

    ∥ GCD(num1,num2) = GCD(num2,num1 Mod num2)

    Integer:Gcd(Integer:num1, Integer:num2)

    While(num2 != 0)

    ∥計算余數(shù)

    Integer:remainder = num1 Mod num2

    ∥計算GCD(num2,remainder)

    num1 = num2

    num2 = remainder

    End While

    ∥GCD(num1,0)為num1

    Return num1

    End Gcd

    (2)計算大整數(shù)大次冪并對大的整數(shù)取模

    #超大整數(shù)超大次冪然后對超大的整數(shù)取模(bs ^ ept) mod n

    def ep_md(bs, ept, n):

    bin_a = bin(ept)[2:][::-1]

    r = len(bin_a)

    bs_a = []

    pre_bs = bs

    bs_a.append(pre_bs)

    for _ in range (r - 1):

    next_bs = (pre_bs * pre_bs) % n

    bs_a.append(next_bs)

    pre_bs = next_bs

    a_w_b = __multi (bs_a, bin_a)

    return a_w_b % n

    def __multi (a, bin_a):

    result = 1

    for index in range(len(a)):

    a = a[index]

    if not int(bin_a[index]):

    continue

    result *= a

    return result

    在此步驟中,使用到了Montgomery算法,該算法最大作用的是使RSA 2個素數(shù)在數(shù)值特別大時也可以使用,由于Montgomery與本文討論的方向不同,故此處不再詳細(xì)介紹。

    (3)公鑰與私鑰生成

    def cre_key(p, q):

    n=p*q

    #計算與n互質(zhì)的整數(shù)個數(shù) 歐拉函數(shù)

    fi=(p-1)*(q-1)

    #選取e,一般選取65537,此處為示例故取小數(shù)值

    e=13

    a=e

    b=fi

    r, x, y = ext_gcd(a, b)

    #計算出的x不能是負(fù)數(shù),如果是負(fù)數(shù),說明p、q、e選取失敗

    while x<0:

    e=e+1

    if gcd(e, fi) !=1:

    continue

    a=e

    b=fy

    r, x, y = ext_gcd(a, b)

    d=x

    return (n, e), (n, d)

    # 加密,m是明文,c為密文

    def encrypt(m, pub_key):

    n=pub_key[0]

    e=pub_key[1]

    c=ep_md(m, e, n)

    return c

    # 解密,c是密文,m是明文

    def decrypt(c, self_key):

    n=self_key[0]

    d=self_key[1]

    m=ep_md(c, d, n)

    return m

    3.2 控制器安全模塊

    控制器部分的安全模塊就是本文所提的方案,終端機(jī)在進(jìn)入網(wǎng)絡(luò)獲得IP地址之后,就向控制器注冊信息,包括IP地址、MAC地址、終端機(jī)接入端口和以自己特征值生成的RSA公鑰,控制器為每個終端機(jī)維護(hù)這一表項(xiàng)。當(dāng)有終端機(jī)發(fā)起ARP請求時,交換機(jī)轉(zhuǎn)發(fā)給控制器,控制器比對表項(xiàng),如果IP地址和MAC地址映射不正確,或者IP地址和MAC地址映射正確但終端機(jī)接入端口號不正確,則需要驗(yàn)證,驗(yàn)證通過就代替目標(biāo)終端機(jī)回復(fù)ARP應(yīng)答報文,驗(yàn)證不通過就向管理員報告ARP攻擊。而驗(yàn)證不通過時,如果是IP地址與MAC地址不匹配,則為攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊,如果IP地址與MAC地址匹配,但是與接入接口不匹配,則為攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊。

    (1)原POX控制器數(shù)據(jù)包處理代碼

    該部分為原POX控制器處理數(shù)據(jù)包過程,主要是創(chuàng)建數(shù)據(jù)包對象,過濾掉無法解析的數(shù)據(jù)包和鏈路層發(fā)現(xiàn)協(xié)議數(shù)據(jù)包,并且當(dāng)交換機(jī)的dpid不在ARP表中,將該減緩及匹配的虛擬網(wǎng)關(guān)加入ARP表中。

    def _handle_openflow_PacketIn(self,event):

    1)創(chuàng)建數(shù)據(jù)包對象,

    dpid=event.connection.dpid

    inport=event.port

    packet=event.parsed

    2)過濾無法解析的數(shù)據(jù)包,

    if not packet.parsed:

    log.warning("%i %i ignoring unparsed packet", dpid, inport)

    return

    3)如果交換機(jī)的dpid不在ARP表中,則為該交換機(jī)創(chuàng)建一個ARP表項(xiàng),并將交換機(jī)匹配的虛擬網(wǎng)關(guān)加入ARP表中,

    if dpid not in self.arpTable:

    self.arpTable[dpid]={}

    for fake in self.fakeways:

    self.arpTable[dpid][IPAddr(fake)]=Entry(of.OFPP_NONE,dpid_to_mac(dpid))

    4)過濾LLDP報文,

    if packet.type == ethernet.LLDP_TYPE:

    Return

    (2)原POX控制器處理IPv4數(shù)據(jù)包

    if isinstance(packet.next, ipv4):

    log.debug("%i %i IP %s => %s", dpid, inport,packet.next.srcip, packet.next.dstip)

    #嘗試將緩沖區(qū)等待的數(shù)據(jù)包發(fā)出去

    self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

    1)如果包源IP在ARP表中,學(xué)習(xí)或者更新端口或MAC表項(xiàng),并且過濾ARP表項(xiàng)的入端口和包源地址不匹配的情況,

    if packet.next.srcip in self.arpTable[dpid]:

    if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):

    #向管理員報arp攻擊

    print 'there is a arp attrack'

    2)如果包源IP不在arp表中,對應(yīng)包dpid和包源地址的條例創(chuàng)建為此包的匹配項(xiàng)目,

    else:

    log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)

    self.arpTable[dpid][packet.next.srcip]=Entry(inport, packet.src)

    #嘗試轉(zhuǎn)發(fā),取包的目的地址

    dstaddr=packet.next.dstip

    3)如果目的地址在ARP表中,有端口信息并將消息發(fā)出,

    if dstaddr in self.arpTable[dpid]:

    #取表中目的交換機(jī)和目的地址對應(yīng)的端口

    prt=self.arpTable[dpid][dstaddr].port

    #取表中目的交換機(jī)和目的地址對應(yīng)的地址

    mac=self. arpTable[dpid][dstaddr].mac

    #排除出端口等于入端口的情況

    if prt == inport:

    log.warning("%i %i not sending packet for %s back out of the ""input port" % (dpid, inport, dstaddr))

    else:

    log.debug("%i %i installing flow for %s => %s out port %i"% (dpid, inport, packet.next.srcip, dstaddr, prt))

    #建立行為列表

    actions=[]

    #添加動作,為設(shè)置目的MAC地址

    actions.append(of.ofp_action_dl_addr. set_dst(mac))

    #添加動作,為交換機(jī)發(fā)消息的出端口為ARP表中目的交換機(jī)的端口

    actions.append(of.ofp_action_output (port=prt))

    if self.wide:#如果為廣泛匹配

    match=of.ofp_match(dl_type=packet.type, nw_dst=dstaddr)

    else:

    match=of.ofp_match.from_packet(packet, inport)

    #添加新的流表項(xiàng)

    msg=of.ofp_flow_mod(command =of.OFPFC_ADD,

    #在FLOW_IDLE_TIMEOUT時間內(nèi),如果沒有報文觸發(fā),則該規(guī)則刪除

    idle_timeout=FLOW_IDLE_TIMEOUT,

    #到達(dá)OFP_FLOW_PERMANENT時間時,無論如何都刪除該規(guī)則

    hard_timeout= of.OFP_FLOW_PERMANENT,

    #設(shè)計數(shù)據(jù)包存儲在數(shù)據(jù)路徑中的緩沖區(qū)的ID

    buffer_id=event.ofp.buffer_id,

    actions=actions,

    match=match)

    event.connection.send(msg.pack())

    4)當(dāng)目的地址不在ARP表中的情況,

    elif self.arp_for_unknowns:

    #如果交換機(jī)的dpid和目的地址不在緩沖區(qū)內(nèi),創(chuàng)建該交換機(jī)的表項(xiàng)

    if (dpid, dstaddr) not in self.lost_buffers:

    self.lost_buffers[(dpid, dstaddr)]=[]

    #取緩沖區(qū)的表項(xiàng)

    bucket=self.lost_buffers[(dpid,dstaddr)]

    #建立條例,當(dāng)前的時間,條例最大存在時間,數(shù)據(jù)包存儲在數(shù)據(jù)路徑中的緩沖區(qū)的ID,入端口

    entry=(time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport)

    bucket.append(entry)

    #如果bucket項(xiàng)目的長度大于交換機(jī)上用于未知ip的最大數(shù)據(jù)包數(shù)

    while len(bucket) > MAX_BUFFERED_PER_IP: del bucket [0]

    # Expire things from our outstanding ARP list...

    self.outstanding_arps={k: v for k, v in self.outstanding_arps.iteritems() if v > time.time()}

    if (dpid, dstaddr) in self.outstanding_arps:

    return

    # 目的地址表項(xiàng)過期時間為4 s,不再接收

    self.outstanding_arps[(dpid, dstaddr)]=time.time() + 4

    #構(gòu)建一個ARP消息

    r=arp()

    #ARP消息類型為以太網(wǎng)

    r.hwtype=r.HW_TYPE_ETHERNET

    #報文proto類型為IP

    r.prototype=r.PROTO_TYPE_IP

    r.hwlen=6

    r.protolen=r.protolen

    r.opcode=r.REQUEST

    r.hwdst=ETHER_BROADCAST

    #協(xié)議目的為目標(biāo)地址

    r.protodst=dstaddr

    #源地址是請求包的地址

    r.hwsrc=packet.src

    #協(xié)議源是請求包源IP

    r.protosrc=packet.next.srcip

    r.payload='1111'

    e=ethernet (type=ethernet.ARP_TYPE, src= packet.src,dst=ETHER_BROADCAST)

    #將ARP消息封裝在鏈路層協(xié)議中

    e.set_payload(r)

    log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,r.protodst, r.protosrc))

    #指示交換機(jī)發(fā)送數(shù)據(jù)包

    msg=of.ofp_packet_out()

    #將e封裝在msg的數(shù)據(jù)域中

    msg.data=e.pack()

    msg.actions.append (of.ofp_action_output(port=of.OFPP_FLOOD))

    msg.in_port=inport

    event.connection.send(msg)

    (3)處理ARP數(shù)據(jù)包的ARP防御模塊

    elif isinstance(packet.next, arp):

    1)創(chuàng)建一個ARP數(shù)據(jù)包對象,并過濾一些數(shù)據(jù)包,

    a=packet.next

    log.debug("%i %i ARP %s %s => %s", dpid, inport,{arp.REQUEST: "request", arp.REPLY: "reply"}.get(a.opcode,'op:%i' % (a.opcode,)), a.protosrc, a.protodst)

    #過濾出ARP數(shù)據(jù)包

    if a.prototype == arp.PROTO_TYPE_IP:

    #如果是鏈路層協(xié)議

    if a.hwtype == arp.HW_TYPE_ETHERNET:

    #并且包的協(xié)議源地址不為0.0.0.0

    if a.protosrc != 0:

    #過濾目的地址為控制器本身的數(shù)據(jù)包

    if a.protodst == '10.168.1.1':

    2)當(dāng)ARP數(shù)據(jù)包為密鑰交換數(shù)據(jù)包時,為終端機(jī)分發(fā)私鑰并記錄終端機(jī)的公鑰,

    if a.payload != '':

    if '(' in str(a.payload):

    #為該終端機(jī)生成密鑰

    pubkey, selfkey=gen_key(p, q)

    self.macTable[packet.src]={}

    #將a負(fù)載域中的密鑰記錄在對應(yīng)的表項(xiàng)中

    self.macTable[packet.src]['host_pubkey']=a.payload

    #將生成的密鑰加入到a對應(yīng)的表項(xiàng)中

    self.macTable[packet.src] ['controller_prakey']=selfkey

    r=arp()

    r.hwtype=a.hwtype

    r.prototype=a.prototype

    r.hwlen=a.hwlen

    r.protolen=a.protolen

    r.opcode=arp.REPLY

    r.hwdst=a.hwsrc

    r.protodst=a.protosrc

    r.protosrc=a.protodst

    r.payload=str(pubkey)

    r.hwsrc=a.hwdst

    e=ethernet (type=packet.type, src= dpid_to_mac(dpid),dst=a.hwsrc)

    e.set_payload(r)

    log.debug("%i %i answering ARP for %s" % (dpid, inport,r.protosrc))

    msg=of.ofp_packet_out()

    msg.data=e.pack()

    msg.actions.append (of.ofp_action_output(port=of.OFPP_IN_PORT))

    msg.in_port=inport

    event.connection.send(msg)

    return

    3)當(dāng)ARP數(shù)據(jù)包為驗(yàn)證信息數(shù)據(jù)包時,用終端機(jī)的公鑰解密,并比對控制器本身生成的驗(yàn)證信息,

    else:

    recheck_prakey=self.macTable [packet.src]['controller_praker']

    recheck_msg=a.payload

    #用a的公鑰解密

    recheck_num=decrypt (recheck_msg, recheck_prakey)

    #比對解密后的信息與自己分發(fā)的信息

    if recheck_num == self.macTable [packet.src]['check_num']:

    self.arpTable[dpid][a.protosrc].port=inport

    if self.macTable[packet.src] ['request_ipaddr'] in self.arpTable[dpid]:

    # We have an answer...

    # if not self.arpTable[dpid] [a.protodst].isExpired():

    r=arp()

    r.hwtype=a.hwtype

    r.prototype=a.prototype

    r.hwlen=a.hwlen

    r.protolen=a.protolen

    r.opcode=arp.REPLY

    r.hwdst=a.hwsrc

    r.protodst=a.protosrc

    r.protosrc=self.macTable[packet.src]['request_ipaddr']

    r.hwsrc=self.macTable[packet.src]['request_macaddr']

    e=ethernet (type=packet.type, src=dpid_to_mac(dpid),dst=a.hwsrc)

    e.set_payload(r)

    log.debug("%i %i answering ARP for %s" % (dpid, inport,r.protosrc))

    msg=of.ofp_packet_out()

    msg.data=e.pack()

    msg.actions.append (of.ofp_action_output(port=of.OFPP_IN_PORT))

    msg.in_port=inport.connection.send(msg)

    return

    else:

    #上報管理員發(fā)生網(wǎng)絡(luò)層和鏈路層的攻擊

    print 'there is a arp attrack which steal and or mac'

    return

    else:

    return

    4)如果終端機(jī)的協(xié)議IP地址存在于主機(jī)驗(yàn)證表項(xiàng),則比對與MAC地址和接入端口的對應(yīng)關(guān)系,判斷是否發(fā)生ARP攻擊,

    if a.protosrc in self.arpTable[dpid]:

    #a的IP地址與MAC地址不對應(yīng),則上報管理員有網(wǎng)絡(luò)層或鏈路層的ARP攻擊

    if self.arpTable[dpid][a.protosrc].mac != packet.src:

    #上報管理員發(fā)生網(wǎng)絡(luò)層或鏈路層的攻擊

    print 'there is a arp attrack which only steal ip or mac'

    return

    else:

    #如果a的IP地址和MAC地址都與驗(yàn)證表中相同,但輸入端口不相同

    if self.arpTable[dpid][a.protosrc].port != inport:

    self.macTable[packet.src] ['request_ipaddr']=a.protodst

    self.macTable[packet.src]['request_macaddr']=packet.src

    check_pubkey=self.macTable[packet.src]['host_pubkey']

    check_num=random.randint(0, 300)

    check_msg=encrypt(check_num, check_pubkey)

    self.macTable[packet.src]['check_num']=str(check_msg)

    r=arp()

    r.hwtype=a.hwtype

    r.prototype=a.prototype

    r.hwlen=a.hwlen

    r.protolen=a.protolen

    r.opcode=arp.REPLY

    r.hwdst=a.hwsrc

    r.protodst=a.protosrc

    r.protosrc=a.protodst

    r.payload=str(check_msg)

    r.hwsrc=self.arpTable[dpid][a.protodst].mac

    e=ethernet(type=packet.type, src=dpid_to_mac(dpid),dst=a.hwsrc)

    e.set_payload(r)

    log.debug("%i %i answering ARP for %s" % (dpid, inport,r.protosrc))

    msg=of.ofp_packet_out()

    msg.data=e.pack()

    msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))

    msg.in_port=inport

    event.connection.send(msg)

    #上報管理員發(fā)生網(wǎng)絡(luò)層和鏈路層的攻擊

    print 'there is a arp attrack which steal and or mac'

    return

    else:

    log.debug("%i %i learned %s", dpid, inport, a.protosrc)

    self.arpTable[dpid][a.protosrc]=Entry(inport, packet.src)

    self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

    if a.protosrc in self.arpTable[dpid]:

    5)如果終端機(jī)身份驗(yàn)證成功,則正?;貜?fù)ARP數(shù)據(jù)包,

    if self.arpTable[dpid][a.protosrc] == (inport, packet.src):

    if a.opcode == arp.REQUEST:

    # Maybe we can answer

    if a.protodst in self.arpTable[dpid]:

    if not self.arpTable[dpid] [a.protodst].isExpired():

    r=arp()

    r.hwtype=a.hwtype

    r.prototype=a.prototype

    r.hwlen=a.hwlen

    r.protolen=a.protolen

    r.opcode=arp.REPLY

    r.hwdst=a.hwsrc

    r.protodst=a.protosrc

    r.protosrc=a.protodst

    r.payload='111111'

    r.hwsrc=self.arpTable[dpid][a.protodst].mac

    e=ethernet(type=packet.type, src= dpid_to_mac(dpid),dst=a.hwsrc)

    e.set_payload(r)

    log.debug("%i %i answering ARP for %s" % (dpid, inport,r.protosrc))

    msg=of.ofp_packet_out()

    msg.data=e.pack()

    msg.actions.append (of.ofp_action_output(port=of.OFPP_IN_PORT))

    msg.in_port=inport

    event.connection.send(msg)

    return

    log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,{arp.REQUEST: "request", arp.REPLY: "reply"}.get(a.opcode,'op:%i' % (a.opcode,)),a.protosrc, a.protodst))

    msg=of.ofp_packet_out(in_port=inport, data=event.ofp,action=of.ofp_action_output(port=of.OFPP_FLOOD))

    event.connection.send(msg)

    3.3 終端機(jī)安全模塊

    終端機(jī)安全模塊主要包括RSA加密部分和以下用于信息驗(yàn)證部分,信息驗(yàn)證部分包括了ARP嗅探,建立與控制器匹配的密鑰表項(xiàng)和發(fā)送驗(yàn)證ARP數(shù)據(jù)包。

    f_arp_msg=sniff(filter='ARP')

    if f_arp_msg.load is not None:

    if '(' in f_arp_msg.load:

    macTable['mac']=f_arp_msg.hwsrc

    macTable['mac']['pubkey']=f_arp_msg.load

    else:

    pkt_hwsrc=f_arp_msg.hwsrc

    pkt_psrc=f_arp_msg.psrc

    check_msg=random.randint(0,300)

    check_pubkey=macTable ['mac']['pubkey']

    check_im=encrypt (check_msg,check_pubkey)

    4 方案示例與測試

    4.1 測試環(huán)境

    實(shí)驗(yàn)的仿真模擬環(huán)境中,需要一臺虛擬機(jī),具體配置如下:

    (1)操作系統(tǒng)為Linux Ubuntu14.04 LTS或者更高版本;

    (2)CPU英特爾i7處理器,主頻2.5 GHz;

    (3)內(nèi)存2GB或者更高配置;

    (4)運(yùn)行SDN控制器的網(wǎng)絡(luò)模擬平臺。

    其中,SDN控制器選用POX 0.5.0開源控制器,使用Open vSwitch交換機(jī),虛擬網(wǎng)絡(luò)運(yùn)用Mininet 2.3.0網(wǎng)絡(luò)仿真平臺構(gòu)建,南向接口協(xié)議使用OpenFlow v1.0協(xié)議,使用Wireshark 2.6.6作為流量分析工具,其次使用Scapy 2.4.3[36]作為ARP攻擊的手段,編程語言為Python 2.7。

    4.2 實(shí)驗(yàn)過程

    實(shí)驗(yàn)建立如圖6的網(wǎng)絡(luò)拓?fù)?。首先啟動POX控制器,如圖7,然后執(zhí)行mn命令創(chuàng)建一個簡單的網(wǎng)絡(luò)拓?fù)?如圖8,控制器指定為POX,使用Open vSwitch作為交換機(jī)。

    圖6 本實(shí)驗(yàn)網(wǎng)絡(luò)拓?fù)銯ig.6 Network topology of this experiment

    圖7 啟動pox控制器Fig.7 Start pox controller

    圖8 建立網(wǎng)絡(luò)拓?fù)銯ig.8 Establish network topology

    假設(shè)圖6中H1S2為攻擊者,對H2S2發(fā)起攻擊,攻擊的類型分為2種:①針對網(wǎng)絡(luò)層或鏈路層的ARP攻擊;②針對網(wǎng)絡(luò)層和鏈路層的ARP攻擊。

    (1)攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊

    攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP欺騙程序代碼如圖9,欺騙程序先盜用 H1S1 的IP地址,同時每間隔3 s向終端機(jī)H2S2發(fā)送 ARP 請求報文。首先觀察沒有使用方案之前該網(wǎng)絡(luò)遭受此類 ARP 攻擊的情況。終端機(jī) H1S2 發(fā)起攻擊之后,交換機(jī) S2 由于沒有對應(yīng)的流表項(xiàng),于是把消息封裝成 Packet_in消息,上傳給控制器,此時控制器已經(jīng)受到了欺騙,控制器將該數(shù)據(jù)包的相關(guān)信息記錄后,指示交換機(jī) S2 將其洪泛,于是終端機(jī) H2S2 接收到了終端機(jī) H1S2 的數(shù)據(jù)包,同時修改自身的 ARP 緩存(圖10),并進(jìn)行回復(fù),交換機(jī)S2 又因?yàn)闆]有找到對應(yīng)流表項(xiàng),于是上報控制器,控制器記錄該數(shù)據(jù)包的信息后,向 S2 下發(fā)流規(guī)則,指示 S2 將該數(shù)據(jù)包轉(zhuǎn)發(fā)給終端機(jī) H1S2。之后終端機(jī) H2S2 再與H1S1通信,終端機(jī) H2S2 對H1S1發(fā)出的數(shù)據(jù)包都會發(fā)送給終端機(jī) H1S2,所以ARP攻擊完成。

    圖9 攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP欺騙程序代碼

    使用方案之后,4臺終端機(jī)都向控制器注冊信息,密鑰交換的過程是終端機(jī)向控制器發(fā)送自己的公鑰,同時控制器向終端機(jī)發(fā)送自己的公鑰,如圖11和圖12。此時終端機(jī)H1S2再發(fā)起ARP攻擊時,交換機(jī)S2因?yàn)闆]有流,將該數(shù)據(jù)包上報控制器,控制器比對終端機(jī)驗(yàn)證信息之后,發(fā)現(xiàn)映射不正確,于是向管理員報告ARP攻擊的錯誤。并且這個時候終端機(jī)H1S1與終端機(jī)H2S2為正常通信,具體攻擊結(jié)果如圖13所示。使用方案之后終端機(jī)H2S2與終端機(jī)H1S1通信結(jié)果如圖14所示。

    圖11 終端機(jī)向控制器發(fā)送自己的公鑰Fig.11 The terminal sends its own public key to the controller

    圖12 控制器向終端機(jī)發(fā)送自己的公鑰Fig.12 The controller sends its own public key to the terminal

    圖13 攻擊者在網(wǎng)絡(luò)層或鏈路層的ARP攻擊結(jié)果

    (2)攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊

    攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊程序代碼如圖15所示。4臺終端機(jī)都向控制器注冊了信息,當(dāng)終端機(jī)H1S2開啟攻擊程序之后,向網(wǎng)絡(luò)中傳輸ARP欺騙包,S2在收到欺騙數(shù)據(jù)包后,由于找不到對應(yīng)的流表項(xiàng),于是封裝消息后,將消息數(shù)據(jù)包發(fā)送到控制器,控制器比對驗(yàn)證信息表之后,發(fā)現(xiàn)IP、MAC地址與輸入端口的映射與表項(xiàng)中的信息不同,于是向終端機(jī)H1S2發(fā)送驗(yàn)證信息,因?yàn)榻K端機(jī)H1S2無法回答正確的消息,控制器將向管理員上報系統(tǒng)發(fā)生了ARP攻擊,攻擊類型是攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊,攻擊結(jié)果如圖16所示。

    圖14 使用方案之后終端機(jī)H2S2與終端機(jī)H1S1通信

    圖15 攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊代碼

    圖16 攻擊者同時利用網(wǎng)絡(luò)層和鏈路層的ARP攻擊結(jié)果

    5 結(jié)束語

    文章分析了現(xiàn)有網(wǎng)絡(luò)架構(gòu)存在的問題,概括了軟件定義網(wǎng)絡(luò)所具有的特點(diǎn),在分析了SDN架構(gòu)下ARP攻擊原理和形式之后,提出了解決SDN架構(gòu)下ARP攻擊的方案。但是本文所提方案驗(yàn)證中終端機(jī)驗(yàn)證信息表比較大,在控制器中占用的空間也比較大,而且在終端機(jī)下線之后也必須維持這樣的表項(xiàng),當(dāng)接入的終端機(jī)變多的時候控制器的存儲空間會變得緊缺,因此,在以后的方案改進(jìn)中可以考慮更小的表項(xiàng),并且能動態(tài)地存儲表項(xiàng)。還有驗(yàn)證IP地址與MAC地址映射時使用了DHCP服務(wù)器,而控制器與DHCP服務(wù)器之間的通信安全沒有保障,這是下一步的完善方向。

    猜你喜歡
    終端機(jī)鏈路層表項(xiàng)
    網(wǎng)絡(luò)傳輸融合及網(wǎng)絡(luò)安全防控技術(shù)研究
    一種改進(jìn)的TCAM路由表項(xiàng)管理算法及實(shí)現(xiàn)
    基于多空間內(nèi)存共享的數(shù)據(jù)鏈路層網(wǎng)絡(luò)包捕獲方法
    基于ARMA模型預(yù)測的交換機(jī)流表更新算法
    重慶ETC手持終端機(jī)方案探討
    SDN數(shù)據(jù)中心網(wǎng)絡(luò)基于流表項(xiàng)轉(zhuǎn)換的流表調(diào)度優(yōu)化
    冷軋機(jī)操作站終端機(jī)的改造性修復(fù)
    數(shù)據(jù)鏈路層的選擇重傳協(xié)議的優(yōu)化改進(jìn)
    國家水資源監(jiān)控能力建設(shè)項(xiàng)目在線數(shù)據(jù)采集傳輸接收設(shè)備規(guī)約符合性測試結(jié)果發(fā)布
    中國水利(2014年9期)2014-07-25 03:57:48
    IEEE 1394事務(wù)層接口的設(shè)計與實(shí)現(xiàn)
    象州县| 莱州市| 河间市| 河曲县| 高青县| 浦北县| 湟源县| 阳朔县| 府谷县| 平昌县| 太保市| 彰武县| 淮北市| 咸宁市| 永顺县| 桃源县| 长沙市| 汨罗市| 大理市| 阜康市| 萨嘎县| 腾冲县| 营山县| 东兰县| 汉寿县| 清徐县| 个旧市| 十堰市| 新巴尔虎右旗| 涡阳县| 乐东| 宜宾县| 繁昌县| 东光县| 息烽县| 易门县| 徐水县| 二手房| 革吉县| 湖口县| 桐城市|