網(wǎng)絡分割與防火墻)
簡介這是一份軟件定義網(wǎng)絡SDN實驗課程設計文檔以PDF格式呈現(xiàn)全文圍繞Mininet模擬環(huán)境展開面向高校實驗教學人員、研究生及SDN初學者。文檔針對硬件實驗成本高、OpenFlow協(xié)議更新快、硬件環(huán)境靈活性不足、學生上手難度大等現(xiàn)實問題提出實驗科目設計應體現(xiàn)最新技術進展、增強與傳統(tǒng)網(wǎng)絡的差異對比、并采用模塊化組織方式。文章具體介紹了基于Mininet配合POX、Kinetic、Pyretic等控制器開展網(wǎng)絡環(huán)境搭建、特定拓撲繪制、網(wǎng)絡分割、二層防火墻編寫等實驗科目的思路并將實驗分為基礎型、驗證型、綜合型三大類可根據(jù)不同學生水平靈活選取學時與難度。資源包共1個文件PDF格式大小174KB已有104人學習瀏覽。讀者從中可獲取完整的SDN實驗課程設計框架、實驗科目組織方法以及教學效果說明可作為開設同類實驗課程或自學SDN仿真的參考。1. 軟件定義網(wǎng)絡實驗課的頭號難題沒有專用設備也能開出實驗軟件定義網(wǎng)絡SDN的實驗課有個普遍尷尬論文和教材寫得很熱鬧真到自己搭環(huán)境時OpenFlow 硬件交換機一臺幾萬元協(xié)議大約每半年更新一版買回來就面臨過時風險多數(shù)硬件對 1.1、1.2、1.3 版本支持不全安全傳輸層協(xié)議 TLS 的支持更少。這份課程設計要解決的核心問題就是讓研究生在沒有專用硬件、沒有現(xiàn)成實驗科目的條件下從零完成網(wǎng)絡環(huán)境搭建、拓撲繪制、網(wǎng)絡分割、防火墻編寫的完整實驗閉環(huán)。落地方案是 Mininet 模擬環(huán)境配合 POX、Kinetic、Pyretic 等控制器開設 11 個實驗科目把整套成本壓到一臺筆記本能承受的范圍。適合高校實驗課、研究生自修也適合想低成本復現(xiàn) SDN 實驗的從業(yè)者照著動手。2. Mininet 環(huán)境搭建與第一張拓撲把 SDN 跑在自己的筆記本上2.1 為什么是 Mininet先把三條路擺出來對比選型這件事不能只看 Mininet 宣傳得熱鬧得先把替代方案都擺出來。課程設計里提到的問題很實在一是實驗科目匱乏網(wǎng)上的 SDN 實驗要么是零散的博客教程要么需要特定硬件二是硬件交換設備貴OpenFlow 協(xié)議半年更新一次跟著買設備經(jīng)費上扛不住三是硬件環(huán)境靈活性差大部分設備只實現(xiàn)了 OpenFlow 1.0學生做拓撲繪制和網(wǎng)絡分割時要分批次排隊實驗環(huán)境切換還麻煩。三條路放在一起看方案成本靈活性學生上手硬件 OpenFlow 交換機高協(xié)議更新快低版本多為 1.0VLAN 切換復雜需分批排隊傳統(tǒng)虛擬機多臺 VM 組網(wǎng)中資源開銷大低復雜拓撲要起很多虛機慢環(huán)境搭建占一半時間Mininet 進程虛擬化幾乎為零高一行命令出任意拓撲快Python API 友好Mininet 是斯坦福 Nick McKeown 團隊基于 Linux Container 架構做的進程虛擬化平臺不是完整虛擬機。每個 host 是共享內(nèi)核的獨立網(wǎng)絡命名空間所以啟動速度快、資源占用小在沒有 GPU、沒有大內(nèi)存的普通筆記本上也能跑出幾十臺主機的拓撲。它支持 OpenFlow、Open vSwitch提供 Python API最大能擴展到 4096 臺主機的網(wǎng)絡結構代碼幾乎可以無縫遷移到真實硬件環(huán)境。對于互聯(lián)網(wǎng)領域的研究生來說這套環(huán)境還有個額外好處所有操作都在 Linux 命令行下完成順手把網(wǎng)絡協(xié)議分析和系統(tǒng)操作的基礎也練了。2.2 安裝與最小驗證先讓環(huán)境可復現(xiàn)我一般建議在 Ubuntu 18.04 以上的干凈環(huán)境里裝 Mininet避免和自己手的其他網(wǎng)絡實驗工具沖突。sudo apt-get update sudo apt-get install -y mininet mn --version sudo mn --test pingall--test pingall會創(chuàng)建一個默認的最小拓撲兩臺主機直連一臺交換機自動執(zhí)行全連通測試。如果看到兩臺主機的 ping 都返回成功說明 Mininet 內(nèi)核模塊、虛擬網(wǎng)卡和默認控制器都正常。這一步很重要后續(xù)所有實驗都建立在「環(huán)境本身是好的」這個前提上。接下來啟動一個帶外部控制器的拓撲sudo mn --topotree,2,3 --controllerremote,ip127.0.0.1,port6633這里的參數(shù)拆開看--topotree,2,3表示生成深度為 2、扇出為 3 的樹形拓撲也就是 1 臺根交換機、3 臺二級交換機、9 臺主機--controllerremote告訴 Mininet 不要用內(nèi)置的簡單控制器而是連接外部控制器ip127.0.0.1,port6633是控制器的監(jiān)聽地址和端口。后面接 POX 時端口必須和這里保持一致這是新手最容易踩的坑。2.3 自定義拓撲把「任意拓撲」寫成 Python 腳本默認拓撲只能應付演示真正做網(wǎng)絡分割、防火墻實驗必須自己定義拓撲。Mininet 的 Python API 寫起來很直接from mininet.topo import Topo class TwoSwitchTopo(Topo): 雙交換機拓撲h1 - s1 - s2 - h2 def build(self): s1 self.addSwitch(s1) s2 self.addSwitch(s2) h1 self.addHost(h1) h2 self.addHost(h2) self.addLink(h1, s1) self.addLink(h2, s2) self.addLink(s1, s2, delay5ms, bw10) topos {twoswitch: TwoSwitchTopo}保存為twoswitch.py后用下面的命令啟動sudo mn --custom twoswitch.py --topo twoswitch --mac --controllerremote邏輯說明build()是 Mininet 2.x 推薦覆蓋的構造方法節(jié)點初始化都寫在這里addSwitch和addHost返回節(jié)點對象鏈路延遲和帶寬通過addLink的可選參數(shù)傳入文件末尾的topos字典是 mn 命令識別拓撲名的入口key 值必須和--topo后面跟的名字一致。--mac參數(shù)會把主機 MAC 固定成00:00:00:00:00:0X這種規(guī)律形式方便后面用 Wireshark 或 tcpdump 對抓包結果做對照這個參數(shù)在驗證型實驗里幾乎是必開的。啟動后進 Mininet CLI先跑net看拓撲結構再跑h1 ping h2驗證鏈路。CLI 里可以直接執(zhí)行sh 命令也就是說你隨時可以在實驗環(huán)境里調(diào)用 ovs-ofctl、ovs-vsctl 這些底層工具這是后面排錯的主戰(zhàn)場。3. 控制器選型與差異對比實驗POX、Kinetic、Pyretic 怎么分工3.1 控制器是 SDN 實驗的「大腦」別一上來就全都要SDN 的核心是「控制與轉(zhuǎn)發(fā)分離」。Mininet 這一側(cè)模擬的是轉(zhuǎn)發(fā)面也就是 Open vSwitch 交換機控制器是控制面決定每一條流量怎么轉(zhuǎn)發(fā)。實驗課程里控制器選型是個關鍵決策選對了學生能順著學下去選錯了光環(huán)境就勸退一半人。課程設計里提到 POX、Kinetic、Pyretic 三種控制器它們的定位完全不同。POX 是純 Python 寫的控制器API 簡單事件模型直觀適合做基礎型實驗和驗證型實驗學生改代碼的難度低Pyretic 在 POX 之上提供更高級的策略組合抽象適合做網(wǎng)絡策略編程的綜合型實驗Kinetic 則側(cè)重于網(wǎng)絡策略的動態(tài)變化適合對 SDN 有濃厚興趣、想往研究方向走的學生。我的建議是基礎實驗統(tǒng)一用 POX綜合型實驗讓學有余力的學生選 Pyretic 或 Kinetic不要在一門課里同時鋪開三個控制器那樣學生會在控制器本身的學習上消耗大量時間偏離實驗目標。3.2 POX 二層轉(zhuǎn)發(fā)模塊先讓網(wǎng)絡通起來再做差異對比POX 自帶一個二層學習轉(zhuǎn)發(fā)模塊行為接近傳統(tǒng)以太網(wǎng)交換機。作為對照組它非常合適cd pox ./pox.py forwarding.l2_learning啟動后再開一個終端跑 Mininet連上 remote 控制器這時 pingall 應該全通。forwarding.l2_learning做的事情和普通交換機一樣收到未知目的 MAC 的幀就洪泛學習源 MAC 后建立 MAC 表。這個模塊的價值在于它是「傳統(tǒng)網(wǎng)絡的參照系」后面做差異對比實驗時用它的行為和自定義控制器行為對照學生一下子就能理解 SDN 的可編程性在哪里。自己寫一個最簡 POX 模塊也不難下面這個例子演示了交換機上線事件和基礎流表下發(fā)from pox.core import core import pox.openflow.libopenflow01 as of log core.getLogger() def _handle_ConnectionUp(event): 交換機接入控制器時下發(fā)一條 IPv4 上送控制器的流表 msg of.ofp_flow_mod() msg.match.dl_type 0x0800 # 匹配 IPv4 數(shù)據(jù)幀 msg.actions.append(of.ofp_action_output(portof.OFPP_CONTROLLER)) event.connection.send(msg) log.info(switch %s connected, event.connection.dpid) def launch(): core.openflow.addListenerByName(ConnectionUp, _handle_ConnectionUp)邏輯說明ConnectionUp是交換機完成 TCP 握手、和控制器建立 OpenFlow 會話后觸發(fā)的事件ofp_flow_mod是流表修改消息用來下發(fā)規(guī)則dl_type0x0800限定只匹配 IPv4 幀避免 ARP 等協(xié)議也被上送actions 里指定OFPP_CONTROLLER意思是把匹配到的包封裝成 PacketIn 消息發(fā)給控制器。這個模塊本身不做轉(zhuǎn)發(fā)決策但它是理解「下一條流表到底是怎么生效的」的最佳入門示例。啟動時用./pox.py mymodule加載自己的模塊日志里看到switch ... connected就說明鏈路建立成功。3.3 對照組怎么設計傳統(tǒng)交換機和 SDN 的行為差異課程設計里強調(diào)「增強差異對比實驗」這是這套實驗體系里最有教學價值的部分。具體做法是同一個拓撲跑兩遍一遍用 Mininet 默認控制器行為接近傳統(tǒng)二層交換機一遍用自寫的 POX 模塊用 iperf 測帶寬、用 pingall 測連通性、用 ovs-ofctl dump-flows 看流表變化。mininet iperf h1 h2 mininet sh ovs-ofctl dump-flows s1對照結果通常會讓學生印象深刻傳統(tǒng)交換機模式下流表是交換機自己學習出來的規(guī)則條目和 MAC 學習表一一對應SDN 模式下流表是控制器下發(fā)的規(guī)則內(nèi)容完全由你寫的代碼決定而且下發(fā)時機、匹配粒度、超時策略都可以程序化控制。同樣一臺交換機換一個控制器模塊網(wǎng)絡行為就完全變了這就是「通用硬件及軟件可編程」的直觀體現(xiàn)。學生在傳統(tǒng) TCP/IP 協(xié)議知識基礎上做這個對比既鞏固了舊知識又理解了為什么需要新的網(wǎng)絡架構。帶寬對比實驗有個細節(jié)要注意iperf 默認走 TCPTCP 的擁塞控制會掩蓋鏈路參數(shù)差異。想測出明顯的帶寬區(qū)別建議加上 UDP 參數(shù)比如mininet h1 iperf -u -b 8M -t 10 h2這樣測試的是鏈路實際轉(zhuǎn)發(fā)能力而不是 TCP 協(xié)議棧的適應結果。4. 網(wǎng)絡分割與防火墻實驗兩個高頻科目一次到位4.1 網(wǎng)絡分割用 VLAN 把廣播域物理切開網(wǎng)絡分割實驗的教學目標是讓學生理解在 SDN 里隔離不再依賴物理設備的位置而是靠流表和端口標簽。實現(xiàn)手段最常用的是 VLANMininet 里做 VLAN 實驗必須用 OVS 交換機默認的用戶態(tài)交換機對 VLAN 支持不完整容易出玄學問題。sudo mn --topolinear,3 --mac --switchovsk --controllerremote--switchovsk指定使用 Open vSwitch 橋接這是 VLAN 標簽能正常工作的前提。啟動后給不同端口的交換機端口打 VLAN 標簽mininet sh ovs-vsctl set Port s1-eth1 tag10 mininet sh ovs-vsctl set Port s1-eth2 tag20 mininet sh ovs-vsctl show邏輯說明tag10是把該端口設置為 VLAN 10 的 access 端口所有從該端口進入的幀都會被打上 VLAN 10 的標簽ovs-vsctl show用來確認標簽真生效了。做完這一步h1 和 h2 雖然在同一個物理交換機上但分屬不同廣播域h1 ping h2應該不通而 h1 和同 VLAN 內(nèi)的其他主機能通。如果想讓實驗更有層次可以再加一層流表規(guī)則mininet sh ovs-ofctl add-flow s1 priority100,dl_vlan10,actionsoutput:2這條規(guī)則的意思是匹配帶 VLAN 10 標簽的幀從端口 2 轉(zhuǎn)發(fā)出去。這樣學生能看到兩種分割思路的差異——一種是純端口標簽隔離一種是流表規(guī)則轉(zhuǎn)發(fā)后者更貼近 SDN「網(wǎng)絡分割由控制器策略決定」的本質(zhì)。4.2 防火墻編寫匹配域?qū)懭珒?yōu)先級調(diào)對二層防火墻是驗證型實驗里學生最有成就感的科目因為規(guī)則生效與否用 ping 就能直觀驗證。下面是一個 POX 防火墻模塊的核心代碼from pox.core import core import pox.openflow.libopenflow01 as of from pox.lib.addresses import IPAddr log core.getLogger() def _handle_ConnectionUp(event): # 丟棄 h1 - h2 的所有 ICMP 流量 drop of.ofp_flow_mod() drop.match.dl_type 0x0800 # IPv4 drop.match.nw_proto 1 # ICMP 協(xié)議號 drop.match.nw_src IPAddr(10.0.0.1) drop.match.nw_dst IPAddr(10.0.0.2) drop.priority 100 # 高于二層學習默認優(yōu)先級 drop.idle_timeout 0 # 永不過期 drop.actions [] # 空 actions 表示丟棄 event.connection.send(drop) log.info(firewall rule installed: block h1-h2 ICMP) def launch(): core.openflow.addListenerByName(ConnectionUp, _handle_ConnectionUp)邏輯說明dl_type匹配網(wǎng)絡層類型0x0800是 IPv4nw_proto匹配傳輸層協(xié)議號1 是 ICMP6 是 TCP17 是 UDPnw_src和nw_dst限定源目 IPpriority100必須明顯高于轉(zhuǎn)發(fā)模塊的優(yōu)先級否則 l2_learning 的洪泛規(guī)則會先命中drop 規(guī)則形同虛設空 actions 列表在 OpenFlow 里就是丟棄語義。idle_timeout0表示規(guī)則常駐流表不會因空閑被回收。這里有一個教學上必須讓學生親手踩一下的細節(jié)如果他們只寫了dl_type和nw_dst沒寫nw_proto那么這條規(guī)則會匹配所有協(xié)議包括 ARP結果連網(wǎng)關都 ping 不通如果寫了nw_proto6TCP但用 ping 測試那規(guī)則永遠不會命中。匹配域的選擇決定了防火墻的粒度這是防火墻實驗最重要的知識點。4.3 實驗驗收別只看「通了沒」要看「規(guī)則是不是真下了」驗證型實驗最容易出現(xiàn)「假通過」——測試命令顯示 ping 通但學生根本不知道背后是控制器在轉(zhuǎn)發(fā)還是交換機自學習在轉(zhuǎn)發(fā)。所以我在驗收時強制要求三步實驗科目驗收動作預期結果網(wǎng)絡環(huán)境搭建pingall全部通過無丟包特定拓撲繪制net、dump 對照設計圖節(jié)點數(shù)、鏈路數(shù)、命名完全一致網(wǎng)絡分割跨 VLAN ping 同 VLAN ping跨 VLAN 不通同 VLAN 通防火墻編寫h1 ping h2 h1 ping h3h1 到 h2 不通到 h3 通規(guī)則下發(fā)確認ovs-ofctl dump-flows流表里有 drop 規(guī)則且 priority 正確第 5 條是每次必查的。ovs-ofctl dump-flows s1能看到交換機流表里實際存在的所有規(guī)則如果規(guī)則沒出現(xiàn)在這里無論測試結果多漂亮都說明實驗沒真正完成。很多學生以為在控制器側(cè)打印了日志就代表規(guī)則生效實際上event.connection.send(msg)只是把消息發(fā)出去了交換機可能因為匹配域格式錯誤、優(yōu)先級沖突等原因拒絕接收只有 dump 出來的才是真相。5. 避坑指南Mininet 實驗里最常見的五個坑5.1 控制器一直連不上remote 端口和監(jiān)聽地址對不上現(xiàn)象啟動mn --controllerremote后POX 日志里始終看不到ConnectionUp事件pingall 全不通交換機好像「失聯(lián)」了。原因最常見的有兩類。第一類是端口不一致——POX 監(jiān)聽 6633Mininet 默認 remote 端口也是 6633但如果你用--port6634改過 POX 端口而 Mininet 這邊沒改兩邊永遠握不上手第二類是 POX 起來了但沒加載任何模塊控制器進程在跑但它沒有開放監(jiān)聽或者沒有處理新連接。解決先在 POX 啟動命令里顯式指定端口./pox.py forwarding.l2_learning --port6633Mininet 側(cè)用--controllerremote,ip127.0.0.1,port6633對齊啟動后第一時間看 POX 窗口有沒有出現(xiàn)交換機連接日志沒有就先用pingall確認拓撲本身通訊正常再用netstat -tlnp | grep 6633查端口監(jiān)聽狀態(tài)逐層定位。5.2 第二次跑同一個實驗報端口占用或數(shù)據(jù)庫鎖現(xiàn)象上一次實驗沒退出干凈再次啟動 mn 時報端口被占用、無法綁定 6653/6633或者報 Open vSwitch 數(shù)據(jù)庫被鎖明明沒開別的終端。原因Mininet 異常退出比如直接關終端、CtrlZ 掛起時殘留的 ovsdb-server、ovs-controller 進程和虛擬網(wǎng)卡沒有被清理端口和數(shù)據(jù)庫資源一直被占著。解決每次實驗前固定執(zhí)行一次sudo mn -c這個命令會清理殘留進程、虛擬網(wǎng)卡和臨時文件。如果mn -c之后還是報端口占用直接sudo pkill -f ovs把殘留的 OVS 進程全部殺掉再重新開始。這個習慣養(yǎng)成后能省掉大量「環(huán)境起不來」的排查時間。5.3 防火墻規(guī)則明明寫了流量照樣通現(xiàn)象在 POX 里配好了 drop 規(guī)則日志也打印了rule installed但 h1 ping h2 照樣通規(guī)則像沒寫一樣。原因兩類問題占九成。第一類是匹配域不完整或?qū)戝e——比如想攔 ICMP結果nw_proto填了 6TCPICMP 是 1規(guī)則永遠匹配不到第二類是優(yōu)先級問題——POX 的 l2_learning 模塊優(yōu)先級是默認值如果 drop 規(guī)則的 priority 沒調(diào)到更高學習規(guī)則先命中包直接按二層轉(zhuǎn)發(fā)了根本輪不到 drop 規(guī)則。解決先ovs-ofctl dump-flows s1看規(guī)則到底有沒有下發(fā)成功如果規(guī)則在流表里用ovs-ofctl dump-flows s1 --strict精確匹配同參數(shù)規(guī)則逐項核對 dl_type、nw_proto、nw_src、nw_dst再把 drop 規(guī)則的 priority 調(diào)到明顯高于轉(zhuǎn)發(fā)規(guī)則的值比如 100 以上改完重新下發(fā)后立即用 ping 驗證。5.4 網(wǎng)絡分割實驗里 ping 不通但不一定是 VLAN 的鍋現(xiàn)象設置了 tag 之后同 VLAN 內(nèi)的兩臺主機也不通了學生以為是 VLAN 配置寫錯了反復改 tag 值無效。原因最典型的兩個。一是啟動時沒加--switchovsk默認用的是用戶態(tài)交換機VLAN 標簽行為不完整二是雖然接了 remote 控制器但控制器里沒有支持 VLAN 的轉(zhuǎn)發(fā)邏輯比如只加載了最基本的模塊帶標簽的幀進了交換機后沒有對應處理規(guī)則直接被丟棄。解決強制--switchovsk啟動并且控制器加載forwarding.l2_learning或自己寫一個能識別dl_vlan的轉(zhuǎn)發(fā)模塊設置 tag 后跑ovs-vsctl show確認標簽真的寫進端口了然后再做 ping 測試。排查順序永遠是先確認物理鏈路通再確認標簽狀態(tài)最后才懷疑控制器邏輯。5.5 實驗腳本版本混亂改著改著不知道哪版是對的現(xiàn)象課程進行到一半學生手里的 mytopo.py 出現(xiàn)了五六個版本有的能跑有的不能跑拓撲參數(shù)和控制器代碼對應不上驗收時對不上號。原因?qū)嶒災_本之間有依賴關系拓撲一變防火墻規(guī)則里的 IP 段、VLAN tag 都要跟著改手動復制粘貼非常容易丟參數(shù)。而且很多學生沒有版本管理習慣改壞了就回不去了。解決從一開始就要求用 gitee 建一個私有倉庫管理實驗腳本每個實驗一個目錄跑通的版本打 tag目錄里放一個 README 寫明拓撲參數(shù)和控制器的對應關系。gitee 在國內(nèi)訪問穩(wěn)定學生提交代碼、老師看提交記錄都方便。我自己的習慣是每個實驗目錄命名為「編號-實驗名-控制器類型」三個月后回來還能秒復現(xiàn)這個習慣在帶多輪學生時價值尤其大。6. 模塊化實驗體系11 個科目怎么排驗證參數(shù)怎么定6.1 三個層次的分工課程設計的核心思路是模塊化不要求所有學生做同樣的實驗而是按難度分三檔學生按自己的基礎和目標選做。類型代表科目面向?qū)ο蠖ㄎ换A型Mininet 環(huán)境搭建、基本使用全體研究生掌握實驗環(huán)境驗證型特定拓撲繪制、二層防火墻、網(wǎng)絡分割全體研究生驗證 SDN 核心特性綜合型Pyretic 策略實驗、OpenStack Neutron 擴展小課題學有余力者獨立研究能力基礎型不設門檻學時自選驗證型是課程主軸每個科目都有明確的驗收標準綜合型不做硬性要求完成可以抵消前面學時。這樣安排的好處是動手能力弱的學生不會被綜合實驗勸退想深入的學生也有往上走的空間。6.2 每個驗證實驗的三步驗證套路我?guī)嶒炚n總結出一套固定的驗證流程適用于所有驗證型科目第一步拓撲腳本統(tǒng)一加--mac固定 MAC 地址保證每次跑的地址完全一致抓包結果可對照第二步控制器側(cè)盯 ConnectionUp 日志確認所有交換機都上了線再開始操作第三步任何規(guī)則下發(fā)后都用ovs-ofctl dump-flows確認規(guī)則真的落到了流表里而不是只在控制器側(cè)打印了日志。參數(shù)速查表也固定下來學生照著填就行實驗關鍵參數(shù)檢查點拓撲繪制--topo或自定義腳本net 輸出與設計圖一致網(wǎng)絡分割--switchovsktag10/20同 VLAN 通、跨 VLAN 不通防火墻priority100idle_timeout0dump-flows 有規(guī)則ICMP 被拒這套流程跑下來驗證型實驗基本不會出現(xiàn)「結果對不上」的情況。從那以后我每次驗收學生實驗都強制先跑一遍ovs-ofctl dump-flows規(guī)則沒有真正落到交換機上后面的一切免談。這個習慣幫我過濾掉了大量「看著通了、其實沒通」的結果也讓學生明白實驗課的重點在驗證而不在抄命令。希望幫到你。本文還有配套的精品資源點擊獲取