ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于SDN和OpenFlow的DDoS攻击检测与防御系统设计与实现

基于SDN和OpenFlow的DDoS攻击检测与防御系统设计与实现 简介一套面向高校计算机相关专业的优秀毕业设计资料基于SDN架构实现DDoS攻击检测与防御适合人工智能、通信工程、物联网等专业学生用于毕设、课设或项目初期演示也便于新手通过完整代码与文档快速入门。整套资源共91个文件整体压缩包约158KB其中71个Java文件构成核心检测与防御逻辑11个XML及2个YML用于工程与运行配置另含TXT项目说明、DOCX详细设计报告、Markdown文档和Shell辅助脚本覆盖从源码阅读到环境部署的完整链路。目前已有254人学习下载项目源码经过严格测试可稳定运行易复现。资料内容包含详细设计报告、项目说明、源码工程和部署脚本可深入理解SDN环境中DDoS流量识别与防护机制也能直接在此基础上升级改造作为课程设计或毕业设计的扎实起点。1. 基于 SDN 的 DDoS 攻击检测与防御系统在毕设里到底做什么DDoS 这个老问题在传统网络里一直有个尴尬点入口路由器能看到流量突变但不知道攻击是从哪条路径、哪个汇聚层涌进来的等运维定位到源的时候上游链路已经被打满了。而 SDN 的价值在于控制器掌握全局视图每台交换机的流表、端口计数器都能被同一套控制面拉取检测和防御能在控制器上闭环完成。这个体系落到毕设里就是一条明确主线用 OpenFlow 协议从交换机收集流量特征在控制器里做攻击判定再通过下发流表、Meter 表把防御动作推回去。这套东西既能体现对网络的整体理解又有完整的工程闭环而且 Mininet 加 Ryu 的组合跑通成本低、演示效果好所以它一直是网络方向毕设的高频选题。2. 基于流表统计的攻击检测模型设计与参数选择2.1 为什么用熵值而不是单纯看流量大小大部分 DDoS 检测方案的第一步都是算吞吐量但吞吐量在真实网络里波动太大平时晚高峰也可能翻几倍单纯设一个 Mbps 阈值很容易误报。熵值解决的正是这个问题它不关心流量总量只关心目的 IP、源 IP、端口这些维度的分布是否变得异常。以最常见的 SYN Flood 为例攻击者会用随机源 IP 打同一个目标端口目的 IP 极度集中。正常网络里目的 IP 分布在很多台服务器上目的 IP 熵值接近理论最大值攻击发生时大量报文全部指向一个 IP熵值会明显下坠。用熵值判定可以避开不同链路带宽差异带来的干扰这也是 SDN 控制器做轻量级检测最常用的思路。还有一种思路是算源 IP 熵用于 UDP Flood 这类源地址分布很广、目的端口随机的场景。毕设里建议两个都算但把目的 IP 熵作为主要判决条件因为它的物理含义最好解释报告里画图也最直观。数据来源有两种选择一种是让交换机把每包都上送控制器通过 PacketIn 事件提取特征另一种是控制器定期用 OFPFlowStatsRequest 轮询流表计数器。前者的优点是实时性高缺点是 PacketIn 会占满控制器 CPU攻击流量本身就是高 PPS 的反而把控制器打瘫。我一般建议用轮询流表统计做主数据源PacketIn 只做辅助验证下表是两者的对比。数据源实时性控制器开销适合场景PacketIn 事件毫秒级高单包触发处理小流量、特征分析端口统计轮询秒级低固定周期拉取长期监测、毕设主方案流表统计轮询秒级中按 switch 粒度控制精确到攻击目标 IP 的检测2.2 在 Ryu 控制器里实现滑动窗口熵计算下面这段代码实现了核心的熵检测逻辑用滑动窗口保存最近 N 个报文的目的 IP每次窗口填满就计算一次 Shannon 熵。from ryu.base import app_manager from ryu.controller import ofp_event from ryu.controller.handler import MAIN_DISPATCHER, set_ev_cls from ryu.ofproto import ofproto_v1_3 from ryu.lib.packet import packet, ipv4 from collections import Counter, deque import math class EntropyDetector(app_manager.RyuApp): OFP_VERSIONS [ofproto_v1_3.OFP_VERSION] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.window deque(maxlen300) # 滑动窗口存目的 IP self.entropy_threshold 3.5 # 熵值低于该值判定为异常 self.min_window_size 200 # 窗口未填满不判定 set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) def _packet_in_handler(self, ev): msg ev.msg pkt packet.Packet(msg.data) ip pkt.get_protocol(ipv4.ipv4) if ip: self.window.append(ip.dst) self._check_entropy() def _shannon_entropy(self, items): counter Counter(items) total len(items) # 熵值公式-Σ p_i * log2(p_i) entropy 0.0 for count in counter.values(): p count / total entropy - p * math.log2(p) return entropy def _check_entropy(self): if len(self.window) self.min_window_size: return dst_entropy self._shannon_entropy(self.window) self.logger.info(dst entropy%.3f, packet_count%d, dst_entropy, len(self.window)) if dst_entropy self.entropy_threshold: self.logger.warning(possible DDoS detected: entropy %.3f, dst_entropy)窗口大小取 200 到 500 比较合适。窗口太小熵值波动大正常流量也会出现低点窗口太大攻击要积累很久才能暴露防御的实时性变差。默认 300 左右时检测延迟大约在 2 到 3 秒内对毕设演示来说很舒服。阈值 3.5 是针对目的 IP 维度设定的参考值并不是通用值。一个只有几十台服务器的实验网络正常熵值在 6 到 8 之间攻击时可能掉到 2 以下。如果你在跑互联网流量模拟正常熵值会更高阈值也得跟着上调。更稳妥的办法是先跑一段正常流量记录熵值基线用「基线均值减三倍标准差」作为动态阈值。2.3 这个方案的两个坑PacketIn 洪泛和采样周期第一个坑是 PacketIn 洪泛。OpenFlow 交换机的默认行为是遇到没有匹配流表的包才上送控制器。所以上述代码在实际环境中会先收到大量学习阶段的 PacketIn而在攻击发生时如果之前已经把普通流表下发下去了攻击流量反而不会上送控制器意味着你的检测模块收不到任何数据。这是个逻辑悖论。解决思路是把检测和转发解耦检测不依赖 PacketIn而是让控制器周期性地向所有交换机发送 OFPFlowStatsRequest从统计回复里拿字节数和包数变化速率。下面是一个轮询流表统计的代码骨架from ryu.controller.handler import set_ev_cls from ryu.controller import ofp_event from ryu.lib import hub import time class FlowStatsPoller(EntropyDetector): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.interval 1 # 轮询周期单位秒 self.flow_rates {} # 记录每个流表项的速率 self._last_ts time.time() self.monitor_thread hub.spawn(self._monitor) def _monitor(self): while True: hub.sleep(self.interval) for dp in self.datapaths.values(): parser dp.ofproto_parser req parser.OFPFlowStatsRequest(dp, 0) dp.send_msg(req) set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) def _flow_stats_reply_handler(self, ev): now time.time() dt now - self._last_ts for stat in ev.msg.body: # 只观察常规转发流表项priority 为 10 的在转发 if stat.priority ! 10: continue ipv4_dst stat.match.get(ipv4_dst) if not ipv4_dst: continue bytes_sec (stat.byte_count - self.flow_rates.get(ipv4_dst, stat.byte_count)) / dt self.flow_rates[ipv4_dst] stat.byte_count if bytes_sec 50 * 1024 * 1024: # 超过 50MB/s 判为异常 self.logger.warning(target %s rate%.2f MB/s, ipv4_dst, bytes_sec / 1024 / 1024)第二个坑是采样周期和检测精度的平衡。轮询周期设为 1 秒能捕获秒级突变但交换机回复量大设成 10 秒则短时攻击可能被平均掉。对毕设系统来说1 秒轮询、30 秒统计窗口是个不错的起点。如果交换机多按 datapath id 随机错开轮询时间避免所有交换机同时回复造成控制器消息队列拥堵。3. 控制器下发流表实现自动防御与流量清洗3.1 三种防御动作的选型对比检测出攻击后防御动作有丢包、限速、重定向三个梯度可选对应不同的攻击强度和业务要求。防御动作OpenFlow 原语适用场景代价完全丢弃空 action 列表的 FlowMod明确识别的攻击流业务完全不可用也没关系可能误杀正常用户端口限速OFPMeter MeterBandDrop攻击流量和正常流量混在一起超限即丢包突发业务受损重定向清洗FlowMod 改输出端口有独立清洗集群或流量镜像设备增加一跳转发延迟毕设里建议做成「分级响应」熵值偏高时先限速熵值继续下降再升级为丢弃或重定向。这样答辩时能演示系统不是一刀切而是有策略性的。3.2 用 OFPMeter 对攻击目标 IP 做限速OpenFlow 1.3 的 Meter 表本质是一个令牌桶超过指定速率后对超额报文执行 band 动作。限速很适合用于 SYN Flood因为攻击流量和正常 TCP 连接共用同一个 80 端口一刀切会误杀业务。def add_meter(self, datapath, meter_id, rate_kbps, burst_size): parser datapath.ofproto_parser ofproto datapath.ofproto # 创建 meter 表项flags 选择 KBPS 表示速率单位是 kbps band parser.OFPMeterBandDrop(raterate_kbps, burst_sizeburst_size) req parser.OFPMeterMod( datapathdatapath, commandofproto.OFPMC_ADD, flagsofproto.OFPMF_KBPS, meter_idmeter_id, bands[band] ) datapath.send_msg(req) def add_rate_limit_flow(self, datapath, dst_ip, port): parser datapath.ofproto_parser ofproto datapath.ofproto match parser.OFPMatch(eth_type0x0800, ipv4_dstdst_ip) actions [parser.OFPActionOutput(port)] instructions [ parser.OFPInstructionMeter(1), parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] mod parser.OFPFlowMod( datapathdatapath, priority100, matchmatch, instructionsinstructions ) datapath.send_msg(mod)rate 参数是限速上限单位为 kbps。设置前可以先通过轮询统计算一下该 IP 的正常峰值带宽把 rate 设为正常峰的 1.2 倍比较稳妥。burst_size 建议设为 10 倍于单包最大报文长度也就是大约 15KB给正常业务波动留出余量。注意 Meter 表是 OpenFlow 1.3 才引入的特性启动 Mininet 交换机时必须指定protocolsOpenFlow13否则控制器下发 OFPMeterMod 会被交换机拒收。如果用的是 OVS还需要确认打开flow-meter相关支持实验环境里默认是开启的。3.3 丢弃流表的正确姿势空动作列表限速挡不住大流量攻击时就需要下发丢弃流表。OpenFlow 规范里没有 OFPP_DROP 这个端口丢弃动作要靠流表指令里不附带任何输出动作来实现。def add_drop_flow(self, datapath, dst_ip): parser datapath.ofproto_parser ofproto datapath.ofproto match parser.OFPMatch(eth_type0x0800, ipv4_dstdst_ip) # 空 action 列表匹配到的报文不转发等价于丢弃 instructions [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, []) ] mod parser.OFPFlowMod( datapathdatapath, priority200, # 必须高于普通转发流表 matchmatch, instructionsinstructions, hard_timeout60 # 60 秒后自动失效防止误杀时间过长 ) datapath.send_msg(mod)priority 必须高于普通转发流表项否则流量会先匹配低优先级的转发规则。另外最好设置 hard_timeout让丢弃规则自动过期避免攻击结束后整个目标 IP 被永久拉黑。实际运维中如果担心永久拉黑影响业务可以改成软状态控制器定时检查该目标 IP 的熵值恢复后主动删除这条丢弃流表。3.4 流量重定向到清洗节点重定向思路是把送往受害 IP 的流量引入一个独立的清洗虚拟机或物理端口。清洗节点可以布防 IDS 过滤器将与攻击特征匹配的报文剥离再把干净流量通过专用链路送回交换机转发给真实服务器。def redirect_to_scrubber(self, datapath, dst_ip, scrub_port): parser datapath.ofproto_parser ofproto datapath.ofproto match parser.OFPMatch(eth_type0x0800, ipv4_dstdst_ip) actions [parser.OFPActionOutput(scrub_port)] instructions [ parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] mod parser.OFPFlowMod( datapathdatapath, priority150, matchmatch, instructionsinstructions ) datapath.send_msg(mod)重定向的配置难点在拓扑层面毕设里可以简化在 Mininet 中单独加一台 scrubber 主机用双网卡分别连接交换机和目标服务器控制器只需把流量导向 scrubber 端口。这个方法放到报告里可以展现你对「检测-清洗-回注」整条链路有完整考虑。3.5 检测与防御模块的联动状态机检测和防御不应是两个独立脚本建议把它们组织成状态机每个受保护的目标 IP 维护一个状态正常 - 可疑 - 防御中 - 恢复。正常状态下只做熵值计算熵值连续 3 次约 3 秒低于阈值则进入可疑态下发限速流表可疑态下熵值继续下降或攻击速率持续超过设定值升级为丢弃或重定向防御持续 60 秒后进入恢复检测如果熵值回升到正常区间删除所有防御流表回到正常态。状态机的好处在于调试时只需要看当前 IP 处于哪个状态日志输出更清晰答辩演示时也更容易讲出层次感。4. 基于 Mininet 的 DDoS 攻击实验环境搭建与复现测试4.1 搭建 SDN 实验拓扑的命令毕设演示环境推荐用 Mininet Ryu Open vSwitch 这套组合全部跑在一台 Ubuntu 虚拟机上都行。启动一个树形拓扑sudo mn --controllerremote,ip127.0.0.1,port6633 \ --topotree,depth2,fanout3 \ --switchovsk,protocolsOpenFlow13 \ --mac参数含义--controllerremote让 Mininet 连接外部 Ryu 控制器而不是用内置的简单控制器--topotree,depth2,fanout3生成两层拓扑、每层 3 个扇出共 4 台交换机和 9 台主机这个规模足够模拟攻击流量的汇聚效果protocolsOpenFlow13指定 OVS 使用 OpenFlow 1.3 协议Meter 表依赖这个版本。Ryu 控制器启动命令ryu-manager --observe-links sdn_ddos_detector.py--observe-links会周期发送 LLDP 探测包让控制器维护全局链路视图后面如果要实现重定向路径计算这个选项是必须的。4.2 Kali 环境里搭建发包机并生成攻击流量攻击流量的生成可以用 hping3也可以写 Scapy 脚本。hping3 是轻量发包工具适合做快速的 SYN Flood 实验Scapy 更灵活能自定义源地址池和报文大小。# SYN Flood随机源 IP 攻击 h2 的 80 端口 hping3 -S -p 80 --rand-source 10.0.0.2 -i u100 # UDP Flood篡改源 IP高速发送 UDP 报文 hping3 -2 -p 53 --rand-source 10.0.0.2 -i u100-i u100表示每 100 微秒发一个包即 1 万 PPS这个量级足够让实验网络里的熵值发生明显变化又不会把虚拟机 CPU 打满。--rand-source随机化源地址模拟真实攻击的源地址分散特性。下面是 Scapy 版的发包脚本适合在检测实验里控制频率和总包数from scapy.all import IP, TCP, send from random import randint target 10.0.0.2 for i in range(5000): src_ip 192.168.%d.%d % (randint(0, 255), randint(1, 254)) pkt IP(srcsrc_ip, dsttarget) / TCP(sportrandint(1024, 65535), dport80, flagsS) send(pkt, verbose0)这段脚本会用不同的随机源 IP 连续发送 5000 个 SYN 包。注意每次send()是逐包发送发包速率受虚拟机网卡限制如果测出来速率不够可以改用sendpfast()配合 pcap 文件提高发包速度。正常流量用 iperf3 生成# h1 作为服务端 iperf3 -s -p 5201 # h3 作为客户端向 h1 打流 iperf3 -c 10.0.0.1 -p 5201 -t 120 -b 100M先跑 120 秒正常流量让控制器采集到基线熵值第 60 秒时启动 hping3 攻击脚本观察控制器日志里的熵值变化和防御动作触发情况。4.3 攻击实验的完整验证流程攻击验证的完整顺序建议这样设计第一步在 Mininet 的 xterm 里分别打开 h1、h2、h3 窗口启动 iperf3 正常流量。第二步观察 Ryu 控制台日志记录正常状态下目的 IP 熵值稳定后再继续。第三步从攻击主机向目标发起洪泛攻击同时用tcpdump -i h2-eth0 port 80抓包统计 SYN 报文数量。第四步观察控制器日志记录从熵值掉到阈值以下到限速流表下发完成的响应时间这个数值是报告里最重要的实验数据。第五步攻击持续 2 分钟后停止观察系统是否从防御状态自动恢复到正常态。实验完成后整理一张对比表这是整个毕设报告的数据支撑指标正常流量攻击中未防御防御生效后目的 IP 熵值7.81.26.9target 吞吐量95 MB/s300 MB/s102 MB/s控制器响应延迟无无0.8s正常业务吞吐恢复率100%被挤占92%数据不用追求漂亮但要注意每条数据的测量条件一致比如采样窗口、轮询周期、攻击包大小都要在报告里写明。4.4 验证中的一个常见问题为什么检测到了却丢不掉实际跑实验最常见的现象是控制器日志已经打印了 DDoS detected但目标主机上 iperf 还是被打满了。原因通常是丢弃流表的 priority 低于交换机里已有的转发流表项或者交换机硬件表项没有刷新。排查步骤很简单用ovs-ofctl dump-flows s1 -O OpenFlow13查看交换机的实际流表内容检查是否有两条匹配同一目的 IP 的流表项以及哪条的 priority 更高。同时确认OVS使用了 OpenFlow 1.3 通道Meter 表项用ovs-ofctl dump-meters s1 -O OpenFlow13检查。提示防御流表删除时也要通过控制器发 FlowMod 删除不要只依赖 hard_timeout。否则状态机已经恢复交换机里还残留过期流表后续相同的检测条件可能被旧规则干扰。5. 毕设报告里 DDoS 检测与防御系统怎么写才有说服力5.1 报告的章节组织与数据图表要点报告部分很多人会堆篇幅实际上评审老师主要看三件事问题是否真实存在、方案是否解决了问题、实验数据能否支撑结论。建议按下面这个结构组织第一章 绪论 1.1 研究背景与意义 1.2 国内外研究现状 1.3 本文的主要工作 第二章 SDN 与 DDoS 攻击检测相关技术 2.1 SDN 架构与 OpenFlow 协议 2.2 DDoS 攻击的典型类型 2.3 攻击检测与防御的国内外方案对比 第三章 基于 SDN 的检测与防御系统设计 3.1 系统总体架构 3.2 检测模块设计 3.3 防御模块设计 3.4 状态机与联动机制 第四章 系统实现与实验分析 4.1 实验环境部署 4.2 实验流程与测试数据 4.3 结果分析与对比 第五章 总结与展望写检测章节时把第二章的熵值原理、第三章的滑动窗口实现、第四章的实验数据串成一条逻辑线。每一张核心图表都要配文字解读比如熵值变化曲线图要明确标出攻击开始时刻、防御下发时刻、恢复时刻三个时间点这比大段论述更有说服力。对比分析部分建议抓一个点做深挖比如比较不同窗口大小对检测延迟的影响或者比较轮询周期对误报率的影响。这类对比实验实现成本很低但报告里显得特别充实。5.2 答辩前 Demo 演示的时间轴脚本答辩演示时容易出现临场混乱。建议把演示过程写成固定脚本提前录一版保底视频时间操作讲解重点0:00-0:30启动 Mininet、Ryu展示拓扑图和控制器链路发现0:30-1:00启动 iperf3 正常流量说明控制器中的正常熵值1:00-1:30启动 hping3 攻击指出熵值曲线的明显下降1:30-2:00控制器自动下发防御流表展示ovs-ofctl dump-flows输出2:00-2:30停止攻击系统自动恢复说明超时自动撤销防御规则演示时如果攻击效果不明显优先检查 Mininet 交换机的协议版本是否真的是 OpenFlow 1.3以及 hping3 的频率是否够高。还有一个常见问题是多个实验共用同一台 Mininet残留流表会导致检测结果不稳定每次演示前重启一次 Mininet 最省事。报告最后留一个「系统不足与改进方向」小节比如把检测模块从熵值扩展到机器学习模型、把控制器从 Ryu 换成 ONOS 做分布式部署。这不是在给自己找缺点而是向评审传达你对系统边界有清晰的认识在毕设等级的评分里这一节的份量甚至比系统功能本身更重要。本文还有配套的精品资源点击获取
返回列表