Openstack中伪造源地址攻击的防御

背景:Openstack在H版之前的时候,租户可以租用虚拟机发动DoS攻击,很多攻击的方式是伪造源地址。还有别的攻击,如ARP攻击等等,都是通过伪造源MAC或IP地址实现的。本文简单介绍一下openstack中抵御虚假源地址的攻击。 这种攻击的特点是攻击者从虚拟化系统内部发起,攻击目标可能是公网主机,或者是内网的主机。对于前者的防御比较容易,只需要在物理网络边界就可以部署安全设施进行检测和清洗;但是后者的攻击流量大部分是存在于虚拟网络和虚拟网络设备中,物理的安全设备是无法观测或理解物理网络中的流量,无法进行有效的防护,所以对于始于内部的DoS攻击,应该在虚拟化环境中将检测并抵御。 在Openstack的架构下,预计一种检测DoS攻击的方式是依靠检测模块Ceilometer,等它成熟之后,就可及时通知管理员或系统,通过Ceilometer与Neutron协作堵住这种攻击。 不过现在Ceilometer还在初级阶段,所以还是需要依靠网络虚拟化模块Neutron进行防护,好在IaaS系统知道VM的真实IP和MAC,所以可以直接在L2防火墙上对数据包进行过滤,H版已经引入了这部分特性。 下面以一台vm为例: # neutron port-list|grep 100.0.0.16 | 368d35e1-4db7-405f-af26-1f2b6f224bd8 | | fa:16:3e:34:c8:f8 | {“subnet_id”: “57b30eb5-e9ee-489f-85ea-77bcaa6249e5”, “ip_address”: “100.0.0.16”} | 2013.2.1引入了基于IPTABLES的过滤方案 iptables -L -nvx 可以看到: Chain neutron-openvswi-s368d35e1-4 (1 references) pkts bytes target prot opt in … Continue reading

Floodlight的流量控制

floodlight在bigswitch退出opendaylight后算是活过来了,新的版本在负载均衡中加入了一些机制,可以参见net.floodlight.loadbalancer 不过我关心的是FL对流量的控制,特别是判断packet_in速率的机制,这个在前几个月的Floodlight是没有的。 现在FL的处理机制是在收到packet_in数据包后,首先判断是否超过阈值,在inputThrottled方法中,计算每1000个数据包所花的时间,得出速率。如果速率超过packetInRateThresholdHigh阈值,则进入监控限制流量模式(enablePacketInThrottle) 在该模式下,依次检查packet_in数据包的src mac(频率为每50个packet_in一次)和in port(频率为每100个packet_in一次),如果近期(1s内)有该类数据包则将其禁止。 这种方法的初衷应该是防止controller的负载过高,例如禁止mac是为了防止host发送过多包,禁止in port是为了禁止sw转发过多包。但后者有可能出现在恶意vm发动DDoS攻击(一个in port,但无数src mac),客观上却使控制器免受DDoS攻击,自然也让域内的VM被DDoS。 贴一下主干代码:

让我们计算一下这种机制的效率,由于阈值packetInRateThresholdHigh设置的是1000,那么now-lastMessageTime应为1000ms=1s;考虑到controller每1000个packet_in进行判断,也就是说入包的极限是每秒1000个packet_in数据包,即1000条新流。这个在小范围内是没问题的,但Nick McKeown等人在经典文章“OpenFlow: Enabling Innovation in Campus Networks”中提到Preliminary results suggested that an Ethane controller based on a low-cost desktop PC could process over 10,000 … Continue reading

Floodlight路由机制解析

路由部分是floodlight最核心的机制,这两天仔细读了一下floodlight这部分的代码,总算有了大体上的了解,与各位分享。 本文中的floodlight(FL)与控制器/网络控制器(NC, nework controller ) 等术语等同,交换机(SW)默认为openflow-enabled switch,不再赘述。 首先谈一下SDN控制器的路由原理:当交换机收到一个不能被当前流表各条流匹配的数据包时,会把这个数据包以openflow的格式(PACKET_IN)发送给控制器。控制器经过路由决策后,同样以openflow的格式(PACKET_OUT)的方式将该数据包的下一跳信息回给该交换机。 如果学过最短路径计算的同学一定知道,两点之间的最短路径计算首先要知道任意两点之间是否相连,如果两者间有link相连还需知道其长度。所以总体而言,FL路由包括两部分:拓扑更新和路由计算,前者是定时事先完成的,形成一个全局的拓扑结构,后者是收到数据包后运行时完成的,根据拓扑生成路由策略。 首先看拓扑更新。SDN环境中拓扑是集中控制的,故FL需要了解全局的拓扑环境,所以FL在链路更新时自动更新拓扑。 1 链路更新 当交换机加入SDN环境后,控制器通过LLDP协议定时地获得该交换机与其他设备连接的link信息,然后添加或更新这些link(LinkDiscoveryManager.addOrUpdateLink()),最后将这些link更新的事件添加到updates队列中(LinkDiscoveryManager.handleLldp())。 2 拓扑更新 计算路由的关键在于路径更新和路由计算,该过程为: 2.1 启动 首先拓扑管理启动(TopologyManager.startUp())时新起一个线程UpdateTopologyWorker,间隔500ms重复运行 。 2.2 更新拓扑 如果之前在第一步中有一些链路、交换机等更新,那么LDUpdates队列中会有元素,那么依次取出这些链路更新的元素(TopologyManager.updateTopology()/TopologyManager.applyUpdates()),判断其类型(如链路更新/删除、端口增加/删除),进行响应处理。 以链路更新为例,调用TopologyManager.addOrUpdateLink()方法,判断链路类型(多跳、单跳或隧道),再把link添加到相应交换机的端口中,如果是多跳的则再删除可能的单跳link 2.3 计算拓扑路径 每次新建一个实例(TopologyManager.createNewInstance()),初始化过程中计算拓扑路径(TopologyInstance.compute()),具体地: 2.3.1 归类 将现有所有相连的link置于同一个簇中,从而形成多个簇结构(identifyOpenflowDomains()) 2.3.2 建簇 遍历所有link(addLinksToOpenflowDomains()),如果link连接的是同一个簇,则将其加入该簇,所以该方法统计了所有簇内的link。FL这么做也是减少路由计算的开销,不然若干个大二层网络中共有n个节点,就需要n平方的存储开销,计算效率也会下降,如果将不相连的节点分开就减少了上述开销。 2.3.3 遍历所有簇 … Continue reading

Floodlight REST module

1 download jackson, restlet lib 2 create AntiDDoSResource extending ServerResource

3 create a ADSWebRoutable class implementing RestletRoutable public class ADSWebRoutable implements RestletRoutable { @Override public Router getRestlet(Context context) { Router router = new Router(context); … Continue reading

Floodlight加载和运行模块的原理

这两天简单看了一下Floodlight的模块机制,大概了解了其插件的机制和流 程,编写了一个非常简单的模块,为大家分享一下 Floodlight加载和运行模块的原理 Floodlight的入口是net.floodlightcontroller.core.Main, 在这个类的main函数中,使用FloodlightModuleLoader加载所有的模块,然后再 调用net.floodlightcontroller.restserver.RestApiServer模块的run方法,启动 rest服务器,最后调用net.floodlightcontroller.core.internal.Controller模块的 run方法,启动网络控制器。

在加载模块的过程中,使用 FloodlightModuleLoader类的findAllModules方法寻找所有在$CLASSPATH路径中的实现了 net.floodlightcontroller.core.module.IFloodlightModule接口的模块,然后用initModules 初始化这些模块,最后用startupModules启动这些模块。 FloodlightModuleLoad.java:303

以MemoryStorageSource类为例,它继承了 NoSqlStorageSource类,后者又继承了AbstractStorageSource类,而 AbstractStorageSource是实现了IFloodlightModule和 IStorageSourceService两个接口。 IFloodlightModule有一个init方法和一个startUp方法,所以MemoryStorageSource会分别实现这两个方法,并在初始化和启动的时候被调用。 一个模块的简单实例 下面简单介绍如何新建一个模块的过程,以一个IDSController为例,现在 只实现定时打印日志的功能: 1 定义服务com.nsfocus.ids.IIntrusionDetectionService:

2 新建一个实现IFloodlightModule接口的类com.nsfocus.ids.IDSController: 分别实现接口IFloodlightModule的 getModuleServices、getServiceImpls、getModuleDependencies等方法,这三个方法 主要用于初始化模块 系统运行 ServiceLoader.load(IFloodlightModule.class, cl)后会将IDSController加载到支持IFloodlightModule模块的列表中。 3 在配置文件中添加新模块: … Continue reading

爱开源,恨开源

这种感觉是一直伴随着 将代码开源是需要强大的内心的 附使用floodlight时做的三处bug report。 其一 namespace导致路由失败 其二 不支持二层设备的发送 导致link 其三 OF link link CNN