网站建设素材图,妇联网站建设方案,注册网站怎么做,关于建立网站的申请目录 具体问题可以私聊博主 一、设计目标
1.1应用场景介绍
1.2应用场景设计要求
网络配置方式
网络技术要求
网络拓扑要求
互联互通
二、课程设计内容与原理
#xff08;1#xff09;预期网络拓扑结构和功能
#xff08;1#xff09;网络设备信息
…目录 具体问题可以私聊博主 一、设计目标
1.1应用场景介绍
1.2应用场景设计要求
网络配置方式
网络技术要求
网络拓扑要求
互联互通
二、课程设计内容与原理
1预期网络拓扑结构和功能
1网络设备信息
2DHCP自动配置
6防火墙技术
7DHCP
三、课程设计方案
四、课程设计配置与实现
五、课程设计验证与结果分析
代码
网络拓扑
WLAN代码
参考资料 一、设计目标
1.1应用场景介绍
现有一个中学需要设计一个中小型网络满足学校的网络需求。
学校有教学区实验室区域和服务器区域。教学区为了满足接入的灵活性和信号强度要求需要满足设计WIFI满足日常教室和同学需求接入上限为200人。实验室区域需要有一台教师主机方便管理实验室其余电脑并且教师主机可以访问学校服务器方便为同学们实验室授课。学校服务器区域设有学校相关重要文件和学校网页相关内容。最后学校还会接入互联网。
1.2应用场景设计要求 网络配置方式
网络配置的方式应该便捷方便管理和排错主机和转发设备应该采用什么配置方式服务器采用什么类型。 网络技术要求
SDN架构实现数控分离、防火墙路由协议NAT其余适合的网络技术或私有技术。 网络拓扑要求
链路要有冗余度链路同时还要具有复杂度。 互联互通
仿真设计的网络需要互联互通访问互联网与其他小组互通 二、课程设计内容与原理
2.1网络拓扑
1预期网络拓扑结构和功能 图2-1 网络拓扑示意图
注此网络拓扑只是表示拓扑联系不代表实际实现拓扑
网络1是WIFI区域此区域主要对应应用场景中的教学区域此区域拥有多个无线AP接入点可以实现设备的AP接入点切换。
网络2是实验室区域此部分区域由三个交换机成环连接在此需要实现STP以此满足实验室考试网络拥堵和网络故障特殊情况保证网络的质量和考试的网络质量。
网络3是学校的服务器区域此区域部署了三台服务器分别是DHCP服务器网页服务器和文件服务器三台服务器通过交换机连接在路由器上面。
路由区域部分需要实现报文的传递和交付。
最后整个校区会通过一个路由器接入互联网。
实际网路拓扑在我们实现的网络拓扑当中网络的拓扑结构如下。 图2-2 实际拓扑示意图
子网1下的交换机连接三个无线AP接入点站点通过不同的策略连接到AP之上后续会详细叙述。
2.2网络配置
1网络设备信息
表2-1 WLAN0中设备接口IP地址分配情况 设备 接口 IP地址 子网掩码 WLAN0 sta1 sta1-wlan0 192.168.4.1 255.255.255.0 sta2 sta2-wlan0 192.168.4.2 255.255.255.0 sta3 sta3-wlan0 192.168.4.3 255.255.255.0 sta4 sta4-wlan0 192.168.4.4 255.255.255.0 sta5 sta5-wlan0 192.168.4.5 255.255.255.0 sta6 sta6-wlan0 192.168.4.6 255.255.255.0 表2-2 子网2设备和接口的IP设置 设备 IP地址 子网掩码 子网2 H1 192.168.1.1 255.255.255.0 H2 DHCP服务器分配地址池192.168.1.2~192.168.1.6 255.255.255.0 H3 255.255.255.0 H4 255.255.255.0 H5 255.255.255.0 H6 255.255.255.0 默认网关 R2-eth2 192.168.1.254 255.255.255.0 表2-3 服务器区域设备和接口IP划分 设备 IP地址 子网掩码 子网3 H7 192.168.2.1 255.255.255.0 H8 192.168.2.2 255.255.255.0 默认网关 R3-eth2 192.168.2.254 255.255.255.0 表2-4 路由器IP设置 路由器 接口 IP 掩码 R1 eth1 192.168.3.2 255.255.255.252 R1 eth2 192.168.3.5 255.255.255.252 R1 eth3 192.168.10.2 255.255.255.252 R2 eth1 192.168.3.1 255.255.255.252 R2 eth2 192.168.1.254 255.255.255.0 R3 eth1 192.168.3.6 255.255.255.252 R3 eth2 192.168.2.254 255.255.255.0 表2-5 交换机连接设置 交换机 接口 连接设备 S1 eth1 R2 eth2 S2 eth3 S3 eth4 H1 eth5 H2 S2 eth1 S1 eth2 H3 eth3 H4 eth4 S3 S3 eth1 S1 eth2 H5 eth3 H6 eth4 S2 S4 eth1 R3 eth2 H7 eth3 H8 2DHCP自动配置
网络配置采用自动配置有诸多的优点下面列举了一些
可以很容易地在网络中添加新的客户端。
IP地址是由DHCP集中管理的。
IP地址可以重复使用从而减少了对IP地址总数的要求。
DHCP服务器上的IP地址空间可以很容易地进行重新配置而不需要单独重新配置客户端。
网络管理员可以利用DHCP协议提供的方法从集中区域配置网络。
综上我们网络采用DHCP的配置方式。
2.3网络技术和原理
SDN
1SDN的网络体系架构
应用层这一层主要是体现用户意图的各种上层应用程序此类应用程序称为协同层应用程序典型的应用包括OSSOperation support system 运营支撑系统、Openstack等。传统的IP网络同样具有转发平面、控制平面和管理平面SDN网络架构也同样包含这3个平面只是传统的IP网络是分布式控制的而SDN网络架构下是集中控制的。
控制层控制层是系统的控制中心负责网络的内部交换路径和边界业务路由的生成并负责处理网络状态变化事件。
转发层转发层主要由转发器和连接器的线路构成基础转发网络这一层负责执行用户数据的转发转发过程中所需要的转发表项是由控制层生成的。
北向接口应用层和控制层通信的接口应用层通过控制开放的API控制设备转发功能
南向接口控制层和数据层通信的接口控制器通过OpenFlow或其他协议下发流表 图2-3 SDN架构示意图
2SDN的主要特征
转控分离网元的控制平面在控制器上负责协议计算产生流表而转发平面只在网络设备上。
集中控制设备网元通过控制器集中管理和下发流表这样就不需要对设备进行逐一操作只需要对控制器进行配置即可。
开放接口第三方应用只需要通过控制器提供的开放接口通过编程方式定义一个新的网络功能然后在控制器上运行即可。
SDN控制器既不是网管也不是规划工具
网管没有实现转控分离网管只负责管理网络拓扑、监控设备告警和性能、下发配置脚本等操作但这些仍然需要设备的控制平面负责产生转发表项。
STP
生成树协议英语Spanning Tree ProtocolSTP是一种工作在OSI网络模型中的第二层(数据链路层)的通信协议基本应用是防止交换机冗余链路产生的环路。用于确保以太网中无环路的逻辑拓扑结构。从而避免了广播风暴,大量占用交换机的资源。
在SDN中如果Mininet建立的拓扑中存在交换机环路则如果利用普通的Ryu Learning Switch APP进行ryu-manager部署会出现ping、pingall不通的问题其原因在于环路中出现了广播风暴。为了在Mininet中使用带有环路的拓扑需要让交换机开启STP协议。
STP协议实现的关键是BDPU封包通过传送该包发现环路决定交换机的哪些端口需要Forward哪些需要Block。下图展示了BDPU包的传送过程。 图2-4 STP协议实现关键-BDPU包
OPSF路由
开放式最短路径优先Open Shortest Path FirstOSPF是广泛使用的一种动态路由协议它属于链路状态路由协议具有路由变化收敛速度快、无路由环路、支持变长子网掩码VLSM和汇总、层次区域划分等优点。
在网络中使用OSPF协议后大部分路由将由OSPF协议自行计算和生成无须网络管理员人工配置当网络拓扑发生变化时协议可以自动计算、更正路由极大地方便了网络管理。
OSPF协议依靠五种不同类型的分组来建立邻接关系和交换路由信息即问候分组、数据库描述分组、链路状态请求分组、链路状态更新分组和链路状态确认分组 图2-5 OSPF协议的5种分组及功能
NAT
NAPT在进行地址转换的同时还进行端口转换可以实现多个私网用户共同使用一个公网IP地址上网。NAPT根据端口来区分不同用户真正做到了地址复用。 图2-6 NAPT原理图
当Host访问Web Server时设备的处理过程如下
1.设备收到Host发送的报文后查找NAT策略发现需要对报文进行地址转换。
2.设备根据源IP Hash算法从NAT地址池中选择一个公网IP地址替换报文的源IP地址同时使用新的端口号替换报文的源端口号并建立会话表然后将报文发送至Internet。
3.设备收到Web Server响应Host的报文后通过查找会话表匹配到步骤2中建立的表项将报文的目的地址替换为Host的IP地址将报文的目的端口号替换为原始的端口号然后将报文发送至Intranet。
WIFI
①WLAN仿真平台
WLAN部分使用Mininet-WiFi进行仿真。Mininet-WiFi 是 Mininet SDN 网络仿真器的一个分支通过添加基于标准 Linux 无线驱动程序和 80211_hwsim 无线仿真驱动程序的虚拟化 WiFi 站和接入点来扩展 Mininet 的功能。这意味着已添加新类以支持在 Mininet 网络场景中添加这些无线设备并模拟移动站的属性例如相对于接入点的位置和移动。
下图描述了一个简单拓扑结构中的组件和连接其中有两个站点或主机是使用 Mininet-WiFi 创建的其中新实现的组件以灰色突出显示沿原始 Mininet 构建块显示。尽管工作站默认配备无线接口但它们也可以通过有线链路veth 对与接入点连接。 图2-7 一个简单拓扑结构中的组件和连接[1] ②无线站点
站sta是通过身份验证和关联连接到接入点的设备。在Mininet-WiFi中每个站都有一个无线网卡staX-wlan0其中 X 为每个站的编号。
③接入点AP
AP是管理关联站的设备。通过 hostapd 守护程序进行虚拟化并将虚拟无线接口用于接入点和身份验证服务器。Mininet-WiFi 当前包括对用户空间参考实现和内核和用户空间模式下的 Open vSwitch 的支持。
无线站点和接入点都使用 cfg80211 与无线设备驱动程序通信这是一个 Linux 802.11 配置 API可提供工作站与 mac80211 之间的通信。该框架反过来通过用于配置 cfg80211 设备和内核-用户空间通信的 netlink 套接字或更具体地说是 nl80211直接与 WiFi 设备驱动程序通信。[1]
④频谱分析
仿真使用802.11b标准在下图给出的例子中可以看出802.11b标准是如何在2.4835Ghz的2.4GHz频段上定义13个信道每个信道分配22MHz间隔5MHz。可以看出通过这种安排只有通道 1、6 和 11 可以在没有频带重叠的情况下运行。 正在上传…重新上传取消图2-8 802.11b中信道定义情况[2]
⑤主动扫描与被动扫描
对于一个站点来说如果希望连接到AP首先必须发现AP。发现的方式就两种被动扫描passive scan和主动扫描active scan。
通俗地讲主动即“搜”是指sta每隔一段时间发送probe request帧用来询问AP的信息probe request可以单独发给某个AP也可以在一个信道上进行广播多数时候是在一个信道上进行广播广播完成后会在当前信道等待一段时间如果收到帧反馈则做记录如果超时就会切换到下个信道进行广播。
被动即“听”是指手机被动的接收AP发出的beacon帧通过解析beacon帧中的信息来获取当前AP列表。手机在监听beacon帧的时候也不停切换信道保证每个信道都能监听到。这种模式下只监听beacon帧不发送探测帧比较节省资源不过获取AP列表时间相对较长不如主动扫描获得信息更及时。
客户端如果通过主动扫描发现很多AP具有相同SSID它会根据信号强度和信号质量选择最佳的AP连接通常客户端还会持续在其他信道发送probe request以得到一个可用AP的list用于漫游。这是我们后续使用的“后台扫描”原理。
6防火墙技术
它是一种位于内部网络与外部网络之间的网络安全系统。是一项信息安全的防护系统依照特定的规则允许或是限制传输的数据通过。
网络层防火墙可视为一种 IP 封包过滤器运作在底层的TCP/IP协议堆栈上。可以以枚举的方式只允许符合特定规则的封包通过其余的一概禁止穿越防火墙病毒除外防火墙不能防止病毒侵入。这些规则通常可以经由管理员定义或修改不过某些防火墙设备可能只能套用内置的规则。
下图展示了防火墙的设置规则通过设置能透过数据报文的源和目的以及通过协议类型和操作类型来设置防火墙。 图2-9 防火墙技术的原理示意图
应用层防火墙是在 TCP/IP 堆栈的“应用层”上运作您使用浏览器时所产生的数据流或是使用 FTP 时的数据流都是属于这一层。应用层防火墙可以拦截进出某应用程序的所有封包并且封锁其他的封包通常是直接将封包丢弃。理论上这一类的防火墙可以完全阻绝外部的数据流进到受保护的机器里。
7DHCP
1. DHCP的原理
DHCP(Dynamic Host Configuration Protocol动态主机配置协议)是一个局域网的网络协议使用UDP协议工作 主要有两个用途给内部网络或网络服务供应商自动分配IP地址给用户或者内部网络管理员作为对所有计算机作中央管理的手段。
DHCP的整个工作流程如下图所示主要有四个阶段 图2-10 DHCP工作流程
1发现阶段DHCP客户端以广播的形式寻找DHCP服务器。
2提供阶段接收到DHCP Discover的服务器都会响应DHCP服务器从未出租的IP地址中挑选一个给客户端发送DHCP Offer包。
3选择阶段DHCP客户端选择第一个收到的DHCP Offer包信息来接收以广播方式回答一个DHCP Request请求信息。
4确认阶段被选择的DHCP服务器确认所提供的IP地址发送DHCP Ack未被选择的服务器回收曾提供的IP地址。
2.DHCP的工作方式
1下载一个DHCP服务器。
2下面有两种方式
1.直接修改步骤1中的DHCP服务器的dhcpd.conf文件此方法可以通过编写subnet进行DHCP中继但有一个使用前提为当前拓扑能够ping通。
2.自己在各个子网中搭建分DHCP服务器并自主生成各个服务器的.conf和发送端的.log文件。此方式在拓扑无法ping通的情况下仍可以实现DHCP服务。
本次选用的是步骤2中的第二个方法。
3.网络配置
在上述子网1和子网2中分别选用一台主机作为DHCP服务器本次实验子网1选用的是h1子网2选用的是h7。
三、课程设计方案
3.1 SDN设计方案
SDN的架构我们采用mininetRYU 的方式使用RYU控制器控制我们网络拓扑里面的交换机以此来下发流表。 图3-1 SDN架构拓扑结构
注左侧WIFI部分实际拓扑以图2-2为准
图3-1中使用的控制器C0,C1皆是远程控制器RYU下图3-2是RYU控制器的结构示意图。 图3-2 RYU架构
此外由于控制器只能设定一个端口我们在实现防火墙应用程序的时候增加了控制器C1。
3.2 OSPF设计方案
我们没有选择使用openflow交换机通过流表来实现路由因为我们发现它能实现的前提是整个网络的ip都是由统一的大地址划分而来。而使用专门的ospf路由协议则没有这样的限制。
OSPF的设计我们采用了quagga软件它可以将linux设备变成一个功能完整的路由器。支持ripospfbgp等协议。这里我们只使用它的ospf功能。 图3-3 ospf运行流程示意图
上图中的ospfd守护进程负责ospf协议的路由更新而zebra守护进程则负责更新内核的路由表。 图3-4 ospf相关文件配置情况
3.3 STP的设计方案
我们设计的校园网络中涉及到实验室场景的模拟。我们希望实验室区域的网络拥有充足的健壮性所以我们设计了环路希望正常情况能防止环路形成特殊情况某条链路断开能恢复连通性保证网络畅通。 aaaaaa
图3-5 STP拓扑设计方案示意图
如图所示的形成环路的三台交换机都连接了同一个ryu控制器c0那么我们只需要ryu对应的模块上进行设定就可以实现stp协议。
3.4 DHCP的设计方案
1尝试过的方案——DHCP
1.配置信息 图3-6 DHCP建立流程图
创建两台unbantu18.0的虚拟机AB在一台虚拟机A上面配置DHCPservever使其成为DHCP服务器而在虚拟机B上搭建拓扑使用添加网卡的方式使得两台虚拟机实现互通使得虚拟机B上面中mininet的主机能够访问虚拟机A从而实现DHCP的功能。
2.存在着的问题
此方法能够实现对虚拟机B的IP地址的自动分配但无法实现对mininet中的主机进行IP地址的自动分配。
自我诊断原因由于一开始IP地址的缺失导致虚拟机B上的网络处于ping不通的未完成状态因此即使虚拟机A能够实现与虚拟机B的通信但无法进行对未完成状态的网络进行DHCP。
最终使用的方案——DHCP
1.配置信息 图3-7 DHCP建立流程图
本方案使用1台虚拟机A在此台虚拟机上配置DHCP服务器在每个需要DHCP的子网中选取一台主机作为该子网的DHCP服务器然后规定该子网的地址池最后生成上述DHCP服务器的独有的.conf文件。当请求方发出请求时会生成对该主机的.log文件然后对DHCP服务器进行相应使用mininet中host.defaultIntf.updateIP()函数进行IP地址的更新。
实现的方案——DHCP中继未使用
1.配置信息 图3-8 DHCP中继建立流程图
在2中的DHCP基础之上对虚拟机中配置的DHCP服务器自带的dhcpd.conf进行地址池的配置——加入sudnet其余与.conf文件的配置一致。
此方案无需在各个子网中单独设置DHCP服务器只需在整个拓扑上层直接使用下载的DHCP服务器即可。
最终能够实现各个子网的IP地址的分配即实现了DHCP中继。
2.发现的问题
此方案需要在各个子网中以及子网之间均需要能够ping通所以在初始化网络的各项配置的阶段无法使用因此没有将此功能加入网络拓扑。 3.5 NAT的设计方案
NAPT的设计方案是采用Mininet自带的NAT类型结点通过将此节点的接口与虚拟机的网卡绑定实现自动的NAPT转换同时与外网通信。并且实现从虚拟机访问Mininet的设备。 图3-9 NAPT流程图
结合整个网络的拓扑最终的NAPT方案如下 图3-10 NAPT实现拓扑图
3.6防火墙的设计方案
防火墙的设计我们采用的是MininetRYU的方式RYU运行防火墙程序。如下图所示在拓扑的右侧当中是我们设置的防火墙控制器交换机S4运行防火墙程序阻塞不能通过
的流表。其中运行防火墙的控制器和另一个RYU控制器C0不是同一控制器因为同一个控制器运行两个程序会存在冲突所以采用了两台控制器。 图3-11 防火墙拓扑设计方案示意图
RYU控制器的防火墙程序是自带的rest_firewall.py文件可以通过RESTAPI连接到RYU控制器防火墙后台设置下发的规则下图是可以设置过滤的报文的类型和内容。 图3-12 rest_firewal.py文件可以设置的类型和内容
3.7 WIFI的设计方案
WLAN中我们计划使用三个AP每个AP有三个站点对应连接。AP与站点的空间位置关系如下图所示 图3-13 无线网络中的接入点与站点物理位置示意 容易看出三个AP的覆盖范围存在交叠。为了避免交叠带来信号冲突从而导致无线网络效率下降我们将这三个AP的信道分别配置成1、6和11。这样三个AP发射的信号在频谱上就完全没有交叠。具体的原理我们在之前的原理介绍部分已经提到了在此将频谱图复现。 图3-14 802.11b中信道定义情况[2] 三个AP拥有相同的SSID统一命名为’handover’并且使用WPA-2认证使用‘123456789a’作为密码。
终端配置使用后台扫描(bgscan)完成在ESS内的漫游。配置后bgscan将以定期和预配置的时间间隔搜索与客户端当前关联的接入点相比具有最佳信号的接入点。如果找到具有最佳信号的接入点bgscan将启动客户端与接入点之间的关联过程。信号质量优良的判断原则有信号强度、负载大小等此处我们选用信号强度作为信号质量优良判断的原则即终端在选择AP时遵循信号最强AP优先原则。
本组最初的方案是使用Mininet-WiFi直接完成网络中所有模块和功能的配置但Mininet-WiFi与本组使用的zebra等其他工具会发生冲突且我们在有限的时间无法解决这个问题导致我们必须把WLAN部分与网络的其他部分分离开分开运行两个网络以避免冲突。
但将网络分开后无法避免的一个问题就是如何将WLAN部分接入其余网络。我们借助了所谓的隧道技术原理是Mininet内的出口OVSOpen vSwitch占用宿主机ubuntu主机网卡从而达到Mininet内虚拟主机与ubuntu宿主机在网络中同等地位的目的。为了实现这一技术我们首先需要在两个Ubuntu虚拟机上各再创建一张新的网卡。创建网络卡后虚拟机可以用如下示意图表示 图3-15 为两台虚拟机新加网卡 再将两张网卡Ubuntu1的ens34和Ubuntu2的ens32桥接在一起即可。这样Mininet-WiFi就作为有线网络交换机S1下的一个局域网的一部分了。
综上所述WLAN部分设计详细拓扑如下 图3-16 WLAN详细拓扑设备接口连接情况 四、课程设计配置与实现
4.1 SDN设计配置与实现
SDN采用RYU控制器和mininet的方式交换机采用的是openflow13协议。
配置
主要是涉及Mininet和RYU控制器的安装一起路由定义软件Quagga的安装和配置。
详细的配置步骤在网络上都可以找到在此不在叙述。
实现
第一步打开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 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 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 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)
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包 …… …… 2实现
由于是直接在ryu控制器中进行设置那么无需在拓扑代码中再进行设置直接运行拓扑文件final.py文件即可。 图4-2启动stp操作示意图 4.4 DHCP设计配置与实现
DHCP采用的是下载额外的DHCP服务器然后通过mininet自带的host.defaultIntf.updateIP()函数进行IP地址的更新。
配置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 )
实现
主要流程如下图 图4-3 DHCP运行流程图
下面介绍各个流程核心代码 地址池的设置例子 DNSTemplate start #开始IP end #结束IP option subnet #子网掩码 option domain local option lease 7 # seconds 创建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 ) ) 启动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 21 % 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 21, 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分配结束。 4.5 NAT配置与实现
NAPT的配置在拓扑代码里实现。通过以下代码在拓扑中加入NAT节点。 NAT节点添加代码 nat0 self.addNode(nat0, clsNAT, ip192.168.10.1/30, subnet192.168.0.0/16, inNamespaceFalse)
其中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)
通过以上配置之后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, datadata1) response requests.post(http://127.0.0.1:8080/firewall/rules/0000000000000004, datadata2) response requests.post(http://127.0.0.1:8080/firewall/rules/0000000000000004, datadata3) response requests.post(http://127.0.0.1:8080/firewall/rules/0000000000000004, datadata4) 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 启动防火墙操作示意图
通过直接运行firewall.py文件或者命令行方式设置防火墙过滤的规则图4-5 启动设置防火墙规则操作示意图
4.7 WIFI配置与实现
WLAN部分的实现以代码为主以下展示具体的实现思路和核心代码。
1设置网络类型为Mininet-WiFi并配置控制器 设置网络类型为Mininet-WiFi并配置控制器 net Mininet_wifi(topoNone, buildFalse, linkwmediumd , wmediumd_modeinterference) info(***Adding controllerln ) c1 net.addController( name c1 ,controllerController, protocol tcp ,port6653) 2配置AP的名称、MAC地址、SSID、信道编号、加密方式、密码和物理位置。 配置AP以AP1为例 ap1 net.addAccessPoint( ap1, mac00:00:00:00:00:01, ssidhandover,modeg, channel1, passwd 123456789a,encryptwpa2, position123.0,323.0,0) 3配置站点的名称、IP地址、物理位置、扫描信号强度门限、短间隔、长间隔和扫描模式。 配置站点以sta1为例 sta1 net.addStation( sta1, ip 192.168.4.1/24,position 54.0,434.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) 4设置无线信号的指数传播模型 设置无线信号的指数传播模型 net.setPropagationModel( modellogDistance , exp3) 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 ) 五、课程设计验证与结果分析
5.1 SDN的验证和结果分析
1操作验证分析 图5-1 RYU控制器运行simple_switch_13.py程序
从图5-2中可以看到已经连接到控制器C0控制器C1还未连接到的原因是控制器C1还没有运行防火墙程序后续会讲到。 图5-2 拓扑对于远程控制器的反应
2实验验证
后续防火墙技术STPOSPFDHCP的成功也可以验证SDN。
5.2 OSPF的验证与结果分析
1路由表项对比分析
在主机通过dhcp分配到ip后ospf协议开始运行以路由器R3的路由表为例网络收敛前的表项 图5-3 R3未收敛时的路由表项展示图
经过约40s后路由完全收敛再次查看R3的路由表 图5-4 R3收敛后的路由表项展示图
2抓包分析
用wireshark抓包后我们发现有大量的ospf的hello报文 图5-5ospf运行时报文展示
3网路ping测试
从下图中可以看到在路由收敛前只有在同一子网中的主机可以ping通跨子网的主机ping不通。 图5-6 路由收敛前的pingall情况
当路由收敛后不同子网下的主机也能ping通不通的为防火墙规则 图5-7 路由收敛后的pingall情况
5.3 STP的验证与结果分析
1流表分析
运行ryu和拓扑代码后开始运行stp 图5-8 stp运行时产生的流表输出
经过约40s后s链路收敛流表输出中告知s3的port2被关闭 图5-9 R3链路收敛后的展示图
2抓包分析
用wireshark抓包后我们发现有大量的广播的stp报文 图5-10 stp运行时报文展示
3网路ping测试
从下图中可以看到stp协议运行成功 图5-11 stp收敛后的pingall情况
4异常情况测试
我们考虑stp的初衷是增强链路的健壮性设置冗余链路。这也要求当正常链路出现故障断开后网络也能保持联通。 所以我们以断开s2与s3的链路为例 图5-12 断开s2与 s3的链路
我们发现链路断开后网络发生了变化立刻有stp的流表输出说明网络正在计算新的拓扑。 图5-13链路变化后的流表输出
等stp重新收敛后进行pingall测试结果与链路变化前一致达到了设计目的 图5-14链路变化后的pinall情况
5.4 DHCP的验证与结果分析其中例子
1实验效果
在地址池设定如下的情况下 图5-15 地址池设定
实验结果如下 图5-16 实验过程图示
2结果分析
截获到如图所示的报文 图5-17 截获报文总览
对Discover报文进行分析 图5-18 Discover报文总览
由图可知广播地址为255.255.255.255Src为0.0.0.0设定需要DHCP服务主机的初始IP。
对offer报文进行分析: 图5-19 offer报文总览
Src为192.168.2.3即设定的该子网内的DHCP服务器的IP地址此时目的IP为255.255.255.255即进行广播其中附带了所分配的IP地址为192.168.2.20。
对Request报文进行分析: 图5-20 Request报文总览
此时Src仍为0.0.0.0发送方式为广播。
对ACK报文进行分析: 图5-21 ACK报文总览
此时可以看到Src为192.168.2.3重复了Your (client) IP address:192.168.2.20。
至此整个DHCP服务运行完成。
5.5 NAT的验证与结果分析
1内网ping外网连通性测试
同时使用网络中的h1和h2ping外网最终的连通性如下 图5-22 ping外网验证图
可以看到h1和h2都是可以成功ping通外网的。
2NAPT测试
之后我们再通过windows上的抓包可以验证h1和h2在ping外网时使用的是同一个IP地址。 图5-23 ping外网wireshark抓包图
上图中可以看到h1和h2都在使用192.168.137.136这一个地址ping外网。证明我们实现了NAPT功能。
3Linux虚拟机ping内部主机
我们在linux虚拟机中ping h1的IP地址其结果如下 图5-24 ping内网验证图
同时我们在wireshark的抓包中也能抓到相应的报文 图5-25 ping内网wireshark抓包图 5.6防火墙的验证与结果分析
1网络连通性测试
在整个网络进行pingall测试发现只有H1(应用环境中的教师主机)可以访问服务器H7和H8其余的主机和路由器是不能访问服务器的符合我们的预期的效果和设置的规则。 图5-26 防火墙pingall测试结果展示图
2流表分析
从交换机S4的流表中可以看出设置的四条规则的操作时正常的说明防火墙是默认阻塞所有的报文我们设置可以通过的IP流向的报文以此来达到防火墙目的。当然同时我们也可以设置默认所有的报文都可以通过设置不可以通过报文的规则。由于应用场景的需求我们采用了第一种方案。 图5-27交换机S4的流表展示
3控制器终端分析
从下图中可以看到控制器终端C1的返回结果相应的规则已经被加入到防火墙中。 图5-28 控制器C1终端防火墙规则设置返回结果
从控制终端的流表中也可以看到被阻塞的报文如下。只要是我们在防火墙程序中没有设置的规则都会被防火墙程序阻塞无法通过交换机S4。 图5-29 控制器C1的流表
5.7 WLAN的验证与结果分析
1网络连通性测试
由于pingall命令产生了非常多行结果这里只展示部分截图。pingall可以很直观地看出WLAN内部的连通性没有问题。 图5-30 WLAN中使用pingall命令测试结果的部分截图 2后台扫描结果演示
为了更清晰地演示后台扫描过程与结果此处只保留sta1一个站点并且我们改变了ap3的位置使得sta1与站点间的距离关系更加直观。
①如图sta1最初距离ap1最近。根据最强信号优先原则sta1应该关联ap1。 图5-31 后台扫描实验使用的网络拓扑 ②验证sta1确实关联ap1黄框内为ap1的MAC地址。 图5-32 后台扫描实验中设备关联最初情况 ③打开sta1命令行观察sta1后台扫描过程。 图5-33 后台扫描实验中打开sta1的终端 ④改变sta1的物理位置。 图5-34 后台扫描实验中改变sta1的位置 ⑤sta1后台扫描发现ap2。 图5-35 后台扫描实验中sta1发现ap2 ⑥能够看到实际上sta1与接入点的关联确实发生了变化。 图5-36 后台扫描实验中设备关联最终情况 3结果分析
通过上面的实验可以得到结论通过配置后台扫描参数终端能够在连接到某一个AP后仍然以某一个时间周期进行扫描并且主动连接到与当前AP的SSID相同且信号最强的AP。这说明我们配置的终端能够实现ESS内的漫游。
代码 附件2final.py网络拓扑DHCPNATSDN防火墙控制器设置 # !/usr/bin/python3 from mininet.topo import Topo from mininet.net import Mininet from mininet.node import Node from mininet.log import setLogLevel, info from mininet.cli import CLI import os from mininet.node import Controller, RemoteController, OVSController from mininet.link import TCLink from mininet.util import quietRun from mininet.term import makeTerms from sys import exit, stdin, argv from re import findall from time import sleep import time from mininet.nodelib import NAT class LinuxRouter(Node): A Node with IP forwarding enabled. def config(self, **params): super(LinuxRouter, self).config(**params) # Enable forwarding on the router self.cmd(sysctl net.ipv4.ip_forward1) def terminate(self): self.cmd(sysctl net.ipv4.ip_forward0) super(LinuxRouter, self).terminate() class NetworkTopo(Topo): A LinuxRouter connecting three IP subnets def build(self, **_opts): defaultIP1 192.168.3.2/30 # IP address for r1-eth1 defaultIP2 192.168.3.1/30 defaultIP3 192.168.3.6/30 router1 self.addNode(r1, clsLinuxRouter, ipdefaultIP1) router2 self.addNode(r2, clsLinuxRouter, ipdefaultIP2) router3 self.addNode(r3, clsLinuxRouter, ipdefaultIP3) nat0 self.addNode(nat0, clsNAT, ip192.168.10.1/30, subnet192.168.0.0/16, inNamespaceFalse) h1 self.addHost(h1, ip192.168.1.1/24, defaultRoutevia 192.168.1.254) # define gateway h2 self.addHost(h2, ip0.0.0.0/24, defaultRoutevia 192.168.1.254) h3 self.addHost(h3, ip0.0.0.0/24, defaultRoutevia 192.168.1.254) h4 self.addHost(h4, ip0.0.0.0/24, defaultRoutevia 192.168.1.254) h5 self.addHost(h5, ip0.0.0.0/24, defaultRoutevia 192.168.1.254) h6 self.addHost(h6, ip0.0.0.0/24, defaultRoutevia 192.168.1.254) h7 self.addHost(h7, ip192.168.2.1/24, defaultRoutevia 192.168.2.254) h8 self.addHost(h8, ip192.168.2.2/24, defaultRoutevia 192.168.2.254) h9 self.addHost(h9, ip0.0.0.0, defaultRoutevia 192.168.2.254) h10 self.addHost(h10, ip0.0.0.0, defaultRoutevia 192.168.2.254) h11 self.addHost(h11, ip0.0.0.0, defaultRoutevia 192.168.2.254) self.addLink(router1, router2, intfName1r1-eth1, intfName2r2-eth1) self.addLink(router3, router1, intfName1r3-eth1, intfName2r1-eth2, params2{ip: 192.168.3.5/30}) self.addLink(router1, nat0, intfName1r1-eth3, intfName2nat0-eth1,params1{ip: 192.168.10.2/30}) s1self.addSwitch(s1) s2self.addSwitch(s2) s3self.addSwitch(s3) s4self.addSwitch(s4) #s5self.addSwitch(s5) self.addLink(s1, router2, intfName2r2-eth2, params2{ip: 192.168.1.254/24}) self.addLink(s4, router3, intfName2r3-eth2, params2{ip: 192.168.2.254/24}) self.addLink(s1, s2) self.addLink(s1, s3) #self.addLink(s2, s3) self.addLink(s1, h1) self.addLink(s1, h2) self.addLink(s2, h3) self.addLink(s2, h4) self.addLink(s3, h5) self.addLink(s3, h6) self.addLink(s3, s2) #self.addLink(s4, s5) self.addLink(s4, h7) self.addLink(s4, h8) #self.addLink(s5, h7) #self.addLink(s5, h8) self.addLink(s4, h9) self.addLink(s4,h10) self.addLink(s4,h11) DNSTemplate start 192.168.1.2 end 192.168.1.6 option subnet 255.255.255.0 option domain local option lease 7 # seconds 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 ) ) 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 21 % host ) def stopDHCPserver( host ): Stop DHCP server on host info( * Stopping DHCP server on, host, at, host.IP(), \n ) host.cmd( kill %udhcpd ) # DHCP client functions 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 21, intf, ) def stopDHCPclient( host ): host.cmd( kill %dhclient ) def waitForIP( host ): Wait for an IP address info( *, host, waiting for IP address ) while True: host.defaultIntf().updateIP() #print(host.IP()) if host.IP(): break info( . ) sleep(1) info( \n ) def readline(): Read a line from stdin return stdin.readline() def prompt( sNone ): Print a prompt and read a line from stdin if s is None: s Press return to continue: print (s), return readline() def DHCP(host,dhcp): Rogue DHCP server demonstration startDHCPserver( dhcp, gw192.168.1.254, dns8.8.8.8) startDHCPclient( host ) waitForIP( host ) print(host.IP()) stopDHCPserver( dhcp ) stopDHCPclient( host ) def usage(): Print usage message print (%s [ -h | -text ]) print (-h: print this message) print (-t: run in text/batch vs. firefox/x11 mode) def run(): topo NetworkTopo() net Mininet(topotopo, buildFalse,controllerRemoteController) c0net.addController(c0,ip127.0.0.1,port6633) #ryu controller c1net.addController(c1,ip127.0.0.1,port6634) #ryu controller net.build() net.start() #net.get(s1).start([c0]) h10 net.getNodeByName( h10) dhcp net.getNodeByName(h1) h11 net.getNodeByName(h11) h8 net.getNodeByName( h8) h2 net.getNodeByName( h2) h3 net.getNodeByName( h3) h4 net.getNodeByName( h4) h5 net.getNodeByName( h5) h6 net.getNodeByName( h6) h9 net.getNodeByName( h9) s1 net.getNodeByName( s1) s2 net.getNodeByName( s2) s3 net.getNodeByName( s3) s4 net.getNodeByName( s4) #net.get(s4).start([c1])ss DHCP(h2,dhcp) DHCP(h3,dhcp) DHCP(h4,dhcp) DHCP(h5,dhcp) DHCP(h6,dhcp) #os.popen(ovs-vsctl add-port s1 ens36) net.get(s1).start([c0]) net.get(s2).start([c0]) net.get(s3).start([c0]) net.get(s4).start([c1]) #DHCP(h9,dhcp) #DHCP(h10,dhcp) #DHCP(h11,dhcp) info(*** Routing Table on Router:\n) r1 net.getNodeByName(r1) r2 net.getNodeByName(r2) r3 net.getNodeByName(r3) nat0 net.getNodeByName(nat0) s1 net.getNodeByName(s1) s2 net.getNodeByName(s2) s3 net.getNodeByName(s3) #s1.cmd(ovs-vsctl set bridge s1 stp_enabletrue) #s2.cmd(ovs-vsctl set bridge s2 stp_enabletrue) #s3.cmd(ovs-vsctl set bridge s3 stp_enabletrue) info(starting zebra and ospfd service:\n) 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) 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) CLI(net) net.stop() os.system(killall -9 ospfd zebra) os.system(rm -f /tmp/*.api) os.system(rm -f /tmp/*.interface) if __name__ __main__: setLogLevel(info) # setLogLevel(debug) run() 附件3WLAN.py # ! /usr/binpython from mininet.node import Controller, ovSKernelSwitch from mininet.log import setLogLevel, info from mn_wifi.net import Mininet_wifi from mn_wifi.node import Station, ovSKernelAPfrom mn_wifi.cli import CLI from mn_wifi.link import wmediumd from mn_wifi.wmediumdConnector import interference from subprocess import call from mininet.nodelib import NAT import os def myNetwork( ): net Mininet_wifi(topoNone, buildFalse, linkwmediumd , wmediumd_modeinterference) info(***Adding controllerln ) c1 net.addController( name c1 ,controllerController,protocol tcp ,port6653) info(***Add switches/APs\n ) ap1 net.addAccessPoint( ap1, mac00:00:00:00:00:01, ssidhandover,modeg, channel1, passwd 123456789a,encryptwpa2, position123.0,323.0,0) ap2 net.addAccessPoint( ap2 , mac00:00:00:00:00:02 , ssidhandover ,modeg , channel6,passwd 123456789a,encryptwpa2, position375.0, 332.0,0) ap3 net.addAccessPoint( ap3 , mac00:00:00:00:00:03, ssidhandover ,nodeg, channel1,passwd 123456789a,encryptwpa2, position 606.0,313.0,0) s2 net. addSwitch( s2 , clsovSKernelSwitch) info(***Add hosts/stations\n ) sta1 net.addStation( sta1, ip 192.168.4.1/24,position 54.0,434.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) sta2 net.addStation( sta2 , ip 192.168.4.2/24 ,position 156.0,433.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) sta3 net. addStation( sta3 , ip 192.168.4.3/24,position 321.0,435.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) sta4 net.addStation( sta4 , ip 192.168.4.4/24,position430.0,433.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) sta5 net.addStation( sta5 , ip 192.168.4.5/24,position 555.0,429.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) sta6 net.addStation( sta6 , ip 192.168.4.6/24 ,position 556,430,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie) nat0net. addHost( nat0 ,clsNAT, ip 192.168.4.8/24 , subnet 192.168.4.0/24,inNamespaceFalse) net. addLink(nat0,s1) info( ***Configuring Propagation Model\n ) net.setPropagationModel( modellogDistance , exp3) info( ***Configuring wifi nodes\n ) net . configurewifiNodes( ) info(·***Add linksln )net. addLink( s1, s2) net.addLink(ap1, s2) net.addLink(s2, ap2) net. addLink(s2, ap3) net.plotGraph( max_x1000,max_y1000) info(***Starting networkin ) net. start() os. popen( ovs-vsctl add-port s1 ens34 ) CLI(net) net.stop( ) ifname____main__: setLogLevel( info) myNetwork( ) 附件4 Rest_firewall.pyRyu控制器防火墙程序 由于代码程序过长打包成文件一起发送 附件5 Simple_switch_13.pyRyu控制器路由程序STP from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER from ryu.controller.handler import set_ev_cls from ryu.ofproto import ofproto_v1_3 from ryu.lib.packet import packet from ryu.lib.packet import ethernet from ryu.lib.packet import ether_types from ryu.lib import stplib #change!!!!! class SimpleSwitch13(app_manager.RyuApp): OFP_VERSIONS [ofproto_v1_3.OFP_VERSION] _CONTEXTS {stplib: stplib.Stp} ##change!!!!!!! def __init__(self, *args, **kwargs): super(SimpleSwitch13, self).__init__(*args, **kwargs) self.mac_to_port {} set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) def switch_features_handler(self, ev): datapath ev.msg.datapath ofproto datapath.ofproto parser datapath.ofproto_parser # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. The bug has been fixed in OVS v2.1.0. match parser.OFPMatch() actions [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] self.add_flow(datapath, 0, match, actions) def add_flow(self, datapath, priority, match, actions, buffer_idNone): ofproto datapath.ofproto parser datapath.ofproto_parser inst [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] if buffer_id: mod parser.OFPFlowMod(datapathdatapath, buffer_idbuffer_id, prioritypriority, matchmatch, instructionsinst) else: mod parser.OFPFlowMod(datapathdatapath, prioritypriority, matchmatch, instructionsinst) datapath.send_msg(mod) #set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) set_ev_cls(stplib.EventPacketIn, MAIN_DISPATCHER)#change!!!!!!! def _packet_in_handler(self, ev): # If you hit this you might want to increase # the miss_send_length of your switch if ev.msg.msg_len ev.msg.total_len: self.logger.debug(packet truncated: only %s of %s bytes, ev.msg.msg_len, ev.msg.total_len) msg ev.msg datapath msg.datapath ofproto datapath.ofproto parser datapath.ofproto_parser in_port msg.match[in_port] pkt packet.Packet(msg.data) eth pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst eth.dst src eth.src dpid format(datapath.id, d).zfill(16) self.mac_to_port.setdefault(dpid, {}) self.logger.info(packet in %s %s %s %s, dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] in_port if dst in self.mac_to_port[dpid]: out_port self.mac_to_port[dpid][dst] else: out_port ofproto.OFPP_FLOOD actions [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port ! ofproto.OFPP_FLOOD: match parser.OFPMatch(in_portin_port, eth_dstdst, eth_srcsrc) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod packet_out if msg.buffer_id ! ofproto.OFP_NO_BUFFER: self.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: self.add_flow(datapath, 1, match, actions) data None if msg.buffer_id ofproto.OFP_NO_BUFFER: data msg.data out parser.OFPPacketOut(datapathdatapath, buffer_idmsg.buffer_id, in_portin_port, actionsactions, datadata) datapath.send_msg(out)
网络拓扑
# !/usr/bin/python3
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.log import setLogLevel, info
from mininet.cli import CLI
import os
from mininet.node import Controller, RemoteController, OVSController
from mininet.link import TCLink
from mininet.util import quietRun
from mininet.term import makeTerms
from sys import exit, stdin, argv
from re import findall
from time import sleep
import time
from mininet.nodelib import NAT
class LinuxRouter(Node):A Node with IP forwarding enabled.def config(self, **params):super(LinuxRouter, self).config(**params)# Enable forwarding on the routerself.cmd(sysctl net.ipv4.ip_forward1)def terminate(self):self.cmd(sysctl net.ipv4.ip_forward0)super(LinuxRouter, self).terminate()class NetworkTopo(Topo):A LinuxRouter connecting three IP subnetsdef build(self, **_opts):defaultIP1 192.168.3.2/30 # IP address for r1-eth1defaultIP2 192.168.3.1/30defaultIP3 192.168.3.6/30router1 self.addNode(r1, clsLinuxRouter, ipdefaultIP1)router2 self.addNode(r2, clsLinuxRouter, ipdefaultIP2)router3 self.addNode(r3, clsLinuxRouter, ipdefaultIP3)nat0 self.addNode(nat0, clsNAT, ip192.168.10.1/30, subnet192.168.0.0/16, inNamespaceFalse)h1 self.addHost(h1, ip192.168.1.1/24, defaultRoutevia 192.168.1.254) # define gatewayh2 self.addHost(h2, ip0.0.0.0/24, defaultRoutevia 192.168.1.254)h3 self.addHost(h3, ip0.0.0.0/24, defaultRoutevia 192.168.1.254)h4 self.addHost(h4, ip0.0.0.0/24, defaultRoutevia 192.168.1.254)h5 self.addHost(h5, ip0.0.0.0/24, defaultRoutevia 192.168.1.254)h6 self.addHost(h6, ip0.0.0.0/24, defaultRoutevia 192.168.1.254)h7 self.addHost(h7, ip192.168.2.1/24, defaultRoutevia 192.168.2.254)h8 self.addHost(h8, ip192.168.2.2/24, defaultRoutevia 192.168.2.254)h9 self.addHost(h9, ip0.0.0.0, defaultRoutevia 192.168.2.254)h10 self.addHost(h10, ip0.0.0.0, defaultRoutevia 192.168.2.254)h11 self.addHost(h11, ip0.0.0.0, defaultRoutevia 192.168.2.254)self.addLink(router1, router2, intfName1r1-eth1, intfName2r2-eth1)self.addLink(router3, router1, intfName1r3-eth1, intfName2r1-eth2,params2{ip: 192.168.3.5/30})self.addLink(router1, nat0, intfName1r1-eth3, intfName2nat0-eth1,params1{ip: 192.168.10.2/30})s1self.addSwitch(s1)s2self.addSwitch(s2)s3self.addSwitch(s3)s4self.addSwitch(s4)#s5self.addSwitch(s5)self.addLink(s1, router2, intfName2r2-eth2,params2{ip: 192.168.1.254/24})self.addLink(s4, router3, intfName2r3-eth2,params2{ip: 192.168.2.254/24})self.addLink(s1, s2)self.addLink(s1, s3)#self.addLink(s2, s3)self.addLink(s1, h1)self.addLink(s1, h2)self.addLink(s2, h3)self.addLink(s2, h4)self.addLink(s3, h5)self.addLink(s3, h6)self.addLink(s3, s2)#self.addLink(s4, s5)self.addLink(s4, h7)self.addLink(s4, h8)#self.addLink(s5, h7)#self.addLink(s5, h8)self.addLink(s4, h9)self.addLink(s4,h10)self.addLink(s4,h11)DNSTemplate
start 192.168.1.2
end 192.168.1.6
option subnet 255.255.255.0
option domain local
option lease 7 # seconds
def makeDHCPconfig( filename, intf, gw, dns ):Create a DHCP configuration fileconfig (interface %s % intf,DNSTemplate,option router %s % gw,option dns %s % dns, )with open( filename, w ) as f:f.write( \n.join( config ) )def startDHCPserver( host, gw, dns ):Start DHCP server on host with specified DNS serverinfo( * Starting DHCP server on, host, at, host.IP(), \n )dhcpConfig /tmp/%s-udhcpd.conf % hostmakeDHCPconfig( dhcpConfig, host.defaultIntf(), gw, dns )host.cmd( udhcpd -f, dhcpConfig,1/tmp/%s-dhcp.log 21 % host )def stopDHCPserver( host ):Stop DHCP server on hostinfo( * Stopping DHCP server on, host, at, host.IP(), \n )host.cmd( kill %udhcpd )# DHCP client functionsdef startDHCPclient( host ):Start DHCP client on hostintf host.defaultIntf()host.cmd( dhclient -v -d -r, intf )host.cmd( dhclient -v -d 1 /tmp/dhclient.log 21, intf, )def stopDHCPclient( host ):host.cmd( kill %dhclient )def waitForIP( host ):Wait for an IP addressinfo( *, host, waiting for IP address )while True:host.defaultIntf().updateIP()#print(host.IP())if host.IP():breakinfo( . )sleep(1)info( \n )def readline():Read a line from stdinreturn stdin.readline()def prompt( sNone ):Print a prompt and read a line from stdinif s is None:s Press return to continue: print (s),return readline()def DHCP(host,dhcp):Rogue DHCP server demonstrationstartDHCPserver( dhcp, gw192.168.1.254, dns8.8.8.8)startDHCPclient( host )waitForIP( host )print(host.IP())stopDHCPserver( dhcp )stopDHCPclient( host )def usage():Print usage messageprint (%s [ -h | -text ])print (-h: print this message)print (-t: run in text/batch vs. firefox/x11 mode)def run():topo NetworkTopo()net Mininet(topotopo, buildFalse,controllerRemoteController) c0net.addController(c0,ip127.0.0.1,port6633) #ryu controllerc1net.addController(c1,ip127.0.0.1,port6634) #ryu controllernet.build()net.start()#net.get(s1).start([c0])h10 net.getNodeByName( h10)dhcp net.getNodeByName(h1)h11 net.getNodeByName(h11)h8 net.getNodeByName( h8)h2 net.getNodeByName( h2)h3 net.getNodeByName( h3)h4 net.getNodeByName( h4)h5 net.getNodeByName( h5)h6 net.getNodeByName( h6)h9 net.getNodeByName( h9)s1 net.getNodeByName( s1)s2 net.getNodeByName( s2)s3 net.getNodeByName( s3)s4 net.getNodeByName( s4)#net.get(s4).start([c1])ssDHCP(h2,dhcp)DHCP(h3,dhcp)DHCP(h4,dhcp)DHCP(h5,dhcp)DHCP(h6,dhcp)#os.popen(ovs-vsctl add-port s1 ens36)net.get(s1).start([c0])net.get(s2).start([c0])net.get(s3).start([c0])net.get(s4).start([c1])#DHCP(h9,dhcp)#DHCP(h10,dhcp)#DHCP(h11,dhcp)info(*** Routing Table on Router:\n)r1 net.getNodeByName(r1)r2 net.getNodeByName(r2)r3 net.getNodeByName(r3)nat0 net.getNodeByName(nat0)s1 net.getNodeByName(s1)s2 net.getNodeByName(s2)s3 net.getNodeByName(s3)#s1.cmd(ovs-vsctl set bridge s1 stp_enabletrue)#s2.cmd(ovs-vsctl set bridge s2 stp_enabletrue)#s3.cmd(ovs-vsctl set bridge s3 stp_enabletrue)info(starting zebra and ospfd service:\n)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)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 socketr1.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)CLI(net)net.stop()os.system(killall -9 ospfd zebra)os.system(rm -f /tmp/*.api)os.system(rm -f /tmp/*.interface)if __name__ __main__:setLogLevel(info)# setLogLevel(debug)run()
WLAN代码
# ! /usr/binpython
from mininet.node import Controller, ovSKernelSwitch
from mininet.log import setLogLevel, info
from mn_wifi.net import Mininet_wifi
from mn_wifi.node import Station, ovSKernelAPfrom mn_wifi.cli
import CLI
from mn_wifi.link import wmediumd
from mn_wifi.wmediumdConnector import interference
from subprocess import call
from mininet.nodelib import NAT
import os
def myNetwork( ):
net Mininet_wifi(topoNone,buildFalse,linkwmediumd ,wmediumd_modeinterference)
info(***Adding controllerln )
c1 net.addController( name c1 ,controllerController,protocol tcp ,port6653)
info(***Add switches/APs\n )
ap1 net.addAccessPoint( ap1, mac00:00:00:00:00:01, ssidhandover,modeg, channel1, passwd 123456789a,encryptwpa2, position123.0,323.0,0)
ap2 net.addAccessPoint( ap2 , mac00:00:00:00:00:02 , ssidhandover ,modeg , channel6,passwd 123456789a,encryptwpa2, position375.0, 332.0,0)
ap3 net.addAccessPoint( ap3 , mac00:00:00:00:00:03, ssidhandover ,nodeg, channel1,passwd 123456789a,encryptwpa2, position 606.0,313.0,0)
s2 net. addSwitch( s2 , clsovSKernelSwitch)
info(***Add hosts/stations\n )
sta1 net.addStation( sta1, ip 192.168.4.1/24,position 54.0,434.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
sta2 net.addStation( sta2 , ip 192.168.4.2/24 ,position 156.0,433.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
sta3 net. addStation( sta3 , ip 192.168.4.3/24,position 321.0,435.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
sta4 net.addStation( sta4 , ip 192.168.4.4/24,position430.0,433.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
sta5 net.addStation( sta5 , ip 192.168.4.5/24,position 555.0,429.0,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
sta6 net.addStation( sta6 , ip 192.168.4.6/24 ,position 556,430,0 , bgscan_threshold-60,s_inverval5, l_interval10,bgscan_modulesimpie)
nat0net. addHost( nat0 ,clsNAT, ip 192.168.4.8/24 , subnet 192.168.4.0/24,inNamespaceFalse)
net. addLink(nat0,s1)
info( ***Configuring Propagation Model\n )
net.setPropagationModel( modellogDistance , exp3)
info( ***Configuring wifi nodes\n )
net . configurewifiNodes( )
info(·***Add linksln )net. addLink( s1, s2)
net.addLink(ap1, s2)
net.addLink(s2, ap2)
net. addLink(s2, ap3)
net.plotGraph( max_x1000,max_y1000)
info(***Starting networkin )
net. start()
os. popen( ovs-vsctl add-port s1 ens34 )
CLI(net)
net.stop( )
ifname____main__:
setLogLevel( info)
myNetwork( )
参考资料
[1]Mininet-WiFi official guideline. https://mininet-wifi.github.io/
[2] R. R. Fontes, S. Afzal, S. H. B. Brito, M. A. S. Santos and C. E. Rothenberg, Mininet-WiFi: Emulating software-defined wireless networks, 2015 11th International Conference on Network and Service Management (CNSM), 2015, pp. 384-389, doi: 10.1109/CNSM.2015.7367387.