• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

RYU+Mininet的SDN架构-设计校园网络三

武飞扬头像
一个编程的菜鸡
帮助1

这是基于RYU Mininet的SDN架构设计仿真校园网络的第一部分

总体详见:【基本中型网络的仿真(RYU Mininet的SDN架构)-以校园为例】

章节:

【RYU Mininet的SDN架构-设计校园网络(一)】【RYU Mininet的SDN架构-设计校园网络(二)】学新通https://blog.csdn.net/weixin_53284122/article/details/129393371

【RYU Mininet的SDN架构-设计校园网络(二)】

【RYU Mininet的SDN架构-设计校园网络(三)】

【RYU Mininet的SDN架构-设计校园网络(四)】

【RYU Mininet的SDN架构-设计校园网络(五)】

 四、设计配置与实现

4.1 SDN设计配置与实现

SDN采用RYU控制器和mininet的方式,交换机采用的是openflow13协议。

  1. 配置

主要是涉及Mininet和RYU控制器的安装,一起路由定义软件Quagga的安装和配置。

详细的配置步骤在网络上都可以找到,在此不在叙述。

  1. 实现

第一步:打开RYU控制器,运行相应的程序(比如simple_switch_13.py默认路由,rest_firewall.py防火墙程序)

第二步:运行拓扑代码,连接到控制器

4.2 OSPF设计配置与实现

ospf采用quagga实现,需要对每个路由器配置相应的守护进程,在通过命令行开启ospf算法,最终实现路由的收敛。

(1)配置

1.在quagga安装目录里写配置文件

r1ospfd.conf(设置r1的直连网络)

hostname r1_ospfd

password 123

enable password 123

router ospf

  ospf router-id 192.168.3.2

  network 192.168.3.0/30 area 0

  network 192.168.3.4/30 area 0

  network 192.168.10.0/30 area 0

debug ospf event

log stdout

  1.  
    hostname r1_ospfd
  2.  
     
  3.  
    password 123
  4.  
     
  5.  
    enable password 123
  6.  
     
  7.  
     
  8.  
     
  9.  
    router ospf
  10.  
     
  11.  
      ospf router-id 192.168.3.2
  12.  
     
  13.  
      network 192.168.3.0/30 area 0
  14.  
     
  15.  
      network 192.168.3.4/30 area 0
  16.  
     
  17.  
      network 192.168.10.0/30 area 0
  18.  
     
  19.  
    debug ospf event
  20.  
     
  21.  
    log stdout
学新通

r2ospfd.conf(设置r2的直连网络)

hostname r2_ospfd

password 123

enable password 123

router ospf

  ospf router-id 192.168.3.1

  network 192.168.1.0/24 area 0

  network 192.168.3.0/30 area 0

debug ospf event

log stdout

  1.  
    hostname r2_ospfd
  2.  
     
  3.  
    password 123
  4.  
     
  5.  
    enable password 123
  6.  
     
  7.  
     
  8.  
     
  9.  
    router ospf
  10.  
     
  11.  
      ospf router-id 192.168.3.1
  12.  
     
  13.  
      network 192.168.1.0/24 area 0
  14.  
     
  15.  
      network 192.168.3.0/30 area 0
  16.  
     
  17.  
    debug ospf event
  18.  
     
  19.  
    log stdout
学新通

r3ospfd.conf(设置r3的直连网络)

hostname r3_ospfd

password 123

enable password 123

router ospf

  ospf router-id 192.168.3.6

  network 192.168.2.0/24 area 0

  network 192.168.3.4/30 area 0

debug ospf event

log stdout

  1.  
    hostname r3_ospfd
  2.  
     
  3.  
    password 123
  4.  
     
  5.  
    enable password 123
  6.  
     
  7.  
     
  8.  
     
  9.  
    router ospf
  10.  
     
  11.  
      ospf router-id 192.168.3.6
  12.  
     
  13.  
      network 192.168.2.0/24 area 0
  14.  
     
  15.  
      network 192.168.3.4/30 area 0
  16.  
     
  17.  
    debug ospf event
  18.  
     
  19.  
    log stdout
学新通

r1zebra.conf、r2zebra.conf、r3zebra.conf 3个文件无需额外配置,直接复制示例模板即可。

2.命令行启动quagga及运行

命令行打开quagga软件,命令如下:

sudo zebra -d

软件打开后,在拓扑代码final.py中嵌入以下命令,运行ospf: 

r1.cmd('zebra -f /etc/quagga/r1zebra.conf -d -z /tmp/r1zebra.api -i /tmp/r1zebra.interface')

    r2.cmd('zebra -f /etc/quagga/r2zebra.conf -d -z /tmp/r2zebra.api -i /tmp/r2zebra.interface')

    r3.cmd('zebra -f /etc/quagga/r3zebra.conf -d -z /tmp/r3zebra.api -i /tmp/r3zebra.interface')

    time.sleep(1)  # time for zebra to create api socket

    r1.cmd('ospfd -f /etc/quagga/r1ospfd.conf -d -z /tmp/r1zebra.api -i /tmp/r1ospfd.interface')

    r2.cmd('ospfd -f /etc/quagga/r2ospfd.conf -d -z /tmp/r2zebra.api -i /tmp/r2ospfd.interface')

r3.cmd('ospfd -f /etc/quagga/r3ospfd.conf -d -z /tmp/r3zebra.api -i /tmp/r3ospfd.interface')

  1.  
    r1.cmd('zebra -f /etc/quagga/r1zebra.conf -d -z /tmp/r1zebra.api -i /tmp/r1zebra.interface')
  2.  
     
  3.  
    r2.cmd('zebra -f /etc/quagga/r2zebra.conf -d -z /tmp/r2zebra.api -i /tmp/r2zebra.interface')
  4.  
     
  5.  
    r3.cmd('zebra -f /etc/quagga/r3zebra.conf -d -z /tmp/r3zebra.api -i /tmp/r3zebra.interface')
  6.  
     
  7.  
    time.sleep(1)  # time for zebra to create api socket
  8.  
     
  9.  
    r1.cmd('ospfd -f /etc/quagga/r1ospfd.conf -d -z /tmp/r1zebra.api -i /tmp/r1ospfd.interface')
  10.  
     
  11.  
    r2.cmd('ospfd -f /etc/quagga/r2ospfd.conf -d -z /tmp/r2zebra.api -i /tmp/r2ospfd.interface')
  12.  
     
  13.  
    r3.cmd('ospfd -f /etc/quagga/r3ospfd.conf -d -z /tmp/r3zebra.api -i /tmp/r3ospfd.interface')

(2)实现

通过直接运行final.py文件

学新通

图4-1启动ospf操作示意图

4.3 STP设计配置与实现

Stp采用ryu控制器实现,通过设置可以处理的流表类型来允许处理BDPU包,从而开启stp,实现防止环路形成/链路恢复。

(1)配置

在ryu的模块simple_switch_13.py中配置

simple_switch_13.py

……

……

from ryu.lib import stplib #改变1:引入stplib,以支持STP协议

class SimpleSwitch13(app_manager.RyuApp):

    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    _CONTEXTS = {'stplib': stplib.Stp} #改变2:指定STP协议参考类

……

……

    #@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)

    @set_ev_cls(stplib.EventPacketIn, MAIN_DISPATCHER)#改变3:将EventOFPPacketIn 换成EventPacketIn,后者封装了前者,且可以处理BDPU包

……

……

  1.  
    ……
  2.  
     
  3.  
    ……
  4.  
     
  5.  
    from ryu.lib import stplib #改变1:引入stplib,以支持STP协议
  6.  
     
  7.  
     
  8.  
     
  9.  
    class SimpleSwitch13(app_manager.RyuApp):
  10.  
     
  11.  
        OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
  12.  
     
  13.  
        _CONTEXTS = {'stplib': stplib.Stp} #改变2:指定STP协议参考类
  14.  
     
  15.  
    ……
  16.  
     
  17.  
    ……
  18.  
     
  19.  
        #@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
  20.  
     
  21.  
        @set_ev_cls(stplib.EventPacketIn, MAIN_DISPATCHER)#改变3:将EventOFPPacketIn 换成EventPacketIn,后者封装了前者,且可以处理BDPU包
学新通

(2)实现

由于是直接在ryu控制器中进行设置,那么无需在拓扑代码中再进行设置,直接运行拓扑文件final.py文件即可。

学新通

图4-2启动stp操作示意图

4.4 DHCP设计配置与实现

DHCP采用的是下载额外的DHCP服务器,然后通过mininet自带的host.defaultIntf.updateIP()函数进行IP地址的更新。

  1. 配置

checkRequired()函数检查各项配置

def checkRequired():

    "Check for required executables"

    required = [ 'udhcpd', 'udhcpc', 'dnsmasq', 'curl', 'firefox' ]

    for r in required:

        if not quietRun( 'which '  r ):

            print '* Installing', r

            print quietRun( 'apt-get install -y '  r )

            if r == 'dnsmasq':

                print quietRun( 'update-rc.d dnsmasq disable' )

  1.  
    def checkRequired():
  2.  
     
  3.  
        "Check for required executables"
  4.  
     
  5.  
        required = [ 'udhcpd''udhcpc''dnsmasq''curl''firefox' ]
  6.  
     
  7.  
        for r in required:
  8.  
     
  9.  
            if not quietRun( 'which '  r ):
  10.  
     
  11.  
                print '* Installing', r
  12.  
     
  13.  
                print quietRun( 'apt-get install -y '  r )
  14.  
     
  15.  
                if r == 'dnsmasq':
  16.  
     
  17.  
                    print quietRun( 'update-rc.d dnsmasq disable' )
学新通

(1)实现

主要流程如下图:

学新通

图4-3 DHCP运行流程图

下面介绍各个流程核心代码

地址池的设置(例子)

DNSTemplate = """

start #开始IP

end #结束IP

option subnet #子网掩码

option domain local

option lease 7  # seconds

"""

  1.  
    DNSTemplate = """
  2.  
     
  3.  
    start #开始IP
  4.  
     
  5.  
    end #结束IP
  6.  
     
  7.  
    option subnet #子网掩码
  8.  
     
  9.  
    option domain local
  10.  
     
  11.  
    option lease 7  # seconds
  12.  
     
  13.  
    """

创建DHCP服务器.conf文件

def makeDHCPconfig( filename, intf, gw, dns ):

    "Create a DHCP configuration file"

    config = (

        'interface %s' % intf,

        DNSTemplate,

        'option router %s' % gw,

        'option dns %s' % dns,

        '' )

     with open( filename, 'w' ) as f:

        f.write( '\n'.join( config ) )

  1.  
    def makeDHCPconfig( filename, intf, gw, dns ):
  2.  
     
  3.  
        "Create a DHCP configuration file"
  4.  
     
  5.  
        config = (
  6.  
     
  7.  
            'interface %s' % intf,
  8.  
     
  9.  
            DNSTemplate,
  10.  
     
  11.  
            'option router %s' % gw,
  12.  
     
  13.  
            'option dns %s' % dns,
  14.  
     
  15.  
            '' )
  16.  
     
  17.  
         with open( filename, 'w' ) as f:
  18.  
     
  19.  
            f.write( '\n'.join( config ) )
学新通

启动DHCP服务器

def startDHCPserver( host, gw, dns ):

    "Start DHCP server on host with specified DNS server"

    info( '* Starting DHCP server on', host, 'at', host.IP(), '\n' )

    dhcpConfig = '/tmp/%s-udhcpd.conf' % host

    makeDHCPconfig( dhcpConfig, host.defaultIntf(), gw, dns )

    host.cmd( 'udhcpd -f', dhcpConfig,

              '1>/tmp/%s-dhcp.log 2>&1  &' % host )

  1.  
    def startDHCPserver( host, gw, dns ):
  2.  
     
  3.  
        "Start DHCP server on host with specified DNS server"
  4.  
     
  5.  
        info( '* Starting DHCP server on', host, 'at', host.IP(), '\n' )
  6.  
     
  7.  
        dhcpConfig = '/tmp/%s-udhcpd.conf' % host
  8.  
     
  9.  
        makeDHCPconfig( dhcpConfig, host.defaultIntf(), gw, dns )
  10.  
     
  11.  
        host.cmd( 'udhcpd -f', dhcpConfig,
  12.  
     
  13.  
                  '1>/tmp/%s-dhcp.log 2>&1  &' % host )

启动请求方,并创建.log文件

def startDHCPclient( host ):

    "Start DHCP client on host"

    intf = host.defaultIntf()

    host.cmd( 'dhclient -v -d -r', intf )

host.cmd( 'dhclient -v -d 1> /tmp/dhclient.log 2>&1', intf, '&' )

  1.  
    def startDHCPclient( host ):
  2.  
     
  3.  
        "Start DHCP client on host"
  4.  
     
  5.  
        intf = host.defaultIntf()
  6.  
     
  7.  
        host.cmd( 'dhclient -v -d -r', intf )
  8.  
     
  9.  
    host.cmd( 'dhclient -v -d 1> /tmp/dhclient.log 2>&1', intf, '&' )

请求方等待IP地址,若失败则进行重复请求

def waitForIP( host ):

    "Wait for an IP address"

    info( '*', host, 'waiting for IP address' )

    while True:

        host.defaultIntf().updateIP()

        if host.IP():

            break

        info( '.' )

        sleep( 1 )

    info( '\n' )

至此,DHCP分配结束。

  1.  
    def waitForIP( host ):
  2.  
     
  3.  
        "Wait for an IP address"
  4.  
     
  5.  
        info( '*', host, 'waiting for IP address' )
  6.  
     
  7.  
        while True:
  8.  
     
  9.  
            host.defaultIntf().updateIP()
  10.  
     
  11.  
            if host.IP():
  12.  
     
  13.  
                break
  14.  
     
  15.  
            info( '.' )
  16.  
     
  17.  
            sleep( 1 )
  18.  
     
  19.  
        info( '\n' )
学新通

4.5 NAT配置与实现

NAPT的配置在拓扑代码里实现。通过以下代码在拓扑中加入NAT节点。

NAT节点添加代码

nat0 = self.addNode('nat0', cls=NAT, ip='192.168.10.1/30', subnet='192.168.0.0/16', inNamespace=False)

其中subnet属性用于配置nat节点所负责的子网范围,只有处于subnet内的主机通信时,nat节点才会为其提供转换。

之后我们还要为所有节点配置默认路由,并为nat节点配置路由使得外面发送的信息能够成功传入Mininet内。

默认路由配置代码

r1.cmd('route add default gw 192.168.10.1 dev r1-eth3')

r2.cmd('route add default gw 192.168.3.2 dev r2-eth1')

r3.cmd('route add default gw 192.168.3.5 dev r3-eth1')

nat0.cmd('route add -net 192.168.0.0/16 gw 192.168.10.2 dev nat0-eth1')

  1.  
    r1.cmd('route add default gw 192.168.10.1 dev r1-eth3')
  2.  
     
  3.  
    r2.cmd('route add default gw 192.168.3.2 dev r2-eth1')
  4.  
     
  5.  
    r3.cmd('route add default gw 192.168.3.5 dev r3-eth1')
  6.  
     
  7.  
    nat0.cmd('route add -net 192.168.0.0/16 gw 192.168.10.2 dev nat0-eth1')

通过以上配置之后,Mininet内的主机便可以与外界主机通信了。

4.6防火墙配置与实现

防火墙采用的是RYU控制器,通过在RYU控制器中的防火墙程序(rest_firewall.py)文件进行实现。

(1)配置

1.通过编写代码设置防火墙规则

Firewall.py(实现防火墙的过滤规则)

import requests

data1='{"nw_src":"192.168.1.1","nw_dst":"192.168.2.1"}'

data2='{"nw_src":"192.168.2.1","nw_dst":"192.168.1.1"}'

data3='{"nw_src":"192.168.2.2","nw_dst":"192.168.1.1"}'

data4='{"nw_src":"192.168.1.1","nw_dst":"192.168.2.2"}'

def firewall():

    # set rules for switch by ryu/ryu.app/rest_firewall.py

    # data1-data4 is the rule by myself)

    response = requests.put('http://localhost:8080/firewall/module/enable/0000

000000000004')

    response=

requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004',

data=data1)

    response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data2)

    response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data3)

    response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data4)

firewall()

  1.  
    import requests
  2.  
     
  3.  
    data1='{"nw_src":"192.168.1.1","nw_dst":"192.168.2.1"}'
  4.  
     
  5.  
    data2='{"nw_src":"192.168.2.1","nw_dst":"192.168.1.1"}'
  6.  
     
  7.  
    data3='{"nw_src":"192.168.2.2","nw_dst":"192.168.1.1"}'
  8.  
     
  9.  
    data4='{"nw_src":"192.168.1.1","nw_dst":"192.168.2.2"}'
  10.  
     
  11.  
    def firewall():
  12.  
     
  13.  
        # set rules for switch by ryu/ryu.app/rest_firewall.py
  14.  
     
  15.  
        # data1-data4 is the rule by myself)
  16.  
     
  17.  
        response = requests.put('http://localhost:8080/firewall/module/enable/0000
  18.  
     
  19.  
    000000000004')
  20.  
     
  21.  
        response=
  22.  
     
  23.  
    requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004',
  24.  
     
  25.  
    data=data1)
  26.  
     
  27.  
        response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data2)
  28.  
     
  29.  
        response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data3)
  30.  
     
  31.  
        response = requests.post('http://127.0.0.1:8080/firewall/rules/0000000000000004', data=data4)
  32.  
     
  33.  
     
  34.  
     
  35.  
    firewall()
学新通

2.命令行设置防火墙规则

命令行打开S4,设置为可以enable状态,配置命令如下:

curl -X PUT  http://localhost:8080/firewall/module/enable/0000000000000004

之后在enable状态下,在链接到RYU控制器后台设置防火墙的过滤规则。

curl -X POST -d '{"nw_src":"192.168.2.1/32","nw_dst":"192.168.1.1/32"}' http://127.0.0.1:8080/firewall/rules/0000000000000004

curl -X POST -d '{"nw_src":"192.168.1.1/32","nw_dst":"192.168.2.1/32"}' http://127.0.0.1:8080/firewall/rules/0000000000000004

(2)实现

1)启动控制器C1的终端,启动RYU控制器的防火墙程序

学新通

图4-4 启动防火墙操作示意图

  1. 通过直接运行firewall.py文件或者命令行方式设置防火墙过滤的规则

学新通

图4-5 启动设置防火墙规则操作示意图

4.7 WIFI配置与实现

WLAN部分的实现以代码为主,以下展示具体的实现思路和核心代码。

(1)设置网络类型为Mininet-WiFi,并配置控制器

设置网络类型为Mininet-WiFi,并配置控制器

net = Mininet_wifi(topo=None,

       build=False,

       link=wmediumd ,

       wmediumd_mode=interference)

info('***Adding controllerln ' )

c1= net.addController( name= 'c1 ',controller=Controller, protocol= 'tcp ' ,port=6653)

  1.  
    net = Mininet_wifi(topo=None,
  2.  
     
  3.  
           build=False,
  4.  
     
  5.  
           link=wmediumd ,
  6.  
     
  7.  
           wmediumd_mode=interference)
  8.  
     
  9.  
    info('***Adding controllerln ' )
  10.  
     
  11.  
    c1= net.addController( name= 'c1 ',controller=Controller, protocol= 'tcp ' ,port=6653)

(2)配置AP的名称、MAC地址、SSID、信道编号、加密方式、密码和物理位置。

配置AP(以AP1为例)

ap1 = net.addAccessPoint( 'ap1', mac='00:00:00:00:00:01', ssid="handover",mode="g", channel="1", passwd= '123456789a',encrypt='wpa2', position='123.0,323.0,0')

ap1 = net.addAccessPoint( 'ap1', mac='00:00:00:00:00:01', ssid="handover",mode="g", channel="1", passwd= '1234567

(3)配置站点的名称、IP地址、物理位置、扫描信号强度门限、短间隔、长间隔和扫描模式。

配置站点(以sta1为例)

sta1 = net.addStation( 'sta1', ip= '192.168.4.1/24',position= '54.0,434.0,0 ', bgscan_threshold=-60,s_inverval=5, l_interval=10,bgscan_module="simpie")

(4)设置无线信号的指数传播模型

设置无线信号的指数传播模型

net.setPropagationModel( model="logDistance" , exp=3)

4.8虚拟机隧道配置与实现

为了实现两个Mininet网络的互连,我们首先需要在两个Ubuntu虚拟机上各再创建一张新的网卡。创建新网卡后,需要将新添加的网卡与Open vSwitch交换机端口绑定。具体实现过程如下:

①在两个Ubuntu虚拟机上各再创建一张新的网卡。添加新的虚拟机网卡需要在VMware Player中设置,如图。

学新通

图4-6 创建一张新的网卡

②进入虚拟机,释放新添加的虚拟机网卡。使用的具体命令如图。

学新通

图4-7 释放虚拟机网卡使用的命令

③然后将两台虚拟机中新创建的虚拟网卡绑定到同一VMnet网卡上(即下图的VMnet0),并且需要将对应VMnet设置成桥接模式。

学新通

图4-8 虚拟机网卡配置

从上图可以看出,VMnet0网卡桥接到了物理主机的无线网卡(Microsoft-WiFi Direct Virtual Adapter)上,因此,我们可以画出如下的设备连接逻辑图。

学新通

图4-9 占用网卡后的无线网网络拓扑

④将OVS交换机端口与刚释放出来的虚拟网卡相绑定。使用的代码如下:

代码-将OVS交换机端口与刚释放出来的虚拟网卡相绑定

import os

……

os. popen( 'ovs-vsctl add-port s1 ens34 ')

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbgeea
系列文章
更多 icon
同类精品
更多 icon
继续加载