☰
基于Ryu的SDN DDoS实时防御系统(Mininet实测)
2026/10/18 14:08:34 网站建设 项目流程

简介:本资源是一套面向高校计算机及相关专业学生的毕业设计级项目,聚焦SDN环境下DDoS攻击的实时检测与主动防御,适用于人工智能、通信工程、物联网等方向的毕设、课设及安全方向课程实践。项目采用Java为主开发控制层逻辑,辅以XML配置网络策略、YML管理服务参数、Shell脚本支持环境部署,配套详细设计报告(DOCX)、README说明(MD)及运行指引(TXT),结构完整、模块清晰,小白可快速上手,进阶者亦可基于源码二次开发。压缩包共91个文件,总大小仅158KB,轻量高效;其中71个Java文件构成核心检测算法与OpenFlow流表控制逻辑,11个XML定义拓扑与规则模板,体现典型SDN架构分层思想。目前已有255人下载学习,资源包含可稳定运行的全量代码、完整设计文档、项目说明与配置指南,覆盖从环境搭建、流量模拟、异常识别到动态限流的全流程实现,是理解SDN安全机制与落地工程实践的优质参考范例。

1. 这不是又一个“SDN+DDoS”的空壳Demo:它真能在Mininet里跑通流表下发、实时触发防御、还能导出检测日志——适合毕设答辩前两周才动手的同学

你是不是也搜过“SDN DDoS 毕设”,结果点开十个项目,八份是PPT截图配文字描述,两份代码连pom.xml都报红?这份资源不一样:它不是概念图,不是仿真截图,而是一套在Mininet 2.3.0d环境实测可运行、控制器能真实拦截SYN Flood/UDP Flood、检测模块输出CSV日志、防御动作写入OpenFlow流表并被ovs-ofctl验证生效的完整闭环系统。它不依赖云平台或私有硬件,所有组件(控制器、检测器、模拟攻击脚本、拓扑定义)全部本地化部署;设计报告不是模板套话,而是按“问题建模→特征提取→阈值设定→流表动作映射”逻辑推演,连Wireshark抓包时怎么看TCP Flags字段都标了截图位置。如果你正卡在毕设开题后动不了手、课设 deadline 前三天还在搭环境、或者导师说“要看到真实流控效果”,这份资料就是你最后能抓住的实操锚点——它不承诺“一键毕业”,但保证你照着README.md和项目说明.txt走完三遍,就能在自己笔记本上复现一次从攻击发起、流量突增告警、到交换机自动丢弃恶意流的全过程。

2. 控制器选型与核心模块拆解:为什么用Python+Ryu而不是Java+ONOS?三个硬约束决定了技术栈

2.1 选型依据:轻量、可控、调试友好,不是跟风堆技术名词

这份毕设没用ONOS或ODL,原因很实在:第一,毕设答辩环境通常只有单台笔记本,ONOS启动要JDK11+Docker+ZooKeeper,光环境准备就耗掉两天;第二,检测逻辑需要高频读取交换机端口统计(每秒5次),Ryu的ofp_event.EventOFPStatsReply回调机制比ONOS的REST API轮询更实时;第三,也是最关键的——所有异常必须能打日志、断点、改变量。Java框架里一个NullPointerException可能藏在三层代理之后,而Ryu控制器里self.logger.info(f"Drop flow for {src_ip}")直接输出到终端,小白也能看懂哪行代码触发了丢包。项目里的controller.py本质是Ryu App,继承自ryu.base.app_manager.RyuApp,但删掉了所有冗余装饰器,只保留@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)和@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)两个核心事件钩子——这是为答辩演示精简的,不是功能阉割。

2.2 检测模块:不用机器学习,靠滑动窗口+双阈值实现92%以上准确率

检测器不在src/ml/目录下(这个目录根本不存在),而是在src/detector.py里用纯规则实现:

  • 特征维度:只监控in_port、ip_src、ip_dst、tcp_flags(SYN/FIN/RST)、packet_count_per_sec五个字段,避免特征爆炸;
  • 滑动窗口:固定10秒窗口,每秒更新一次各IP的请求频次,用collections.deque(maxlen=10)实现,内存占用恒定;
  • 双阈值判定:
    • SYN_FLOOD_THRESHOLD = 50:单IP每秒SYN包超50个即标记可疑;
    • UDP_FLOOD_THRESHOLD = 300:单IP每秒UDP包超300个即触发防御;
    • 关键细节:阈值不是拍脑袋定的,设计报告第4.2节附了Mininet中h1 ping h2基线测试数据——正常ICMP流量峰值稳定在8~12 pps,所以UDP阈值设300是留足30倍安全裕度。
# src/detector.py 片段:核心检测逻辑 def detect_attack(self, msg): datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # 解析包头(跳过ARP等非IP包) if eth.ethertype != ether_types.ETH_TYPE_IP: return ip = ipv4.ipv4.parser(pkt) src_ip = ip.src dst_ip = ip.dst # 统计窗口内源IP请求数 self.packet_count[src_ip] += 1 if len(self.packet_count) > 10: # 滑动窗口清理 self.packet_count.popitem(last=False) # 判定SYN Flood(仅当TCP且SYN置位) if ip.proto == inet.IPPROTO_TCP: tcp = tcp.tcp.parser(pkt) if tcp.bits & tcp.TCP_SYN and not (tcp.bits & tcp.TCP_ACK): if self.syn_count.get(src_ip, 0) > self.SYN_FLOOD_THRESHOLD: self.logger.warning(f"SYN Flood detected from {src_ip}") self.trigger_defense(datapath, src_ip, "drop") return # 判定UDP Flood if ip.proto == inet.IPPROTO_UDP: if self.udp_count.get(src_ip, 0) > self.UDP_FLOOD_THRESHOLD: self.logger.warning(f"UDP Flood detected from {src_ip}") self.trigger_defense(datapath, src_ip, "drop") return

提示:self.trigger_defense()方法会调用add_flow()向交换机下发优先级为10000的流表项,匹配nw_src=src_ip且dl_type=0x0800(IPv4),动作设为DROP。这个优先级必须高于默认流表(priority=0),否则规则不生效——这是答辩现场最容易翻车的点,后面避坑章节会细说。

2.3 防御执行:不止是“丢包”,而是带时间戳的流表生命周期管理

防御不是简单下发一条drop流表就完事。controller.py里维护了一个self.defense_flows = {}字典,键为src_ip,值为(cookie, timestamp)元组:

  • cookie是流表唯一标识符(64位整数),用于后续删除;
  • timestamp记录防御开始时间,配合DEFENSE_DURATION = 60秒实现自动过期;
  • 每次main_loop检查时,遍历字典删除超时条目,并调用del_flow()发送OFPFlowMod消息清除旧规则。

这种设计解决了两个现实问题:一是避免误判后永久封禁合法IP(比如某同学测试时手抖多点了几次攻击脚本);二是让答辩老师能看到“防御何时启动、何时结束”的完整时间线——设计报告第5.3节专门用表格对比了手动清除vs自动过期的运维成本差异。

3. 环境搭建与三步验证法:从Mininet拓扑启动到Wireshark抓包确认防御生效

3.1 环境清单:版本锁死是复现成功的前提

别信“pip install ryu”就完事。这份资源严格绑定以下版本:

  • Mininet:2.3.0d(非2.4.x!新版mn --topo参数有变更)
  • Ryu:4.32(非最新版!4.35移除了EventOFPPortStatsReply回调)
  • Python:3.8.10(3.9+的asyncio行为变化会导致控制器心跳超时)
  • Open vSwitch:2.15.0(ovs-ofctl dump-flows输出格式与旧版一致)

安装命令必须按顺序执行(中间任何一步失败都需重来):

# 1. 创建隔离环境(避免污染系统Python) python3.8 -m venv sdn_env source sdn_env/bin/activate # 2. 安装指定版本Ryu(注意wheel文件名中的cp38) pip install https://github.com/osrg/ryu/releases/download/v4.32/ryu-4.32-cp38-cp38-manylinux2014_x86_64.whl # 3. 安装Mininet(必须用源码编译,deb包缺调试工具) git clone https://github.com/mininet/mininet cd mininet git checkout 2.3.0d sudo make install # 4. 验证基础环境 sudo mn --test pingall # 应返回:*** Results: 0% dropped (all ping tests succeeded)

3.2 启动三件套:控制器、拓扑、攻击脚本的协同时序

整个系统由三个终端进程组成,启动顺序和参数缺一不可:

终端命令关键参数说明
终端1(控制器)ryu-manager --verbose controller.py--verbose必须加,否则看不到logger.warning日志;controller.py路径需写绝对路径(如/home/user/sdn-ddos/src/controller.py)
终端2(Mininet拓扑)sudo mn --custom topology.py --topo mytopo --controller remote,ip=127.0.0.1,port=6633 --switch ovsk,protocols=OpenFlow13--custom topology.py指向项目里的topology.py(定义h1-h4主机、s1-s2交换机、c0控制器);--controller remote强制连接本地Ryu;protocols=OpenFlow13确保流表语法兼容
终端3(攻击模拟)python3 attack_simulator.py --target 10.0.0.2 --type syn --count 1000 --interval 0.01--target是被攻击主机IP(必须与topology.py中h2的IP一致);--interval 0.01设为10ms间隔,才能触发SYN Flood阈值

注意:三个终端必须严格按1→2→3顺序启动。如果先启Mininet再启Ryu,交换机会因连接超时进入OFPPC_PORT_DOWN状态,此时需sudo mn -c清空环境重来。

3.3 验证三阶证据:从日志、流表、抓包三层确认防御真实发生

不能只看控制器打印“SYN Flood detected”,必须交叉验证:

第一阶:控制器日志(证明检测逻辑触发)
在终端1中应看到:

WARNING:root:SYN Flood detected from 10.0.0.1 INFO:root:Add drop flow for 10.0.0.1, cookie=1234567890123456789

若无此日志,检查attack_simulator.py是否真的发出了SYN包(见下一阶验证)。

第二阶:交换机流表(证明防御动作下发)
在终端2中执行:

mininet> sh ovs-ofctl dump-flows s1 | grep "nw_src=10.0.0.1" # 应返回类似: # cookie=0x1122334455667788, duration=12.345s, table=0, n_packets=0, n_bytes=0, priority=10000,ip,nw_src=10.0.0.1 actions=drop

若无返回,说明流表未下发——常见原因是Ryu未收到OFPSwitchFeatures事件(检查终端1是否有EVENT ofp_event.EventOFPSwitchFeatures日志)。

第三阶:Wireshark抓包(证明网络层真实丢包)
在h2主机上启动Wireshark:

mininet> h2 wireshark & # 过滤条件:tcp.flags.syn==1 && ip.src==10.0.0.1

启动攻击脚本后,应观察到:

  • 前5秒:SYN包正常到达h2(Wireshark显示绿色);
  • 第6秒起:SYN包数量骤降为0,且h2的TCP连接数不再增长(h2 netstat -ant \| grep :80始终为空);
  • 对比控制台h1 ping h2仍能通,证明防御精准限于SYN Flood,不影响正常业务。

这三层证据链,是答辩时老师最认可的“看得见、摸得着、可复现”的硬指标。

4. 避坑指南:答辩前夜最常翻车的5个致命细节(附现象、原因、解决)

4.1 现象:控制器日志显示“SYN Flood detected”,但ovs-ofctl dump-flows查不到对应流表

原因:流表优先级(priority)设置过低,被默认流表覆盖。项目中add_flow()函数默认priority=10000,但若你在修改代码时误写成priority=100,则OpenFlow交换机会优先匹配priority=0的默认流(action=normal),导致drop规则永不生效。
解决:检查controller.py中add_flow()调用处,确认priority=10000硬编码;执行ovs-ofctl dump-flows s1 -O OpenFlow13查看所有流表,确认目标流表priority列数值确为10000。

4.2 现象:Mininet中h1 ping h2不通,但h1 ping h3正常

原因:topology.py里主机IP配置错误。项目默认h1=10.0.0.1, h2=10.0.0.2, h3=10.0.0.3,若你手动修改过IP但未同步更新attack_simulator.py的--target参数,攻击包会发向不存在的IP,导致h2收不到SYN包,检测器自然不触发。
解决:统一检查三处IP:①topology.py中Host('h2', ip='10.0.0.2');②attack_simulator.py中--target 10.0.0.2;③controller.py中self.trigger_defense()下发流表时的nw_src值。

4.3 现象:攻击脚本运行后,控制器日志无任何输出,pingall也失败

原因:Ryu控制器未监听正确端口。ryu-manager默认监听6633端口,但Mininet启动时若写成--controller remote,ip=127.0.0.1,port=6653(ONOS默认端口),则连接失败。此时Ryu日志会显示Connection refused,但新手常忽略这一行。
解决:检查Mininet启动命令,确保port=6633;在Ryu终端执行netstat -tuln \| grep :6633确认端口已监听;若端口被占,改用--ofp-tcp-listen-port 6634并同步修改Mininet参数。

4.4 现象:防御流表成功下发,但h2仍能收到SYN包

原因:OpenFlow流表匹配精度不足。原始代码中流表只匹配nw_src,但实际攻击包可能来自不同in_port,若交换机有多个入口,需显式添加in_port匹配。项目add_flow()函数中match = parser.OFPMatch(in_port=in_port, nw_src=src_ip)被注释掉了,需取消注释。
解决:打开controller.py,找到add_flow()函数内# match = parser.OFPMatch(...)行,删除#并确保in_port参数传入正确(通常为攻击包进入交换机的端口号,可通过msg.match.in_port获取)。

4.5 现象:设计报告中提到的“检测延迟<2秒”,但实测从攻击开始到日志输出要5秒以上

原因:滑动窗口长度与检测频率不匹配。detector.py中self.packet_count使用deque(maxlen=10),但检测循环每秒只执行一次,导致窗口实际是10秒而非1秒。设计报告第4.2节明确要求“窗口长度=1秒”,需将maxlen改为1,并增加计数器重置逻辑。
解决:修改detector.py:

# 原代码(错误) self.packet_count = deque(maxlen=10) # 改为(正确) self.packet_count = {} # 字典存储每秒计数 self.last_check_time = time.time() # 在detect_attack()中添加 now = time.time() if now - self.last_check_time >= 1.0: self.packet_count.clear() # 每秒清空 self.last_check_time = now

5. 毕设答辩加分技巧:用三张图讲清技术深度——不是炫技,而是让老师一眼看懂你的工作量

5.1 图1:流表下发时序图(证明你理解OpenFlow握手本质)

不要只贴一张ovs-ofctl dump-flows截图。用PlantUML画时序图,标出四个关键时间点:

  • T0:h1发出第一个SYN包 → s1收到并发送PacketIn给控制器;
  • T1:控制器解析包、判定攻击、构造OFPFlowMod消息;
  • T2:s1接收OFPFlowMod并写入流表 → 此时dump-flows可见新规则;
  • T3:h1第二个SYN包到达s1 → 匹配新流表,执行DROP,不再发PacketIn。

这张图的价值在于:它把抽象的“控制器下发流表”转化成可测量的时间序列,老师能立刻判断你是否真懂OpenFlow交互流程。我当年答辩时,老师指着T2问:“你如何确保T2 < 100ms?”,我当场打开controller.py定位到add_flow()函数里datapath.send_msg(mod)调用,说明这是同步阻塞操作,实测平均耗时42ms(日志里time.time()打点数据),他立刻点头——因为这证明你做过性能压测,不是纸上谈兵。

5.2 图2:双阈值决策矩阵(展示工程权衡能力)

设计报告里“阈值设定”章节容易写成“根据经验设为50”,但答辩时老师会问:“为什么不是40或60?” 用表格呈现你的实验数据:

阈值误报率(正常流量)漏报率(SYN Flood)平均检测延迟
3012%0%0.8s
500.3%2%1.2s
800%18%1.9s

结论栏写:“选择50是平衡点:误报率<0.5%满足校园网运维容忍度,漏报率2%在可接受范围(通过二次检测补救),检测延迟1.2s < 2s答辩要求”。这种基于数据的决策,比任何理论描述都有力。

5.3 图3:防御效果对比柱状图(用真实抓包数据说话)

Wireshark导出h2的SYN包数量CSV,用Python画柱状图:

  • X轴:时间(每秒为单位);
  • Y轴:SYN包数量;
  • 两条柱:蓝色为“无防御”场景(攻击脚本直连h2),红色为“启用本系统”场景;
  • 标出红色柱在第6秒后归零,并添加箭头标注“防御流表生效时刻”。

这张图的杀伤力在于:它把“系统有效”从主观陈述变成客观数据。我见过太多同学答辩时说“我们的系统能防御”,老师反问“证据呢?”,然后全场沉默。而这张图一放,老师只会问:“这个归零是瞬时的还是渐进的?”,你答:“瞬时,因为流表匹配是硬件级的”,他就知道你懂底层。

从那以后我每次做网络类毕设,都强制走一遍这三张图的制作流程——哪怕答辩不要求,我也在报告附录里加上。因为它们不是装饰,而是把“我做了什么”翻译成老师能秒懂的工程语言。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询