亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        SDN架構下ARP攻擊的解決方案及示例

        2022-01-19 12:10:22徐大偉祝烈煌厙怡婕
        廣州大學學報(自然科學版) 2021年4期
        關鍵詞:終端機鏈路層表項

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

        (1. 北京理工大學 網絡空間安全學院, 北京 100081; 2. 長春大學 網絡安全學院, 吉林 長春 130022)

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

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

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

        1 SDN架構與ARP欺騙

        1.1 SDN架構

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

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

        SDN架構按層次結構劃分,如圖1所示,包含5個層次,即應用程序層、北向接口層、控制層、南向接口層和數(shù)據(jù)層[15-16]。

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

        圖1 SDN架構層次[1]Fig.1 SDN architecture levels

        1.2 OpenFlow協(xié)議

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

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

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

        1.3 SDN架構下的ARP攻擊形式

        (1)攻擊者在網絡層或鏈路層的ARP攻擊

        攻擊者在TCP/IP的網絡層面,竊取合法用戶的終端機的IP地址或者MAC地址[24],使其他終端機和控制層面錯誤地將攻擊者的IP地址誤判為對應合法終端機的MAC地址,或者錯誤地將攻擊者的MAC地址誤認為對應的合法終端機的IP地址[27-28]。

        (2)攻擊者同時利用網絡層和鏈路層的ARP攻擊

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

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

        2 方案設計

        2.1 方案設計思路

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

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

        總之,本方案中,需要每個終端機向控制器注冊信息,而控制器代替目標機回復ARP請求,并且只有通過驗證的ARP請求才能收到回復。

        2.2 詳細方案

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

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

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

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

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

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

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

        圖5 終端機驗證信息表項Fig.5 Terminal verification information table entry

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

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

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

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

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

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

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

        2.3 方案的有效性

        (1)對于“攻擊者在網絡層或鏈路層”的ARP攻擊

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

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

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

        3 核心代碼

        3.1 RSA加密部分

        該部分代碼在控制器安全模塊和終端機的防御模塊中都需要使用,用于生成屬于自己的公鑰與私鑰,并發(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與本文討論的方向不同,故此處不再詳細介紹。

        (3)公鑰與私鑰生成

        def cre_key(p, q):

        n=p*q

        #計算與n互質的整數(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不能是負數(shù),如果是負數(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 控制器安全模塊

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

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

        該部分為原POX控制器處理數(shù)據(jù)包過程,主要是創(chuàng)建數(shù)據(jù)包對象,過濾掉無法解析的數(shù)據(jù)包和鏈路層發(fā)現(xiàn)協(xié)議數(shù)據(jù)包,并且當交換機的dpid不在ARP表中,將該減緩及匹配的虛擬網關加入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)如果交換機的dpid不在ARP表中,則為該交換機創(chuàng)建一個ARP表項,并將交換機匹配的虛擬網關加入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表中,學習或者更新端口或MAC表項,并且過濾ARP表項的入端口和包源地址不匹配的情況,

        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表中,對應包dpid和包源地址的條例創(chuàng)建為此包的匹配項目,

        else:

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

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

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

        dstaddr=packet.next.dstip

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

        if dstaddr in self.arpTable[dpid]:

        #取表中目的交換機和目的地址對應的端口

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

        #取表中目的交換機和目的地址對應的地址

        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=[]

        #添加動作,為設置目的MAC地址

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

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

        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)

        #添加新的流表項

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

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

        idle_timeout=FLOW_IDLE_TIMEOUT,

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

        hard_timeout= of.OFP_FLOW_PERMANENT,

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

        buffer_id=event.ofp.buffer_id,

        actions=actions,

        match=match)

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

        4)當目的地址不在ARP表中的情況,

        elif self.arp_for_unknowns:

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

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

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

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

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

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

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

        bucket.append(entry)

        #如果bucket項目的長度大于交換機上用于未知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

        # 目的地址表項過期時間為4 s,不再接收

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

        #構建一個ARP消息

        r=arp()

        #ARP消息類型為以太網

        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é)議目的為目標地址

        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))

        #指示交換機發(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)當ARP數(shù)據(jù)包為密鑰交換數(shù)據(jù)包時,為終端機分發(fā)私鑰并記錄終端機的公鑰,

        if a.payload != '':

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

        #為該終端機生成密鑰

        pubkey, selfkey=gen_key(p, q)

        self.macTable[packet.src]={}

        #將a負載域中的密鑰記錄在對應的表項中

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

        #將生成的密鑰加入到a對應的表項中

        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)當ARP數(shù)據(jù)包為驗證信息數(shù)據(jù)包時,用終端機的公鑰解密,并比對控制器本身生成的驗證信息,

        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ā)生網絡層和鏈路層的攻擊

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

        return

        else:

        return

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

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

        #a的IP地址與MAC地址不對應,則上報管理員有網絡層或鏈路層的ARP攻擊

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

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

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

        return

        else:

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

        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ā)生網絡層和鏈路層的攻擊

        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)如果終端機身份驗證成功,則正?;貜虯RP數(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 終端機安全模塊

        終端機安全模塊主要包括RSA加密部分和以下用于信息驗證部分,信息驗證部分包括了ARP嗅探,建立與控制器匹配的密鑰表項和發(fā)送驗證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)境

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

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

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

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

        (4)運行SDN控制器的網絡模擬平臺。

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

        4.2 實驗過程

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

        圖6 本實驗網絡拓撲Fig.6 Network topology of this experiment

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

        圖8 建立網絡拓撲Fig.8 Establish network topology

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

        (1)攻擊者在網絡層或鏈路層的ARP攻擊

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

        圖9 攻擊者在網絡層或鏈路層的ARP欺騙程序代碼

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

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

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

        圖13 攻擊者在網絡層或鏈路層的ARP攻擊結果

        (2)攻擊者同時利用網絡層和鏈路層的ARP攻擊

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

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

        圖15 攻擊者同時利用網絡層和鏈路層的ARP攻擊代碼

        圖16 攻擊者同時利用網絡層和鏈路層的ARP攻擊結果

        5 結束語

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

        猜你喜歡
        終端機鏈路層表項
        網絡傳輸融合及網絡安全防控技術研究
        一種改進的TCAM路由表項管理算法及實現(xiàn)
        通信技術(2022年5期)2022-06-11 00:47:44
        基于多空間內存共享的數(shù)據(jù)鏈路層網絡包捕獲方法
        基于ARMA模型預測的交換機流表更新算法
        重慶ETC手持終端機方案探討
        SDN數(shù)據(jù)中心網絡基于流表項轉換的流表調度優(yōu)化
        冷軋機操作站終端機的改造性修復
        數(shù)據(jù)鏈路層的選擇重傳協(xié)議的優(yōu)化改進
        國家水資源監(jiān)控能力建設項目在線數(shù)據(jù)采集傳輸接收設備規(guī)約符合性測試結果發(fā)布
        中國水利(2014年9期)2014-07-25 03:57:48
        IEEE 1394事務層接口的設計與實現(xiàn)
        91免费在线| 亚洲人成网网址在线看| 国产激情久久久久影院老熟女免费| 亚洲网站地址一地址二| 欧美国产伦久久久久久久| 国产成人精品一区二区三区av| 成人a级视频在线播放| 久久亚洲中文字幕无码| 亚洲欧洲国无码| 中文字幕av素人专区| 白丝爆浆18禁一区二区三区| 国产熟妇搡bbbb搡bb七区| 噜噜噜色97| 99久久婷婷国产一区| 蜜臀av午夜一区二区三区| 亚洲国产精品一区二区久| 久久人妻少妇中文字幕| 日韩在线精品视频一区| 欧美俄罗斯40老熟妇| 亚洲精品美女久久久久久久| 久久熟女精品—区二区蜜臀| 偷拍综合在线视频二区| 国产亚洲av无码专区a∨麻豆| 依依成人影视国产精品| 96中文字幕一区二区 | 欧美人与禽2o2o性论交| 国产av影片麻豆精品传媒| 一本大道久久精品一本大道久久| 国产精品一区二区av不卡| 天天色影网| 香蕉视频免费在线| 日韩av天堂综合网久久| 免费欧洲毛片a级视频老妇女| 99久久夜色精品国产网站| 亚洲日本在线中文字幕| 国产自拍视频在线观看网站| 日本少妇被黑人xxxxx| 亚洲AV乱码毛片在线播放| 亚洲sm另类一区二区三区| 夜鲁很鲁在线视频| 国产精品国产三级国产专播|