ARTICLE DETAIL

资讯详情

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

Django+Docker+Nmap漏洞扫描系统源码拆解与实战复现

Django+Docker+Nmap漏洞扫描系统源码拆解与实战复现 简介这份资源是面向初级运维人员与网络安全研究者的毕业设计文档围绕基于Python的漏洞扫描系统展开重点解决中小型网络环境中安全检测门槛高、工具集成难的问题。文档以Django Web框架实现快速业务开发借助Docker轻量级虚拟化封装Nmap扫描工具构建B/S架构的低学习成本扫描平台涵盖用户认证、信息管理、漏洞扫描、日志文章与权限管理等模块并配有需求分析、逻辑架构与功能设计等章节。资源包共1个docx文件约2.18MB内容为完整的系统设计与实现说明适合作为课程设计、毕业设计或安全工具入门的参考材料。目前已有345人学习下载读者可从中获取系统架构思路、模块划分方式以及Python与Docker在安全场景中的集成方案便于对照完成自己的项目实践。1. 从一份 Django 毕设到能跑的漏洞扫描平台这套源码到底值不值得拆很多刚入行的运维和网络安全方向的学生手里都攥着一份类似“基于 Python 的漏洞扫描系统”的毕设或课程设计。表面看它就是个交作业的文档但真正拆进去会发现它其实是一套完整的 B/S 架构落地样本Django 做 Web 层、Docker 承载 Nmap 扫描容器、MySQL 存扫描记录五个功能模块从认证到权限一条龙。这套东西解决的不是“教你写代码”而是给初级运维和刚摸安全门槛的人一个低学习成本的扫描入口——不用记一长串 nmap 命令浏览器里填个目标 IP 就能出结果。它适合两类人一是需要快速搭一套内部自测工具的中小网络运维二是想通过一个真实项目把 Django、Docker、Nmap 串起来理解的入门研究者。如果你正卡在“知道每个技术名词但不知道怎么拼成一个系统”的阶段这份源码的拆解价值远大于它作为文档本身。2. 技术选型拆解为什么是 Django Docker Nmap 这套组合2.1 Django 的 MTV 模式怎么撑起扫描系统的业务层这套系统选 Django 而不是 Flask 或 FastAPI核心原因在于它自带的东西足够多。Django 的 MTVModel-Template-View模式把数据模型、页面模板和业务逻辑做了强制分离对于漏洞扫描这种“用户提交目标 → 后台执行扫描 → 结果落库 → 前端展示”的流程来说每一段都能找到对应的层去放。Model 层用 ORM 定义scanner_scannerdata表字段包括扫描发起 IP、目标 IP、扫描工具、扫描时间、扫描结果完全不用手写 SQLView 层处理扫描请求的接收和 Docker 容器的调度Template 层用 LayUI 做前端展示配合 Ajax 做异步刷新。这种分层的好处是当你后面想加一个新的扫描类型比如从端口扫描扩展到服务版本探测只需要在 View 里加一个分支、在 Model 里加一个字段不用动整体结构。Django 的另一个隐性优势是自带认证和权限体系。系统里的用户认证模块、权限管理模块本质上都是在 Django 内置的auth_user表和权限系统上做扩展。auth_user表存用户名、密码PBKDF2 加密、超级用户标记account_userinfo表通过外键关联补充职位、个人简介、头像、联系电话。权限管理模块直接复用 Django 的 Group 和 Permission 机制超级管理员可以控制普通用户对各个模块的访问权限。如果换成 Flask这些都要自己从头搭对于一个面向初级运维的工具来说开发成本划不来。2.2 Docker 集成 Nmap容器化扫描的隔离逻辑把 Nmap 放进 Docker 容器里跑而不是直接装在宿主机上这个选择背后有三个实际考虑。第一是环境一致性Nmap 在不同 Linux 发行版上的依赖和版本差异会导致扫描结果有细微差别容器镜像一旦构建好换台机器拉下来跑结果是一样的。第二是资源隔离扫描任务可能瞬间占用大量网络连接和 CPU放在容器里可以限制资源上限不至于把 Web 服务拖垮。第三是安全边界扫描工具本身具有攻击性特征放在容器里与宿主机文件系统隔离降低误操作风险。具体实现上Django 后台通过 Docker SDK for Python 与 Docker 守护进程通信。当用户在前端提交扫描目标后View 层调用 Docker 客户端在预先构建好的 Nmap 镜像上启动一个容器把目标 IP 和扫描参数作为命令传入容器执行完毕后将结果输出到标准输出Django 捕获后写入scanner_scannerdata表再通过 Ajax 返回前端渲染。整个链路的关键在于容器启动时的参数传递和结果回传格式这部分在第四章的实现细节里有对应代码。2.3 Nmap 在系统中的角色定位与扫描能力边界Nmap 在这套系统里承担的是“探测引擎”角色不是完整的漏洞利用工具。它能做的是主机存活探测、端口开放扫描、服务版本识别、操作系统指纹推断。系统里对应的功能是“服务版本检测”和“操作系统检测”两个子项。需要明确的是Nmap 本身不直接输出“这个服务存在 CVE-XXXX 漏洞”这样的结论它给出的是端口、服务名、版本号这些原始信息真正的漏洞判定需要结合版本号去比对漏洞库。这套源码的扫描模块目前停留在信息收集层面没有集成漏洞库比对这是它的能力边界也是后续扩展的入口。从参数角度看系统前端暴露给用户的输入应该尽量简化。Nmap 原生命令有几十个参数组合但面向初级运维的界面只需要暴露目标 IP、扫描类型快速端口扫描 / 服务版本检测 / 操作系统检测两个输入项。后台根据用户选择拼接对应的 Nmap 命令比如快速扫描用-T4 -F服务版本检测用-sV操作系统检测用-O。这种封装思路是把复杂度留在后端前端只做选择不做配置。3. 从零复现环境搭建、数据库配置与扫描模块实现3.1 开发环境与依赖版本锁定这套系统的原始开发环境是 Windows 10 PyCharm 2019.3.4 VMware 虚拟机 MobaXterm 终端数据库用 MySQL前端插件包括 LayUI 2.5.6、Editor.md 1.5、jQuery 1.11。Python 版本 3.7Django 2.2.1PyMySQL 0.9.3。这些版本号看起来旧但组合在一起是经过验证能跑通的。如果你用 Python 3.10 以上配 Django 4.x部分 API 会有变化比如url()要换成re_path()django.conf.urls的导入方式也变了。建议第一次复现时按原始版本走跑通之后再考虑升级。环境搭建的第一步是创建虚拟环境并安装依赖。PyCharm 里可以直接在项目设置里配解释器也可以用命令行python -m venv venv venv\Scripts\activate # Windows pip install django2.2.1 pymysql0.9.3 docker4.2.0这里多装了一个docker库因为扫描模块要通过 Docker SDK 与容器通信。原始文档里没有明确写这个依赖但根据“Docker 容器与前台的通信”这个功能点Docker SDK for Python 是必须的。安装完成后在 Django 项目的__init__.py里加上 PyMySQL 的伪装导入让 Django 以为用的是 MySQLdbimport pymysql pymysql.install_as_MySQLdb()这一步不做的话Django 连接 MySQL 时会报No module named MySQLdb。这是 Python 3 下用 PyMySQL 连接 MySQL 的标准操作很多新手会卡在这里。3.2 settings.py 关键配置与数据库连接Django 的settings.py需要改四个地方语言、时区、数据库、静态文件路径。语言改成zh-hans时区改成Asia/Shanghai这样后台管理界面和日志时间都是中文环境。数据库配置如下DATABASES { default: { ENGINE: django.db.backends.mysql, NAME: vulnscan, USER: root, PASSWORD: your_password, HOST: 127.0.0.1, PORT: 3306, } }数据库名vulnscan需要提前在 MySQL 里创建字符集用utf8mb4否则中文日志内容会乱码。静态文件配置里要加上STATICFILES_DIRS指向项目根目录下的static文件夹LayUI 和 Editor.md 的 CSS、JS 文件都放在那里。配置完成后执行python manage.py migrate生成 Django 内置表再执行python manage.py createsuperuser创建超级管理员账号。3.3 扫描模块的 Docker 调用与结果落库扫描模块的核心逻辑在 View 层。用户在前端提交目标 IP 和扫描类型后View 接收参数调用 Docker SDK 启动 Nmap 容器捕获输出写入数据库。下面是一个简化后的实现骨架import docker from django.http import JsonResponse from .models import ScannerData def run_scan(request): target_ip request.POST.get(target_ip) scan_type request.POST.get(scan_type) # 根据扫描类型拼接 Nmap 参数 cmd_map { quick: [nmap, -T4, -F, target_ip], version: [nmap, -sV, target_ip], os: [nmap, -O, target_ip], } cmd cmd_map.get(scan_type, cmd_map[quick]) client docker.from_env() container client.containers.run( nmap-scanner:latest, commandcmd, removeTrue, network_modehost ) result container.decode(utf-8) # 落库 ScannerData.objects.create( source_addressrequest.META.get(REMOTE_ADDR), target_addresstarget_ip, toolscan_type, resultresult ) return JsonResponse({status: ok, result: result})这段代码里几个关键点docker.from_env()要求宿主机 Docker 服务已启动且当前用户有权限访问 Docker socketnetwork_modehost让容器直接使用宿主机网络栈否则容器内的 Nmap 无法扫描到宿主机所在局域网的目标removeTrue让容器执行完自动删除避免堆积大量停止的容器。ScannerData模型对应scanner_scannerdata表字段包括source_address、target_address、tool、time、result其中time可以设auto_now_addTrue自动记录扫描时间。Nmap 镜像需要提前构建Dockerfile 很简单FROM alpine:latest RUN apk add --no-cache nmap ENTRYPOINT [nmap]构建命令docker build -t nmap-scanner:latest .构建完成后可以用docker run --rm nmap-scanner:latest -sV 127.0.0.1测试镜像是否正常工作。注意 Alpine 的 Nmap 版本可能比官方最新版旧一些但对于端口和服务识别来说够用。3.4 用户认证与权限模块的复用策略用户认证模块不需要自己写登录逻辑直接用 Django 的authenticate和login函数。注册功能在auth_user表插入记录密码用set_password()方法加密。用户信息管理模块通过account_userinfo表与auth_user做一对一外键关联扩展职位、简介、头像等字段。权限管理模块用 Django 的Group和Permission超级管理员在后台给不同组分配不同模块的访问权限。前端用 LayUI 的表格和表单组件做展示Ajax 提交数据后端返回 JSON。日志文章模块用article_articlecolumn、article_articlepost、article_articlepost_users_like三张表分别存分类、文章、点赞记录。文章内容用 Editor.md 做富文本编辑支持 Markdown 语法。这个模块的技术含量不高但它是系统里唯一让用户产生内容的部分对于运维记录工作日志和漏洞修复心得来说比较实用。4. 避坑与排查部署和扫描过程中最容易翻车的五个点4.1 Docker 容器内 Nmap 扫描不到局域网主机现象是容器启动正常、Nmap 也执行了但扫描结果只有容器自身的回环地址目标 IP 显示 host down。原因通常是容器默认使用 bridge 网络模式Nmap 发出的探测包无法到达宿主机所在的局域网。解决办法是在containers.run()里加network_modehost让容器共享宿主机网络命名空间。如果宿主机是 Windows 或 macOShost 模式的行为和 Linux 有差异建议把整个系统部署在 Linux 虚拟机或服务器上。4.2 PyMySQL 版本与 Django 2.2 的兼容报错执行migrate时如果报AttributeError: str object has no attribute decode这是 PyMySQL 0.9.x 和 Django 2.2 的已知兼容问题。解决办法是升级 PyMySQL 到 1.0 以上或者在 Django 的operations.py里手动改一行代码。更稳妥的做法是直接用mysqlclient替代 PyMySQL但mysqlclient在 Windows 上安装需要编译工具链新手容易卡住。折中方案是锁定 PyMySQL 0.9.3 并打补丁。4.3 扫描结果中文乱码Nmap 输出里如果包含中文比如某些服务的 banner 信息存到 MySQL 后显示乱码。原因是数据库字符集不是utf8mb4或者 Django 连接配置里没指定字符集。解决方法是建库时指定CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci并在DATABASES配置里加OPTIONS: {charset: utf8mb4}。另外 Docker 容器的 locale 也要设置Alpine 镜像默认没有中文 locale可以在 Dockerfile 里加ENV LANGC.UTF-8。4.4 扫描任务阻塞导致 Web 页面超时Nmap 全端口扫描-p 1-65535在目标响应慢的情况下可能跑几分钟Django 的同步 View 会一直等容器返回前端 Ajax 请求超时。解决办法是把扫描任务丢到异步队列里用 Celery Redis 做任务分发View 立即返回一个任务 ID前端轮询任务状态。如果不想引入 Celery至少要把 Nmap 的超时参数设上比如--host-timeout 60s避免单个任务无限期挂起。4.5 权限管理模块的越权访问Django 的权限系统默认只控制到 View 级别如果 View 里没有加permission_required装饰器普通用户可以通过直接构造 URL 访问管理员接口。检查方法是把所有需要权限控制的 URL 列出来逐个确认对应的 View 有没有做权限校验。另外scanner_scannerdata表里存了扫描发起 IP 和目标 IP普通用户不应该看到别人的扫描记录查询时要加filter(source_addressrequest.META[REMOTE_ADDR])或者按用户 ID 过滤。5. 进阶技巧把扫描结果从“信息展示”推到“风险判定”这套系统目前给出的扫描结果是 Nmap 的原始输出用户看到的是“80/tcp open http nginx 1.18.0”这样的信息但“nginx 1.18.0 有没有已知漏洞”需要用户自己去查。一个实用的进阶方向是在扫描完成后加一步版本比对把 Nmap 输出的服务名和版本号提取出来去本地的 CVE 数据库或 NVD 的离线镜像里匹配匹配到就标记为“疑似漏洞”匹配不到就标记为“未发现已知漏洞”。实现上可以用 Python 的re模块从 Nmap 输出里提取service和version字段然后查 SQLite 格式的 CVE 库。另一个技巧是给扫描任务加历史对比。scanner_scannerdata表里已经存了每次扫描的结果可以在前端加一个“对比上次扫描”的按钮把同一目标 IP 的最近两次扫描结果做 diff新增的开放端口和变化的 service 版本高亮显示。这个功能对运维来说比单次扫描结果更有价值因为端口变化往往意味着有新的服务上线或者配置被改动。验证扫描结果准确性时不要只依赖系统自己的输出。我一般会同时开一个终端手动跑nmap -sV target把结果和系统输出做对比。如果系统输出少了某些端口检查 Docker 容器的网络模式如果版本号识别不一致检查 Nmap 镜像的版本是否和宿主机一致。还有一点扫描本机127.0.0.1和扫描局域网其他主机的行为可能不同测试时至少覆盖这两种场景。从那以后我每次部署这类扫描系统都会先手动跑一遍 Nmap 确认网络可达再启动容器做集成测试最后才走前端流程。这个顺序能帮你快速定位问题出在网络层、容器层还是应用层。希望帮到你。本文还有配套的精品资源点击获取
返回列表