• 
    

    
    

      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)
      保康县| 华阴市| 嘉善县| 东乌珠穆沁旗| 云南省| 石景山区| 锡林浩特市| 永福县| 微博| 百色市| 自贡市| 白河县| 华坪县| 广州市| 会宁县| 永城市| 政和县| 济源市| 胶州市| 凤阳县| 舟山市| 衡阳县| 富锦市| 永州市| 厦门市| 台中县| 威海市| 嘉定区| 托里县| 桓仁| 安远县| 岳普湖县| 屯门区| 长岛县| 临夏县| 双牌县| 胶南市| 嫩江县| 三江| 尚义县| 朝阳区|