1. 程式人生 > >openflow流表項中有關ip掩碼的匹配的問題(控制器為ryu)

openflow流表項中有關ip掩碼的匹配的問題(控制器為ryu)

一.寫在前面

  唉,被分配到sdn安全方向,頂不住,頂不住,感覺搞不出來什麼有搞頭的東西。可若是讓我水水的應付,我想我也是做不到的,世上無難事只怕有心人。好了,進入正題,本次要討論的時一個比較細節的東西,在流表項中的有關ip掩碼的問題。對了,本文適合於,有一定基礎的openflow使用者,一點點就行。

二、問題描述

  若不是機緣巧合,我甚至完全不會注意到這個問題,為什麼,咱來看一個平時實驗環境中最為常見的流表項長啥樣,如圖1

  

                                                           圖1 常見的流表項

  當我剛開始學習openflow的時候,我看到的就是這樣的流表項,當時我一度以為“喔,這和路由表中的表項是不同的,連掩碼都沒有,sdn是新型網路的架構設計,應該拋棄了原來的網路架構,可能連掩碼都不用使用了”。其實稍微深入想一想就可以發現這個想法根本佔不住腳,從實際運用的角度,現在ip網根深蒂固,sdn若想要商業化,必須是要以融入ip網為前提,那麼就肯定要考慮在傳統網路中具有重大作用的ip掩碼了,其次流表項裡都有ip地址了,怎麼可能不去考慮ip掩碼的問題,若不考慮,跨網段通訊如何解決?

  直到我在學習ryu防火牆的時候,這個問題的再次出現,才讓我恍然大悟,也順理成章的解決了它。現在來看一下在ryu的防火牆應用中看到的流表項,如圖2:

  

 

                                                         圖2 ryuf防火牆中的流表

  有沒有覺得流表中的ip地址有些奇怪,對,確實挺奇怪的,但真正奇怪的點在於,這條流表項的產生使用的curl命令為:curl -X POST -d ’{“nw_src”:"10.0.0.1/8","nw_dst:"10.0.0.2/8"}‘ http://localhost:8080/firewall/rules/0000000000000001。沒錯,你沒有看錯curl命令中的10.0.0.1/8到達流表項後變為10.0.0.0/8了。先別急這考慮為什麼,咱再做個實驗,這次curl 的命令為curl -X POST -d curl -X POST -d ’{“nw_src”:"10.0.0.1/32","nw_dst:"10.0.0.2/32"}‘ http://localhost:8080/firewall/rules/0000000000000001,這個curl也是ryu官方文件中的樣例,實驗後流表項為圖3

  

 

 

                 圖3 ryuf防火牆中的流表

 

  圖3中的流表項和curl中表達的一致,等等圖3中的流表項是不是在哪見過?對,和最開始圖1中的一樣,接下來我們開始根據這三張圖的內容進行分析

 

三、猜想與實驗論證

 

  首先圖3中的實驗,我們使用的掩碼是32位的,我是從未見過有32位的掩碼,所以從這點可以看出這裡的掩碼與我們常見的路由表中的掩碼肯定在概念上是有不同。其次我們再來看這個流表的效果,圖1、3可以匹配的僅為源ip為10.0.0.1,目的ip為10.0.0.2的ip,而圖2可以匹配的為10.0.0.0整個網段的主機,再考慮這是防火牆的應用,肯定是既需要同時考慮整個網段也需要考慮單獨的主機。現在再來看看圖2的流表是怎麼得到的,curl中寫的是10.0.0.1/8 再流表中變為10.0.0.0/8,是不是很像10.0.0.1與255.0.0.0想與得到的結果?

 

      對,就是這樣的,通過檢視ryu的原始碼發現,就是將你所輸入的ip原始碼和掩碼做了與操作。在資料包到達ovs之後也是先與掩碼做與操作,再和ip匹配。因此如果在防火牆應用階段如果你想表達整個網段的的ip地址,就是用低於32的掩碼即可,也就是說照常用,如果你僅僅只想表達兩個主機間的禁止或允許,有兩種表達方式,分別就是圖1和圖3,圖1中是在curl中寫的“10.0.0.1”,沒有寫掩碼的位數,圖3中是在curl中寫的“10.0.0.1/32”,寫的32位掩碼,32位的掩碼與任何ip與的結果都是其本身。

 

  能讀到這的都是勇士。到現在不知你心裡是否有個疑惑,不管你有沒有,反正我是有。疑惑在於圖1與圖3,圖1的curl語句沒有寫掩碼在流表中的效果卻和圖3中寫了32位掩碼效果一樣,這是不是意味著如果不寫掩碼,那麼預設的掩碼就是32位的?

 

不是這樣的,如何證明這個結論,抓包。wireshark 抓取圖1和圖3控制器下發的flow-mod資訊如圖4和圖5:使用的curl命令的ip地址分別位10.0.0.0和10.0.0.0/32

 

 

                  圖4 無掩碼的情況

 

     圖5 32位掩碼的情況

從圖4和圖5可以看出,是有個欄位has mask 控制著是否使用掩碼,在不使用掩碼的時候,也是沒有預設掩碼這一說法,此時就是精確匹配。比如說在不使用掩碼時curl中的ip地址你寫的是10.0.0.0,就意味者只能匹配一臺ip地址為10.0.0.0的主機,而不是匹配整個網段!

四、結論

1.掩碼匹配的情況,總體可分為兩種,使用掩碼或者不使用,不使用掩碼,並不是有預設掩碼的存在。

2.在不使用掩碼的時候,就是完全精確匹配,IP地址要一摸一樣。

3.使用掩碼時,無論是使用curl下發流表還是ovs中的流表匹配都是單純的ip地址與掩碼的與操作,所以會有32掩碼的存在,32位的掩碼就是想表達單個主機,若想表達網段就使用低於32位的掩碼。

&n