作者简介:智智方,西安电子科技大学硕士研究生,主要研究方向为SDN与网络安全,邮箱:675520574@qq.com
一、前言
我们都知道在SDN架构下,交换机是根据流表来对数据流进行转发的,如果交换机收到一个在流表中无法匹配的数据流时,就会向控制器询问如何对该数据流进行处理。在OpenFlow协议下,交换机会针对每一个无法匹配的数据流产生packet-in消息并将该消息发送给控制器以询问如何对该数据流进行处理。因此当攻击者在SDN环境下制造虚假数据流或者瞬间产生大量数据流时交换机也会向控制器发送大量的packet-in消息,大量的packet-in消息会占用控制器的大量资源因而可以产生拒绝服务的攻击效果,本文针对这一问题在Opendaylight上开发了相关的应用以检测和防护这种类型的攻击。
二、架构图
主要需要两个模块,监测模块用来计算当前packet-in消息的速率来查看是否超过警戒值,当超过警戒值以后则由处理模块来进行处理,监测模块通过PacketProcessingListener接口来接收packet-in消息,并对消息进行解析,解析出IP地址以及MAC地址等信息,然后对packet-in消息进行速率计算,当速率超过警戒值以后,通过DataBroker将相应的威胁信息记录到DataStore中,用户可以通过RPC来查看记录在DataStore中的威胁信息,然后通过发送Notification消息的方式来通知处理模块,处理模块根据IP地址以及MAC地址等信息,通过SalFlowService接口来向交换机下发流表,让交换机丢弃相应的数据流,从而实现了对packet-in flooding攻击的防护。
三、方案实现
本部分从maven建立opendaylight架构开始逐步实现每一模块,并会对关键的操作步骤和代码进行说明。
3.1 maven建立opendaylight架构
在终端输入如下指令。
构建基于Carbon版的opendaylight框架,构建完成后,这个框架只有最基本的功能,根据刚才的描述,本文建立的框架需要支持OpenFlow协议并且需要支持基本的二层交换功能,因此本框架需要有openflowplugin以及l2switch两个模块,而这两个模块在默认生成的基本框架中是不包含的,因此完成框架构建后,需要在所依赖的features中添加这两个模块。
具体做法是,打开框架中features文件夹下的pom.xml文件,在其中添加相应的依赖,首先需要在properties标签下添加openflowplugin.version以及l2switch.version。
需要注意的是版本信息需要和上述一致,否则最后在安装feature时会发生版本冲突的问题而无法安装,然后在dependencies标签中添加相应的依赖。
完成对pom.xml文件的修改以后在features\src\main\features文件夹下修改features.xml,在其中添加相应的repository。
修改完成后对整个框架进行编译,然后开启karaf后就能安装与openflowplugin和l2switch相应的feature了,然后将整个项目导入到eclipse中。
3.2监测模块的实现
监测模块的原理很简单,主要就是通过记录某一个时间段内packet-in消息的数量,然后来计算这段时间的packet-in消息的速率并和预先设置好的阈值进行比较,以判断是否达到警戒的速率值来确定是否发出Notification消息。
首先需要在api文件夹下创建yang文件来确定相应的接口和在datastore中存储的数据结构,首先要在yang文件中确定notification的具体内容:
需要把IP地址以及MAC地址等信息发送给处理模块,处理模块根据这些信息来下发相应的流表项。
然后用container关键字来确定相应的威胁信息在datastore中存储的数据结构,具体如下:
总体来说需要把威胁流量的IP地址、MAC地址、协议、端口等各种信息存储起来,以为用户提供详细的威胁信息的记录。
然后在impl下创建PacketHandler类来实现这一模块,由于这一模块需要监听packet-in消息,则该类需要实现PacketProcessingListener接口,而这个接口是由openflowplugin的相关yang model产生的,因此需要在api下的pom.xml添加相关的依赖以导入相关的接口,具体添加如下依赖。
添加完成后保存,maven会自动导入相关的依赖,然后就可以实现PacketProcessingListener接口了,PacketProcessingListener接口只有一个方法需要实现,即onPacketReceived,实现了PacketProcessingListener接口的类即可视为packet-in消息的监听者,在onPacketReceived方法中可以添加相应的对packet-in消息的处理逻辑,具体处理逻辑如下:
主要是通过两个工具类来实现对数据包的解析从而获取ingress switch以及各个层级的地址等相关信息,然后调用Lwm()方法。
这个方法的最核心的逻辑如下:
主要就是通过记录一段时间内packet-in消息的个数并除以这段时间来计算packet-in速率,然后当超过警戒值以后会通过NotificationPublishService接口来发布notification消息,并通过DataBroker接口将相应的威胁信息记录到datastore中。
3.3处理模块的实现
在impl下创建HandlerModule类,实现DefenderpluginListener接口以成为监听模块发送notification的监听者,并实现onLowWaterMarkBreached方法,在这个方法中主要是根据notification发送过来的相关信息来下发流表项,让交换机丢弃相关的数据流,具体代码如下:
注意如果目的MAC地址是
”FF:FF:FF:FF:FF:FF”时,这个数据包时ARP请求,则不能根据这个目的MAC地址来下发流表项,这样会影响正常的数据通信,当判断不是ARP请求后则会通过DataBroker获取当前与控制器连接的所有交换机,并根据notification消息内容创建相关的flow,然后将这一流表项下发给每个交换机,这其中也编写了Flow创建的方法和下发流表的方法。
Flow构建的步骤相对比较繁琐,在这里详细介绍一下,Opendaylight采用的Yang文件建模的方法,这种方法能直接根据Yang模型生成相应的Java接口,这些接口并不需要我们来实现,而是可以直接使用这些接口相对应的builder类来直接构建,一般来说我们只需要创建相应的builder类,然后通过它提供的set方法为相关字段赋值,最后使用期其他的build方法即可得到相应接口的实现类,一般来说Flow的构建主要有四步:
下面结合代码来具体说明一下,首先要设置相关的ID:
然后来设置匹配域:
然后来设置相应的指令:
最后来设置该Flow的其他项:
整个Flow的构建步骤相对繁琐,建议在构建时应该比对Flow的yang文件按照其规定的数据结构一项一项赋值。
3.4 RPC的实现
RPC主要为用户提供查看攻击消息的功能,具体来说用户可以根据源IP地址和目的IP地址来查看该IP地址被攻击或者发动攻击的相关记录,也可以根据用户输入的时间段来查看这段时间内发生的攻击事件,当然也可以根据需求来添加其他的RPC,但是原理都是一样的,都是根据用户的输入从datastore中查找相关的信息,并将这些消息封装成Future来返回。
首先在yang文件中定义相关的RPC:
其中alert是用grouping定义的公共字段,包括IP地址、MAC地址以及协议等信息。然后创建DefenderRPCImpl类来实现相应的RPC,由于几种RPC的实现原理都类似,这里只选择根据源IP地址来查看该IP地址发动攻击的相关记录的RPC的实现来进行解释,代码如下:
其他几种RPC的实现类似,只不过改变一下筛选条件。
四、测试
对整个项目编译完成后启动
karaf\target\assembly\bin下的karaf
然后安装相应的feature,在终端输入如下命令:
然后启动mininet,测试时使用的是2.2.2版本的mininet,在mininet终端中输入如下指令与控制器进行连接:
同时在karaf终端中输入log:tail来显示相关的日志信息,连接上控制器以后,在mininet上输入h1 ping -f h2命令产生大量的请求数据,由于交换机流表中没有相应的流表项,因此会触发大量的packet-in消息从而来模拟packet-in flooding攻击,此时在karaf终端上输出如下日志:
说明已经检测到packet-in flooding攻击,并下发流表给mininet中虚拟的交换机,然后在mininet中输入dpctl dump-flows,可以看到在交换机上已经存在了actions=drop的流表项,此时切断了h1和h2之间的通信,从而防止了packet-in flooding攻击。
然后我们登录到opendaylight为我们提供的web页面,在yangman中选择defenderplugin module,然后选择Operations中的attacksToIP的RPC在其中输入10.0.0.2,即刚才被攻击的主机的IP地址,此时可以看到我们可以通过目的IP地址查看到刚才的攻击记录。
同样的我们也可以通过其他的RPC根据不同的筛选条件来获取相关的攻击记录。
五、总结
本实验在opendaylight上实现了对packet-in flooding攻击的检测与防护,也同时用到了opendaylight的MD-SAL为我们提供的三种基本服务以及通过SalFlowService接口下发流表的方法,篇幅有限很多细节也没有展开,如有兴趣欢迎大家和我交流!
附源码链接:
https://pan.baidu.com/s/1SJCUIcDzaKJijp7O1Z77yA