作者简介:毛从雷,在读研究生,研究方向sdn
一、摘要
5G时代的到来,带来的不仅仅是庞大的流量,卓越的速度,优越的性能。还有不可计数的数据包。这时对于有危害数据流量的检测将变得尤为重要。传统网络检测数据报的可用性目前已知的只有两种:ACL,防火墙。但是这两个都有着共同的缺点就是配置麻烦而且不易变动。但是SDN(软件定义网络)可以做到零配置灵活变动,而且可以实现数据报的在线实时检测。基于SDN可以实现数据包的在线提取,在线检测。
二、介绍
本文主要由数据采集,数据处理,建立模型与训练模型这三大块组成。这个都是在Ubuntu下进行,本文使用CNN卷积神经网络对获取的到的数据进行训练,并将训练好的模型保存。网络是SDN,控制器使用RYU,基础网络使用OVS搭,在启动RYU之后整个网络就开始运行了。这个时候控制器就会实时地检测这个网络里的数据流。由于是边缘网络的检测,于是在边缘网络的OVS交换机上不添加转发数据包到其他交换机的流表,这样做的是可以检测到流经他的所有的数据包(OVS交换机对于未知包的处理向控制器发送PacketIn数据包)此时在控制器里就可以接收到此数据包,对数据包拆解,提取需要的信息(特征),然后将提取到的特征列表传入到已经训练好的模型当中。对于输出的结果做判别。正常流做资源调度,不是正常的流即被判别为是攻击包就执行丢弃。最后做一个GUI界面用于展示实时的数据监测情况。
三、具体实现
(一)、实现方案
本文是基于Ubuntu16.04的。由于硬件设备的限制,于是只在一台电脑上开启了一台虚拟机。在虚拟机里开启Mininet,建立一个简单的网络用于测试,如下图4-1。采集外部数据包并向该网络发送数据包。该网络接收到后会交由控制器。控制器接收依据特征提取相应的信息并将其保存下来。经过数据的预处理将其传给预先训练好的模型当中。有模型预测得出结果。
图4-1 Mininet的基本图
图4-2 实施方案
(二)、实现原理
本文能够实现的基本是由于SDN(软件定义网络)的存在。由于SDN的网络在接受到一个陌生的数据包时将会通过Openflow协议向控制器发送PacketIn数据包。该数据包中包含了这个数据包的完整信息。控制器在接受到数据包后会解析其数据包的包装即数据包的各层信息。一层一层如同剥洋葱一样将数据包的各层信息收取出来。这样就可以依据提取出来的信息为该数据包建立流表。然后在通过Openflow协议向交换机下发PacketOut数据包。PacketOut包含了转发这个数据包的接口。
基于此原理就可以处理交换机递交上来的数据包,然后可以提取想要的信息。然后将其传递给训练好的模型,进行结果的预测。
图4-3是实现的原理图
图4-3 实现原理
(三)、实现步骤
1.数据的准备
使用20万条数据用来训练模型,使用8万条数据来测试模型,一共训练四次。数据从互联网获取。
使用工具(wireshark、scapy)截获当前的网络流量,将网络流量预先保存在本地。使用scapy将数据包发往Mininet的网络。这个适用于最终测试的数据。
2. SimpleSwitch的定制
由于Ryu有自己实现的SimpleSwitch版本于是在实现一个控制器的时候只要继承这个类就好了。但是由于它内部写了关于如何自学习mac的代码。由于抓取下来的代码的mac基本上都是一样的。于是当向Mininet网路传入第一个数据包的时候那么交换机就已经学到了mac。当向Mininet网路传送第二个数据包的时候此时控制器是接收不到任何的数据包的,因为数据包已经通过交换机的本地流表转发了。于是为了解决这个问题,设计出了另一个版本的SimpleSwitch。
使用了此SimpleSwitch只有边缘的交换机会没有下发流表(使用泛洪)的功能,其他的交换机都有转发流表的功能。这样虽然会增加边缘节点的负担,但是这样就可以在边缘网络上搭起一道数据包的检测防御。这样的牺牲是值得的。
3.数据的预处理
在控制器里获取到了数据包后就可以依据特征进行相应数据的提取。本文使用了这样的特征:
其最终若是只有一个数据包那么Total Fwd Packets,Min Packet Length, Max Packet Length, Packet Length Mean是一样的。
按照层次显示IP层提取出源IP,目的IP ,和上层使用的协议。
Tcp层提取出源端口,目的端口,fin,syn,rest,push,ack,urg等标志位信息。
Udp层只提取出源端口,目的端口。
最后计算一下数据包的大小,最大最小及平均包大小。
将统计好的数据交由Numpy(一个python实现的科学计算库,用来存储和处理大型矩阵)和pandas(基于Numpy的一种工具,为了解决数据分析而创建)进行处理成为模型可以处理的数据。
4.基于CNN的神经网络模型
由于数据时文本形式的,于是用CNN的一维卷积来处理数据。依据公式:
其中N是指输入数据纬度的大小,这里是看特征的大小,本文有16个特征。
P是指填充数据的大小。默认为0。F是指卷积核的大小。S是指步长,默认为1。
例如:有一种网络结构可以是:
输入数据16161,此时N为16。
第一层卷积:F为2,32个过滤器,S为2,P为0,则输出大小为8832。
第二层卷积:F为2,64个过滤器,S为2,P为0,则输出大小为4464。
第三层卷积:F为2,128个过滤器,S为2,P为0,则输出大小为22128。
第四层卷积:F为2,512个过滤器,S为2,P为0,则输出大小为11512。
输出位512。此时在经过一个全连接就可以输出最终的结果了。
使用此种方式可以最快的建立处模型,并且效果是比较理想的。
模型使用了两层,每层包括一个卷积层一个池化层。最后在经过一个平均池化层和一个全连接层。
5.结果展示
(1)在windows下的训练进度显示(训练次数为四次)
(2)在Ubuntu下的训练经度显示(训练次数为四次)
(3)模型的损失函数和准确率的变化曲线(训练次数为四次)
(四)、程序流程图
(五)、主要功能
本文的主要功能是收集当前的流量数据,将其传给控制器对其进行特征提取,将提取的特征经过数据预处理并传给神经网络的模型,给出预测结果。
由于硬件的限制,只能在Mininet上做实验(也可以开启多个虚拟机桌面(两个),一个作为发送端,一个作为接收端)。这样可以达到实时监测的效果。先把数据抓取下来,再将其转发到Mininet网络。
在边缘节点预测数据的可用性,再按照相应的策略对于不同类型数据进行转发。进一步提高了数据的安全性和可用性。
四、测试
(一)打开Ryu控制器
使用下面的命令在Pycharm的Terminal下开启Ryu
(二)打开Mininet
Mninetstart.sh文件中包含一下命令:
(三)发送数据
为了能够及时的显示数据而且由于硬件条件的原因于是将GUI和发送程序绑定到一起。点击开始,便开始发送数据。将数据保存在本地用于在GUI显示。
以下是GUI界面(数据包是:板块显示的是数据包的主要的信息,比如IP,端口号,协议。特征是:板块显示的是提取出来的特征。结果是:板块显示的是预测的结果。)
点击开始后,按钮会消失,等到所有的数据包都显示完之后才会显示出来:
五、途中解决的问题
(一)解决RYU使用Import出错问题
当前最重要的是实现数据的在线实时的提取数据包,而不是通过其他的方法。比如在控制器端实现数据包特征的提取,然后保存特征在文件中,然后在发送端找到保存的文件并提取特征将其放置到模型中。这样能够实现的原理是每发送一个数据包然后等待控制器将特征写入到文件中后在提取文件中的特征。这样做有两个缺点,第一这个不是实时的,第二发送端和控制器不是独立的,他们之间有文件联系的。在真实的环境中这个肯定会不行的。
所以将模型放置到控制器当中,但是这是有一个问题显示出来了。Import出现错误。他会如下图这样提示:
所以为了解决这个问题一开始使用sys.path.append()的形式在代码的内部。但是还是会报这个错误。于是跟进源码发现在Ryu的内部是先导入代码需要的所有的模块才回去执行代码。于是这种方法不行。但是在跟进源码的时候发现了Ryu导入模块的秘密—他是会在utils这个包里向sys.path里添加代码所在的完整路径。出错的原因是import的包没在那个完整路径下。于是本文有多重方法可以解决这个问题。
①将需要导入的包都放在那个完整路径下。比如完整路径为root/pycharm/cnn/k/s/,那么可以将包如ss.py放置到其下面如root/pycharm/cnn/k/s/ss.py,这样Ryu在扫描包的时候就会扫描到它。这样就不会报错了。但是这样会使得代码没有层次感,而且会使得这个文件看起来很臃肿。而且追重要的是我如果需要使用一个不能移动的文件,并且这个文件还不在完整路径下,那么这个方法就会失效。
②可以将sys.path.append(xxxx)添加到源码中,这样也能解决问题。但是这种方法只能解决单个项目问题。换到另一个项目就还需要再去在源码中添加相应的代码。这样很麻烦。
③修改Ryu源码,一次解决所有的问题。在Ryu/base/app_manager.py修改def load_app(self, name,relativepath=None):方法,添加一个参数relativepath=None。
再添加一个函数用于获取项目的路径:
当然Ryu/cmd/manager.py也是需要改的如:
这样就可以解决问题了,这里使用的是第三种方法。
(二)解决RYU和Keras的整合问题
由于keras是基于Tensorflow的,于是和Tensorflow有同样的问题就是使用他和其他的框架一起使用进行预测时会出现错误。总是提示预测有问题。后来查阅了大量的资料解决了这个问题。解决思路是在导入模型后马上进行预测,之后的预测就没有问题了。
(三)基于RYU实现了对数据包的实时解析
成功将模型嵌入到Ryu当中,实现实时的处理,这一步非常的重要。没有这一步那么即使训练的模型在好,也不能够实现数据包的实时处理。那么只能在本地实现数据包的检测,那么这将会失去应有的意义。每过来一个数据包都会经由控制器,控制器对其进行解析提取数据包的特征信息。经过数据的预处理然后将其放置到模型中进行预测。得出预测结果后再对预测的结果进行相应的QOS操作。下面是实时提取及预测的流程图:
六、总结
使用Sdn技术实现了数据的采集以及对采集的数据进行预测。
具体的代码放在了我的github下面:
https://github.com/mcl973/-/tree/master/RenGongZhiNeng/Cnn_Identify_Model