自动化漏洞扫描与预警平台
1. 项目概述
本项目旨在构建一个集资产管理、自动化漏洞扫描、风险分析与预警于一体的综合安全管理平台。通过整合 Nmap/OpenVAS 等扫描工具,结合 CMDB 资产数据库,实现漏洞与资产的精确关联,并基于资产重要性进行风险分级预警,帮助企业快速感知和处置安全风险。
1.1 项目背景
随着企业信息化程度的不断提高,网络资产数量急剧增长,安全漏洞层出不穷。传统的漏洞扫描工具虽然能够发现大量漏洞,但存在以下痛点:
- 缺乏业务关联:扫描结果仅显示技术层面的漏洞,无法与业务资产、负责人关联
- 风险分级不准确:仅基于 CVSS 评分,未考虑资产重要性对业务的实际影响
- 预警机制缺失:无法自动通知资产负责人,导致漏洞处置滞后
- 数据孤岛:扫描工具、资产管理系统、漏洞库相互独立,缺乏统一视图
1.2 项目目标
- 资产统一管理:建立 CMDB 资产库,实现 IP、端口、服务、负责人的统一管理
- 自动化扫描:集成主流扫描工具,支持定时扫描和手动触发
- 智能关联分析:通过算法将扫描结果与资产精确关联
- 风险精准评估:结合 CVSS 和资产重要性,计算最终风险等级
- 自动化预警:高危漏洞自动发送邮件通知资产负责人
- 可视化展示:提供风险看板、图表分析,直观展示安全态势
2. 数据集设计
2.1 数据集来源
本项目涉及三类主要数据:
2.1.1 CMDB 资产数据
数据来源:企业资产管理系统(CMDB)或手动录入
数据结构:
- IP 地址:资产网络标识
- 端口:服务开放端口
- 服务类型:Web、数据库、SSH 等
- 负责人:资产维护人员邮箱
- 重要性等级:high(高)、medium(中)、low(低)
示例数据:
csv
ip,port,service,owner,importance
192.168.1.10,80,Web Server,admin@example.com,high
192.168.1.10,22,SSH,ops@example.com,medium
192.168.1.11,3306,MySQL,dba@example.com,high
192.168.1.12,8080,Tomcat,dev@example.com,low
2.1.2 扫描工具输出数据
数据来源:Nmap、OpenVAS 等扫描工具的原始报告
数据结构:
- IP 地址:扫描目标
- 端口:发现漏洞的端口
- 漏洞名称:CVE 编号或漏洞描述
- CVSS 评分:0.0-10.0 的漏洞严重性评分
示例数据:
json
[
{"ip": "192.168.1.10", "port": 80, "vuln_name": "SQL Injection", "cvss": 8.5},
{"ip": "192.168.1.10", "port": 22, "vuln_name": "Weak Password", "cvss": 5.0},
{"ip": "192.168.1.11", "port": 3306, "vuln_name": "Old Version", "cvss": 4.0}
]
2.1.3 CVE 知识库数据
数据来源:CVE 官方数据库或第三方漏洞库
数据结构:
- CVE 编号:标准漏洞标识
- 描述:漏洞详细说明(中文)
- CVSS 评分:标准评分
- 发布日期:漏洞公开时间
- 参考链接:修复建议和详细分析
2.2 数据预处理
-
资产数据清洗:
- 验证 IP 地址格式(IPv4/IPv6)
- 验证端口范围(1-65535)
- 验证邮箱格式
- 去重处理(基于 IP+Port 唯一性)
-
扫描结果解析:
- 解析 XML/JSON 格式的扫描报告
- 提取 IP、端口、漏洞信息
- 标准化漏洞名称(映射到 CVE 编号)
-
数据关联准备:
- 建立 IP+Port 索引,加速匹配
- 处理未匹配资产(标记为 unknown)
3. 核心算法与模型
本项目的核心在于如何将孤立的扫描结果与业务资产进行关联,并进行科学的风险评估。
3.1 漏洞-资产关联算法 (Vulnerability-Asset Mapping)
3.1.1 算法原理
采用精确匹配 策略,使用 (IP, Port) 二元组作为唯一键进行关联。
输入:
- 扫描结果集合:
S = {(IP₁, Port₁, Vuln₁, CVSS₁), ..., (IPₙ, Portₙ, Vulnₙ, CVSSₙ)} - 资产库集合:
A = {(IP₁, Port₁, Owner₁, Importance₁), ..., (IPₘ, Portₘ, Ownerₘ, Importanceₘ)}
算法流程:
python
def associate_vulnerability_with_asset(scan_results, assets_df):
"""
将扫描结果关联到具体资产
参数:
scan_results: 扫描结果列表,每个元素包含 ip, port, vuln_name, cvss
assets_df: 资产数据框,包含 ip, port, owner, importance
返回:
关联后的数据框,包含资产信息和匹配状态
"""
associated_data = []
for result in scan_results:
# 核心匹配逻辑:IP 和 Port 同时匹配
match = assets_df[
(assets_df['ip'] == result['ip']) &
(assets_df['port'] == result['port'])
]
if not match.empty:
asset = match.iloc[0]
entry = result.copy()
entry['asset_id'] = asset['id']
entry['owner'] = asset['owner']
entry['importance'] = asset['importance']
entry['status'] = 'matched' # 匹配成功
else:
# 未找到匹配资产,可能是新发现的端口或未录入的机器
entry = result.copy()
entry['asset_id'] = None
entry['owner'] = None
entry['importance'] = 'unknown'
entry['status'] = 'unmatched' # 未匹配
associated_data.append(entry)
return pd.DataFrame(associated_data)
匹配规则:
- 精确匹配 :
(Scan_IP, Scan_Port) == (Asset_IP, Asset_Port)→ 关联成功 - 未匹配处理 :标记为
unmatched,提示管理员补录资产
时间复杂度:O(n×m),其中 n 为扫描结果数,m 为资产数。实际应用中可通过建立哈希索引优化至 O(n)。
3.1.2 算法优势
- 精确性:IP+Port 二元组确保唯一性,避免误关联
- 可扩展性:支持同一 IP 多个端口的不同资产
- 容错性:未匹配资产不影响已匹配数据的处理
3.2 风险定级模型 (Risk Assessment Model)
3.2.1 模型原理
传统 CVSS 评分仅反映漏洞本身的技术严重性,无法体现对业务的实际影响。本项目引入资产重要性系数进行修正,使风险评估更贴近业务实际。
基础公式:
最终风险分 = CVSS分数 × 资产重要性系数 \text{最终风险分} = \text{CVSS分数} \times \text{资产重要性系数} 最终风险分=CVSS分数×资产重要性系数
重要性系数设定:
- 高重要性 (High):系数 = 1.2(核心业务资产,漏洞影响放大)
- 中重要性 (Medium):系数 = 1.0(标准资产,保持原评分)
- 低重要性 (Low):系数 = 0.8(非关键资产,影响降低)
风险分级标准:
| 最终风险分 | 风险等级 | 颜色标识 | 处置优先级 |
|---|---|---|---|
| ≥ 9.0 | Critical (严重) | 红色 | 立即处理 |
| 7.0 ≤ 分数 < 9.0 | High (高危) | 橙色 | 优先处理 |
| 4.0 ≤ 分数 < 7.0 | Medium (中危) | 黄色 | 计划处理 |
| < 4.0 | Low (低危) | 绿色 | 可延后处理 |
3.2.2 算法实现
python
def calculate_risk_level(cvss, importance):
"""
计算最终风险等级
参数:
cvss: CVSS 基础评分 (0.0-10.0)
importance: 资产重要性 ('high', 'medium', 'low')
返回:
(final_score, risk_level) 元组
"""
# 重要性系数映射
coefficient_map = {
'high': 1.2,
'medium': 1.0,
'low': 0.8
}
coefficient = coefficient_map.get(importance, 1.0)
final_score = cvss * coefficient
# 风险等级判定
if final_score >= 9.0:
risk_level = 'Critical'
elif final_score >= 7.0:
risk_level = 'High'
elif final_score >= 4.0:
risk_level = 'Medium'
else:
risk_level = 'Low'
return final_score, risk_level
3.2.3 模型示例
示例 1:高重要性资产上的高危漏洞
- CVSS = 8.5(高危)
- 重要性 = High(系数 1.2)
- 最终风险分 = 8.5 × 1.2 = 10.2 → Critical(严重)
示例 2:低重要性资产上的高危漏洞
- CVSS = 8.5(高危)
- 重要性 = Low(系数 0.8)
- 最终风险分 = 8.5 × 0.8 = 6.8 → Medium(中危)
示例 3:中重要性资产上的中危漏洞
- CVSS = 5.0(中危)
- 重要性 = Medium(系数 1.0)
- 最终风险分 = 5.0 × 1.0 = 5.0 → Medium(中危)
3.3 算法评估与可视化
基于模拟数据集,对算法进行评估和可视化分析。以下图表展示了算法的评估结果:
(1) 漏洞 CVSS 分数分布

图表说明:
- 图表类型:直方图(Histogram)配合核密度估计曲线(KDE)
- X 轴:CVSS 评分(0.0-10.0)
- Y 轴:漏洞数量(Count)
- 含义 :
- 展示扫描发现的所有漏洞的 CVSS 基础分数分布情况
- 正态分布或偏态分布反映了系统整体的安全健康度
- 如果高分漏洞(>7.0)占比高,说明系统存在较多高危漏洞
- 如果低分漏洞(<4.0)占比高,说明系统整体安全状况较好
分析要点:
- 分布峰值位置:反映大多数漏洞的严重程度
- 分布形状:右偏分布表示存在较多高危漏洞
- 异常值:极高分(>9.0)的漏洞需要重点关注
(2) 漏洞风险等级分布

图表说明:
- 图表类型:饼图(Pie Chart)
- 数据:经过资产重要性修正后的最终风险等级占比
- 颜色标识 :
- Critical(严重):红色
- High(高危):橙色
- Medium(中危):黄色
- Low(低危):绿色
含义:
- 展示经过资产重要性修正后的最终风险等级分布
- 高危和严重级别的漏洞是预警的重点对象
- 各等级占比反映了整体安全态势:
- Critical 占比高 → 系统存在严重安全隐患,需立即处置
- Low 占比高 → 系统整体安全状况良好
- 分布均衡 → 需要分级管理,优先处理高危漏洞
分析要点:
- Critical 和 High 级别漏洞的占比决定了预警工作量
- 与 CVSS 分布对比,可以看出资产重要性修正的效果
(3) 不同资产重要性等级的平均漏洞风险分

图表说明:
- 图表类型:柱状图(Bar Chart)
- X 轴:资产重要性等级(high, medium, low)
- Y 轴:平均风险分(Average Risk Score)
- 含义 :
- 对比不同重要性资产的平均风险分
- 理想情况下,重要资产应受到更严密的防护,平均风险分应较低
- 若高重要性资产的平均风险分反而更高,则说明核心资产存在重大安全隐患,需要加强防护
分析要点:
- 理想状态:高重要性资产的平均风险分 < 中重要性 < 低重要性
- 异常状态 :高重要性资产的平均风险分 > 其他等级,说明:
- 核心资产防护不足
- 需要优先对高重要性资产进行安全加固
- 可能需要调整资产重要性分类
业务价值:
- 帮助识别安全投入与资产重要性的匹配度
- 指导安全资源分配(优先保护高重要性资产)
- 评估安全策略的有效性
3.4 模型训练与优化
3.4.1 模型特点
本项目采用规则引擎而非机器学习模型,具有以下特点:
- 可解释性强:风险计算公式清晰,易于理解和审计
- 无需训练数据:基于专家经验和行业标准(CVSS)设计
- 参数可调:重要性系数可根据企业实际情况调整
3.4.2 参数调优
重要性系数调优:
根据企业实际情况,可以调整重要性系数:
python
# 默认配置(保守策略)
IMPORTANCE_COEFFICIENTS = {
'high': 1.2, # 高重要性资产风险放大 20%
'medium': 1.0, # 标准资产保持原评分
'low': 0.8 # 低重要性资产风险降低 20%
}
# 激进策略(更重视高重要性资产)
IMPORTANCE_COEFFICIENTS_AGGRESSIVE = {
'high': 1.5, # 高重要性资产风险放大 50%
'medium': 1.0,
'low': 0.6 # 低重要性资产风险降低 40%
}
# 保守策略(降低高重要性资产权重)
IMPORTANCE_COEFFICIENTS_CONSERVATIVE = {
'high': 1.1, # 高重要性资产风险放大 10%
'medium': 1.0,
'low': 0.9 # 低重要性资产风险降低 10%
}
调优方法:
- 历史数据分析:分析历史漏洞处置数据,评估不同系数下的预警准确率
- 专家评审:邀请安全专家评估风险分级是否符合实际业务影响
- A/B 测试:在测试环境使用不同系数,对比预警效果
3.4.3 模型评估指标
虽然采用规则引擎,但仍可通过以下指标评估模型效果:
-
关联准确率:
- 定义:正确关联到资产的漏洞占比
- 计算:
准确率 = 匹配成功的漏洞数 / 总漏洞数 - 目标:> 95%
-
风险分级合理性:
- 定义:Critical/High 级别漏洞的处置优先级是否与实际业务影响一致
- 评估方法:专家评审、历史数据验证
-
预警及时性:
- 定义:从漏洞发现到通知资产负责人的时间
- 目标:< 5 分钟
-
误报率:
- 定义:被标记为 Critical/High 但实际影响较小的漏洞占比
- 目标:< 10%
4. 数据库设计
系统采用关系型数据库(SQLite/MySQL)存储核心数据,主要包含资产、扫描任务、漏洞信息及知识库。
4.1 实体关系图 (ER Diagram)
实体关系:
- Asset (资产) 1 : N Vulnerability (漏洞):一个资产可以有多个漏洞
- ScanTask (扫描任务) 1 : N Vulnerability (漏洞):一次扫描可以发现多个漏洞
- Asset 1 : N ScanTask:逻辑关联,通过 IP 地址关联(一个资产可以被多次扫描)
关系说明:
Vulnerability.asset_id→Asset.id(外键,可为空,表示未匹配资产)Vulnerability.scan_task_id→ScanTask.id(外键,必填)ScanTask.target_ip与Asset.ip逻辑关联(用于查询资产相关的扫描任务)
4.2 数据表详解
4.2.1 资产表 (assets_asset)
表说明:存储 CMDB 资产信息,是关联分析的基础数据源。
| 字段名 | 类型 | 长度 | 非空 | 唯一 | 默认值 | 描述 |
|---|---|---|---|---|---|---|
id |
Integer (BigAutoField) | - | Y | Y | AUTO | 主键,自增 |
ip |
GenericIPAddressField | 100 | Y | - | - | 资产 IP 地址(支持 IPv4/IPv6) |
port |
IntegerField | - | Y | - | - | 开放端口(1-65535) |
service |
CharField | 100 | Y | - | - | 服务名称(如 Web Server, MySQL, SSH) |
owner |
EmailField | 254 | Y | - | - | 资产负责人邮箱,用于发送预警通知 |
importance |
CharField | 10 | Y | - | 'medium' | 重要等级:high(高)、medium(中)、low(低) |
created_at |
DateTimeField | - | Y | - | auto_now_add | 录入时间,自动记录创建时间 |
表约束:
- 唯一性约束 :
unique_together = ('ip', 'port'),确保同一 IP 的同一端口不重复录入 - 索引 :在
(ip, port)上建立联合索引,加速关联查询
字段说明:
ip:使用GenericIPAddressField类型,自动验证 IP 地址格式port:整数类型,范围 1-65535importance:使用choices限制可选值,确保数据一致性owner:使用EmailField类型,自动验证邮箱格式
示例数据:
sql
INSERT INTO assets_asset (ip, port, service, owner, importance) VALUES
('192.168.1.10', 80, 'Web Server', 'admin@example.com', 'high'),
('192.168.1.10', 22, 'SSH', 'ops@example.com', 'medium'),
('192.168.1.11', 3306, 'MySQL', 'dba@example.com', 'high');
4.2.2 扫描任务表 (scans_scantask)
表说明:记录每次扫描任务的配置与执行状态,支持任务进度跟踪和日志记录。
| 字段名 | 类型 | 长度 | 非空 | 唯一 | 默认值 | 描述 |
|---|---|---|---|---|---|---|
id |
Integer (BigAutoField) | - | Y | Y | AUTO | 主键,自增 |
target_ip |
CharField | 100 | Y | - | - | 扫描目标(支持单个 IP 或 IP 段,如 192.168.1.0/24) |
scan_tool |
CharField | 20 | Y | - | 'nmap' | 使用工具:nmap、openvas 等 |
parameters |
TextField | - | N | - | '{}' | 扫描参数(JSON 格式),如端口范围、扫描强度等 |
status |
CharField | 20 | Y | - | 'pending' | 任务状态:pending(等待中)、running(扫描中)、finished(已完成)、failed(失败) |
progress |
IntegerField | - | Y | - | 0 | 扫描进度(0-100),用于前端进度条显示 |
logs |
TextField | - | N | - | '' | 实时扫描日志,记录扫描过程的详细信息 |
result_file |
FileField | - | N | - | NULL | 原始报告文件路径(XML/JSON 格式) |
created_at |
DateTimeField | - | Y | - | auto_now_add | 创建时间 |
finished_at |
DateTimeField | - | N | - | NULL | 完成时间(任务结束时记录) |
表约束:
status使用choices限制可选值progress范围 0-100(应用层验证)
字段说明:
-
target_ip:支持单个 IP(如192.168.1.10)或 IP 段(如192.168.1.0/24) -
parameters:JSON 格式存储扫描参数,例如:json{ "port_range": "common", // 常用端口 "intensity": "normal", // 扫描强度 "timeout": 30 // 超时时间(秒) } -
logs:多行文本,记录扫描过程的实时输出,格式:[14:30:15] 扫描任务已启动,目标: 192.168.1.10 [14:30:16] 正在加载扫描插件... [14:30:17] 开始端口扫描... [14:30:20] 发现漏洞: SQL Injection (Risk: Critical)
示例数据:
sql
INSERT INTO scans_scantask (target_ip, scan_tool, status, progress) VALUES
('192.168.1.10', 'nmap', 'finished', 100);
4.2.3 漏洞表 (scans_vulnerability)
表说明:存储扫描发现的具体漏洞详情,包含关联资产信息和风险等级。
| 字段名 | 类型 | 长度 | 非空 | 唯一 | 默认值 | 描述 |
|---|---|---|---|---|---|---|
id |
Integer (BigAutoField) | - | Y | Y | AUTO | 主键,自增 |
asset_id |
ForeignKey | - | N | - | NULL | 关联资产 ID(外键,可为空,表示未匹配资产) |
scan_task_id |
ForeignKey | - | Y | - | - | 来源扫描任务 ID(外键,必填) |
ip |
GenericIPAddressField | 100 | Y | - | - | 漏洞所在 IP 地址 |
port |
IntegerField | - | Y | - | - | 漏洞所在端口 |
name |
CharField | 200 | Y | - | - | 漏洞名称(如 SQL Injection、CVE-2021-44228) |
cvss |
FloatField | - | Y | - | - | CVSS 评分(0.0-10.0,保留 1 位小数) |
risk_level |
CharField | 20 | Y | - | - | 风险等级:Critical(严重)、High(高危)、Medium(中危)、Low(低危) |
description |
TextField | - | N | - | '' | 漏洞详细描述 |
status |
CharField | 20 | Y | - | 'new' | 处置状态:new(已发现)、processing(处理中)、fixed(已修复) |
resolution_note |
TextField | - | N | - | '' | 处置/修复备注(记录修复方法、时间等) |
found_at |
DateTimeField | - | Y | - | auto_now_add | 发现时间,自动记录创建时间 |
表约束:
asset_id外键关联Asset.id,on_delete=models.SET_NULL(资产删除时漏洞保留,但关联置空)scan_task_id外键关联ScanTask.id,on_delete=models.CASCADE(任务删除时漏洞一并删除)risk_level使用choices限制可选值status使用choices限制可选值
字段说明:
asset_id:可为空(NULL),表示该漏洞未匹配到资产(可能是新发现的端口或未录入的机器)ip和port:冗余存储,便于快速查询和统计(避免频繁 JOIN)cvss:浮点数,范围 0.0-10.0risk_level:由算法计算得出,基于 CVSS 和资产重要性status:用于漏洞生命周期管理,支持工作流:new → processing → fixed
示例数据:
sql
INSERT INTO scans_vulnerability (asset_id, scan_task_id, ip, port, name, cvss, risk_level, status) VALUES
(1, 1, '192.168.1.10', 80, 'SQL Injection', 8.5, 'Critical', 'new'),
(2, 1, '192.168.1.10', 22, 'Weak Password', 5.0, 'Medium', 'new');
4.2.4 CVE 知识库表 (knowledge_cve)
表说明:本地化的漏洞详情知识库,存储 CVE 标准漏洞信息,支持漏洞查询和详情展示。
| 字段名 | 类型 | 长度 | 非空 | 唯一 | 默认值 | 描述 |
|---|---|---|---|---|---|---|
id |
Integer (BigAutoField) | - | Y | Y | AUTO | 主键,自增 |
cve_id |
CharField | 20 | Y | Y | - | CVE 编号(如 CVE-2021-44228),唯一标识 |
description |
TextField | - | Y | - | - | 漏洞详细描述(中文),包含漏洞原理、影响范围等 |
cvss_score |
FloatField | - | Y | - | - | 标准 CVSS 评分(0.0-10.0) |
published_date |
DateField | - | Y | - | - | 发布日期(CVE 公开时间) |
references |
TextField | - | N | - | '' | 参考链接(换行分隔,包含修复建议、详细分析等) |
表约束:
cve_id唯一性约束,确保不重复cvss_score范围 0.0-10.0(应用层验证)
字段说明:
-
cve_id:标准 CVE 编号格式,如CVE-2021-44228(年份-编号) -
description:中文描述,便于国内用户理解,例如:Apache Log4j2 远程代码执行漏洞。攻击者可通过构造特殊的日志消息触发远程代码执行, 影响范围广泛,包括大量使用 Log4j2 的 Java 应用。 -
references:多行文本,存储参考链接,例如:https://nvd.nist.gov/vuln/detail/CVE-2021-44228 https://logging.apache.org/log4j/2.x/security.html
示例数据:
sql
INSERT INTO knowledge_cve (cve_id, description, cvss_score, published_date) VALUES
('CVE-2021-44228', 'Apache Log4j2 远程代码执行漏洞', 10.0, '2021-12-10'),
('CVE-2021-34527', 'Windows Print Spooler 权限提升漏洞', 8.8, '2021-07-13');
4.3 数据库索引设计
为提高查询性能,在关键字段上建立索引:
-
资产表索引:
(ip, port)联合唯一索引:加速关联查询importance索引:按重要性筛选资产
-
漏洞表索引:
asset_id索引:查询资产相关漏洞scan_task_id索引:查询任务相关漏洞risk_level索引:按风险等级筛选status索引:按处置状态筛选(ip, port)联合索引:加速 IP+Port 查询
-
扫描任务表索引:
status索引:按状态筛选任务created_at索引:按时间排序
4.4 数据库迁移
使用 Django 的 Migration 机制管理数据库结构变更:
bash
# 创建迁移文件
python manage.py makemigrations
# 应用迁移
python manage.py migrate
5. 系统架构与目录结构
系统基于 Python Django 框架开发,采用 MVT (Model-View-Template) 架构模式,实现前后端分离和模块化设计。
5.1 技术栈
后端技术:
- 框架:Django 5.2.9(Python Web 框架)
- 数据库:SQLite(开发环境)/ MySQL(生产环境)
- 并发处理 :Python
threading模块(多线程扫描) - 邮件服务 :Django
send_mail(预警通知)
前端技术:
- UI 框架:Bootstrap 5(响应式布局)
- 图表库:ECharts 5(数据可视化)
- 模板引擎:Django Template(服务端渲染)
开发工具:
- 数据分析:Pandas、Matplotlib、Seaborn(算法评估)
- 版本控制:Git
5.2 系统架构图
┌─────────────────────────────────────────────────────────┐
│ 前端展示层 │
│ (Bootstrap + ECharts + Django Templates) │
├─────────────────────────────────────────────────────────┤
│ 业务逻辑层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
│ │ 资产管理 │ │ 扫描引擎 │ │ 风险分析 │ │ 预警通知 ││
│ │ (assets) │ │ (scans) │ │ (算法) │ │ (email) ││
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘│
├─────────────────────────────────────────────────────────┤
│ 数据访问层 │
│ Django ORM (Model Layer) │
├─────────────────────────────────────────────────────────┤
│ 数据存储层 │
│ SQLite / MySQL │
└─────────────────────────────────────────────────────────┘
5.3 后端目录结构 (system/)
system/
├── manage.py # Django 项目管理脚本
├── db.sqlite3 # SQLite 数据库文件(开发环境)
│
├── vuln_platform/ # 项目核心配置目录
│ ├── __init__.py
│ ├── settings.py # 项目配置文件(数据库、中间件、应用注册等)
│ ├── urls.py # 根 URL 路由配置
│ ├── wsgi.py # WSGI 部署配置
│ └── asgi.py # ASGI 部署配置(异步支持)
│
├── assets/ # 资产管理应用
│ ├── __init__.py
│ ├── models.py # Asset 模型定义
│ ├── views.py # 视图函数(资产列表、导入、生成测试数据等)
│ ├── urls.py # 应用 URL 路由
│ ├── admin.py # Django Admin 配置
│ ├── apps.py # 应用配置
│ ├── tests.py # 单元测试
│ └── migrations/ # 数据库迁移文件
│ └── 0001_initial.py
│
├── scans/ # 扫描引擎应用(核心模块)
│ ├── __init__.py
│ ├── models.py # ScanTask、Vulnerability 模型定义
│ ├── views.py # 视图函数(任务列表、详情、看板等)
│ ├── utils.py # 核心工具函数(多线程扫描、风险计算、邮件预警)
│ ├── urls.py # 应用 URL 路由
│ ├── admin.py
│ ├── apps.py
│ ├── tests.py
│ └── migrations/ # 数据库迁移文件
│ ├── 0001_initial.py
│ ├── 0002_scantask_scan_tool.py
│ └── 0003_scantask_logs_scantask_progress_and_more.py
│
├── accounts/ # 用户认证应用
│ ├── __init__.py
│ ├── models.py # 用户模型(使用 Django 内置 User)
│ ├── views.py # 登录、注册、用户管理视图
│ ├── forms.py # 表单定义(UserCreationForm、AuthenticationForm)
│ ├── urls.py
│ ├── admin.py
│ ├── apps.py
│ ├── tests.py
│ └── migrations/
│
├── reports/ # 报表应用
│ ├── __init__.py
│ ├── models.py # 报表模型(可选)
│ ├── views.py # 报表生成、下载视图
│ ├── urls.py
│ ├── admin.py
│ ├── apps.py
│ ├── tests.py
│ └── migrations/
│
├── knowledge/ # 知识库应用
│ ├── __init__.py
│ ├── models.py # CVE 模型定义
│ ├── views.py # CVE 查询、列表视图
│ ├── urls.py
│ ├── admin.py
│ ├── apps.py
│ ├── tests.py
│ ├── migrations/
│ │ └── 0001_initial.py
│ └── templates/
│ └── knowledge/
│ └── cve_list.html # CVE 列表模板
│
├── sys_config/ # 系统配置应用
│ ├── __init__.py
│ ├── models.py
│ ├── views.py # 系统维护视图(备份、日志清理、状态监控)
│ ├── urls.py
│ ├── admin.py
│ ├── apps.py
│ ├── tests.py
│ └── migrations/
│
├── templates/ # 前端模板目录
│ ├── base.html # 全局基座模板(侧边栏、顶部栏、公共样式)
│ ├── navigation.html # 导航菜单模板
│ │
│ ├── accounts/ # 用户认证模板
│ │ ├── login.html # 登录页面
│ │ ├── register.html # 注册页面
│ │ ├── profile.html # 个人信息页面
│ │ └── user_list.html # 用户列表(管理员)
│ │
│ ├── assets/ # 资产管理模板
│ │ ├── asset_list.html # 资产列表
│ │ └── asset_detail.html # 资产详情
│ │
│ ├── scans/ # 扫描任务模板
│ │ ├── dashboard.html # 风险看板(首页)
│ │ ├── scan_list.html # 扫描任务列表
│ │ └── scan_detail.html # 扫描任务详情
│ │
│ ├── reports/ # 报表模板
│ │ ├── report_center.html # 报表中心
│ │ └── vuln_kb.html # 漏洞知识库(可选)
│ │
│ └── sys_config/ # 系统配置模板
│ └── data_management.html # 数据管理页面
│
└── static/ # 静态资源目录
├── css/
│ ├── bootstrap.min.css # Bootstrap 5 样式库
│ └── style.css # 自定义样式(玻璃拟态风格)
├── js/
│ ├── bootstrap.bundle.min.js # Bootstrap 5 JavaScript
│ └── echarts.min.js # ECharts 图表库
└── img/ # 图片资源
5.4 核心模块说明
5.4.1 vuln_platform/settings.py 配置说明
关键配置项:
python
# 已安装应用
INSTALLED_APPS = [
'django.contrib.admin', # Django 管理后台
'django.contrib.auth', # 用户认证系统
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'assets', # 资产管理应用
'scans', # 扫描引擎应用
'accounts', # 用户认证应用
'reports', # 报表应用
'knowledge', # 知识库应用
'sys_config', # 系统配置应用
]
# 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3', # 开发环境使用 SQLite
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# 时区配置
LANGUAGE_CODE = 'zh-hans' # 中文界面
TIME_ZONE = 'Asia/Shanghai' # 中国时区
# 登录重定向
LOGIN_REDIRECT_URL = 'vuln_dashboard' # 登录后跳转到风险看板
LOGOUT_REDIRECT_URL = 'login' # 登出后跳转到登录页
LOGIN_URL = 'login' # 未登录访问保护页面时跳转
5.4.2 scans/utils.py 核心功能
多线程扫描引擎:
python
def run_scan_async(task_id):
"""
异步执行扫描任务(在后台线程中运行)
流程:
1. 关闭旧数据库连接,避免 SQLite 锁死
2. 更新任务状态为 running
3. 模拟扫描过程(实际应调用 Nmap/OpenVAS API)
4. 执行漏洞-资产关联算法
5. 计算风险等级
6. 创建漏洞记录
7. 发送预警邮件(高危漏洞)
8. 更新任务状态为 finished
"""
# 实现细节见代码
风险计算函数:
python
def calculate_risk_level(cvss, importance):
"""
计算最终风险等级
参数:
cvss: CVSS 基础评分
importance: 资产重要性
返回:
(final_score, risk_level)
"""
# 实现细节见代码
邮件预警函数:
python
def send_warning_email(vuln, email):
"""
发送预警邮件给资产负责人
邮件内容包含:
- 漏洞名称、风险等级、CVSS 评分
- 资产 IP、端口
- 发现时间
"""
# 实现细节见代码
6. 界面功能与技术实现详解
6.1 登录与注册

功能说明:
- 用户注册:新用户填写用户名、邮箱、密码进行注册
- 用户登录:已注册用户输入用户名和密码进行登录
- 安全机制:CSRF Token 防护、密码加密存储(PBKDF2 哈希)
技术实现:
后端实现 (accounts/views.py):
python
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth import login
def register_view(request):
"""用户注册视图"""
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user) # 注册后自动登录
return redirect('vuln_dashboard')
else:
form = UserCreationForm()
return render(request, 'accounts/register.html', {'form': form})
def login_view(request):
"""用户登录视图"""
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('vuln_dashboard')
else:
form = AuthenticationForm()
return render(request, 'accounts/login.html', {'form': form})
前端实现 (templates/accounts/login.html):
- 使用 Bootstrap 5 表单组件
- 全屏背景图 + 半透明卡片设计(玻璃拟态风格)
- 表单验证:前端 HTML5 验证 + 后端 Django 表单验证
安全机制:
- CSRF 防护:Django 中间件自动添加 CSRF Token
- 密码加密:使用 PBKDF2 算法(Django 默认),不可逆哈希
- 会话管理:使用 Django Session 框架,支持会话过期
6.2 系统导航 (Portal)

功能说明:
- 统一入口:系统的功能导航页面,快速跳转至各功能模块
- 模块分类 :
- 资产管理:资产列表、资产导入
- 扫描任务:任务列表、创建任务
- 风险看板:全局安全态势
- 知识库:CVE 查询
- 报表中心:报告生成
- 系统维护:数据备份、日志管理
界面设计:
- 卡片式布局:每个功能模块以卡片形式展示
- Hover 特效:鼠标悬停时卡片放大、阴影加深
- 响应式设计:移动端自动调整为单列布局
技术实现:
- 使用 Bootstrap 5 Grid System(
col-md-4三列布局) - CSS 过渡动画(
transition)实现悬停效果 - Django 模板变量动态生成链接
6.3 风险看板 (Dashboard)

功能说明:
- 全局安全态势感知:一站式展示系统整体安全状况
- 关键指标卡片 :
- 严重漏洞数(Critical):红色高亮
- 高危漏洞数(High):橙色警告
- 中危漏洞数(Medium):黄色提示
- 低危漏洞数(Low):绿色安全
- 数据可视化 :
- 漏洞等级分布饼图:直观展示各等级漏洞占比
- 近7天趋势折线图:展示漏洞数量变化趋势
- 资产统计柱状图:按重要性统计资产数量
技术实现:
后端实现 (scans/views.py):
python
@login_required
def vuln_dashboard(request):
"""风险看板视图"""
vulns = Vulnerability.objects.all().order_by('-risk_level', '-cvss')
recent_scans = ScanTask.objects.all().order_by('-created_at')[:5]
# 统计各等级漏洞数量
critical_count = vulns.filter(risk_level='Critical').count()
high_count = vulns.filter(risk_level='High').count()
medium_count = vulns.filter(risk_level='Medium').count()
low_count = vulns.filter(risk_level='Low').count()
context = {
'vulns': vulns,
'recent_scans': recent_scans,
'critical_count': critical_count,
'high_count': high_count,
'medium_count': medium_count,
'low_count': low_count,
}
return render(request, 'scans/dashboard.html', context)
前端实现 (templates/scans/dashboard.html):
-
统计卡片:使用 Bootstrap Card 组件,渐变背景色
-
ECharts 图表 :
javascript// 风险分布饼图 var riskChart = echarts.init(document.getElementById('riskPieChart')); var riskOption = { tooltip: { trigger: 'item' }, series: [{ type: 'pie', data: [ { value: {{ critical_count }}, name: 'Critical' }, { value: {{ high_count }}, name: 'High' }, { value: {{ medium_count }}, name: 'Medium' }, { value: {{ low_count }}, name: 'Low' } ] }] }; riskChart.setOption(riskOption);
数据传递:
- Django 模板变量(
{``{ critical_count }})直接嵌入 JavaScript - ECharts 通过 JSON 数据渲染图表
6.4 资产管理

功能说明:
- CMDB 核心视图:统一管理企业 IT 资产
- 功能特性 :
- 资产列表:展示所有资产(IP、端口、服务、负责人、重要性)
- 新增资产:手动录入新资产信息
- 编辑资产:修改资产信息(负责人、重要性等)
- 删除资产:删除不需要的资产记录
- 一键生成测试数据:快速生成模拟资产数据,便于演示和测试
- 一键扫描:直接对特定资产发起扫描任务
- CSV 导入:批量导入资产数据
技术实现:
后端实现 (assets/views.py):
python
@login_required
def asset_list(request):
"""资产列表视图"""
assets = Asset.objects.all()
return render(request, 'assets/asset_list.html', {'assets': assets})
@login_required
def asset_import(request):
"""CSV 导入资产"""
if request.method == "POST":
csv_file = request.FILES.get('csv_file')
# 解析 CSV 文件
reader = csv.DictReader(decoded_file)
for row in reader:
Asset.objects.update_or_create(
ip=row['ip'],
port=int(row['port']),
defaults={
'service': row['service'],
'owner': row['owner'],
'importance': row.get('importance', 'medium')
}
)
return redirect('asset_list')
@login_required
def generate_mock_data(request):
"""生成测试数据"""
# 随机生成资产、扫描任务、漏洞数据
# 用于演示和测试
return redirect('asset_list')
数据模型约束:
unique_together = ('ip', 'port'):确保同一 IP 的同一端口不重复GenericIPAddressField:自动验证 IP 地址格式EmailField:自动验证邮箱格式
前端实现:
- 使用 Bootstrap Table 组件展示数据
- 响应式设计:移动端自动调整列宽
- 操作按钮:编辑、删除、扫描(AJAX 请求)
6.5 扫描任务管理

功能说明:
- 任务列表:展示所有扫描任务(目标 IP、工具、状态、进度、创建时间)
- 创建任务:配置扫描目标、工具、参数,创建新任务
- 任务状态 :
- pending(等待中):任务已创建,等待执行
- running(扫描中):任务正在执行,显示实时进度
- finished(已完成):任务执行完成,可查看结果
- failed(失败):任务执行失败,显示错误信息
- 进度显示:进度条实时显示扫描进度(0-100%)
- 状态徽章:不同状态使用不同颜色标识
- 操作功能 :
- 查看详情:跳转到任务详情页
- 删除任务:删除不需要的任务记录
技术实现:
后端实现 (scans/views.py):
python
@login_required
def scan_list(request):
"""扫描任务列表视图"""
scans = ScanTask.objects.all().order_by('-created_at')
return render(request, 'scans/scan_list.html', {'scans': scans})
@login_required
def create_scan(request):
"""创建扫描任务"""
if request.method == 'POST':
target_ip = request.POST.get('target_ip')
scan_tool = request.POST.get('scan_tool', 'nmap')
parameters = {
'port_range': request.POST.get('port_range', 'common'),
'intensity': request.POST.get('intensity', 'normal')
}
task = ScanTask.objects.create(
target_ip=target_ip,
scan_tool=scan_tool,
parameters=json.dumps(parameters)
)
# 异步启动扫描(多线程)
trigger_scan(task.id)
return redirect('scan_detail', scan_id=task.id)
return redirect('scan_list')
多线程扫描机制 (scans/utils.py):
python
def trigger_scan(task_id):
"""启动后台扫描线程"""
t = threading.Thread(target=run_scan_async, args=(task_id,))
t.start() # 非阻塞,立即返回
def run_scan_async(task_id):
"""后台扫描线程执行函数"""
# 1. 关闭旧数据库连接,避免 SQLite 锁死
connection.close()
# 2. 更新任务状态
task = ScanTask.objects.get(id=task_id)
task.status = 'running'
task.progress = 10
task.logs = "扫描任务已启动...\n"
task.save()
# 3. 模拟扫描过程(实际应调用 Nmap/OpenVAS API)
time.sleep(0.2)
task.progress = 50
task.save()
# 4. 执行漏洞-资产关联和风险计算
# ... (见算法部分)
# 5. 更新任务状态
task.status = 'finished'
task.progress = 100
task.save()
前端实现:
- 进度条:Bootstrap Progress 组件,动态更新宽度
- 状态徽章:Bootstrap Badge 组件,不同状态不同颜色
- 实时刷新 :JavaScript 定时器(
setInterval)轮询任务状态
6.6 扫描任务详情

功能说明:
- 任务信息:显示任务配置(目标 IP、工具、参数、状态、进度)
- 实时日志:显示扫描过程的实时输出(Console Output)
- 漏洞列表 :展示该任务发现的所有漏洞
- 漏洞名称、CVSS 评分、风险等级
- 关联资产、IP、端口
- 处置状态(new/processing/fixed)
- 风险分布图表:ECharts 饼图展示该任务的风险等级分布
- 漏洞操作 :
- 更新状态:标记为处理中或已修复
- 添加备注:记录修复方法和时间
技术实现:
后端实现 (scans/views.py):
python
@login_required
def scan_detail(request, scan_id):
"""扫描任务详情视图"""
scan = get_object_or_404(ScanTask, id=scan_id)
vulns = Vulnerability.objects.filter(scan_task=scan)
# 统计该任务的风险分布
risk_counts = {
'Critical': vulns.filter(risk_level='Critical').count(),
'High': vulns.filter(risk_level='High').count(),
'Medium': vulns.filter(risk_level='Medium').count(),
'Low': vulns.filter(risk_level='Low').count(),
}
context = {
'scan': scan,
'vulns': vulns,
'risk_counts': risk_counts,
}
return render(request, 'scans/scan_detail.html', context)
前端实现:
- 日志显示 :
<pre>标签 + CSS 样式,保持格式 - 实时刷新 :JavaScript 定时器轮询
task.logs和task.progress - ECharts 图表:动态渲染风险分布饼图
- 表单提交:AJAX 更新漏洞状态,无需刷新页面
6.7 漏洞知识库

功能说明:
- CVE 查询:按 CVE 编号搜索漏洞详情
- 漏洞列表 :展示所有 CVE 记录
- CVE 编号(如 CVE-2021-44228)
- CVSS 评分
- 漏洞描述(中文)
- 发布日期
- 参考链接
- 详情展示:点击 CVE 编号查看详细信息
技术实现:
后端实现 (knowledge/views.py):
python
@login_required
def cve_list(request):
"""CVE 列表视图"""
query = request.GET.get('q', '') # 搜索关键词
if query:
cves = CVE.objects.filter(cve_id__icontains=query)
else:
cves = CVE.objects.all()
return render(request, 'knowledge/cve_list.html', {'cves': cves})
数据模型 (knowledge/models.py):
cve_id:唯一标识,建立唯一索引description:中文描述,便于理解cvss_score:标准评分published_date:发布日期
6.8 报表中心

功能说明:
- 报表列表:展示已生成的报告(报告名称、生成时间、大小)
- 生成报告:选择时间范围、风险等级,生成安全报告
- 报告类型 :
- HTML 报告:网页格式,便于在线查看
- PDF 报告:便携格式,便于打印和存档
- 下载报告:点击下载按钮,浏览器自动下载报告文件
技术实现:
后端实现 (reports/views.py):
python
@login_required
def report_center(request):
"""报表中心视图"""
# 展示已生成的报告列表
reports = [
{'id': 1, 'name': '安全报告_2025-01-01.html', 'created_at': '2025-01-01', 'size': '2.5 MB'},
# ...
]
return render(request, 'reports/report_center.html', {'reports': reports})
@login_required
def download_report(request, report_id):
"""下载报告"""
# 生成 HTML/PDF 内容
html_content = generate_report_html(report_id)
# 设置响应头,触发浏览器下载
response = HttpResponse(html_content, content_type='text/html')
response['Content-Disposition'] = 'attachment; filename="report.html"'
return response
报告生成:
- HTML 报告:使用 Django 模板生成 HTML 内容
- PDF 报告 :使用
reportlab或weasyprint库生成 PDF
6.9 系统维护

功能说明:
- 管理员专属区域:仅超级用户可访问
- 系统状态监控 :
- CPU 使用率:实时显示服务器 CPU 使用情况
- 内存使用率:显示服务器内存占用
- 磁盘使用率:显示磁盘空间使用情况
- 系统运行时间:服务器持续运行时间
- 数据库大小:数据库文件占用空间
- 日志大小:日志文件占用空间
- 数据管理 :
- 数据备份:手动触发数据库备份,生成 SQL 文件
- 备份历史:查看历史备份记录
- 日志清理:清理过期日志文件
- 系统信息:显示最后备份时间、系统版本等
技术实现:
后端实现 (sys_config/views.py):
python
from django.contrib.auth.decorators import user_passes_test
def is_admin(user):
"""判断用户是否为管理员"""
return user.is_superuser
@login_required
@user_passes_test(is_admin) # 权限控制装饰器
def data_management(request):
"""系统维护视图"""
# 获取系统状态(实际应调用系统 API)
system_stats = {
'cpu_usage': get_cpu_usage(), # 实际应调用 psutil
'memory_usage': get_memory_usage(),
'disk_usage': get_disk_usage(),
'uptime': get_uptime(),
'db_size': get_db_size(),
'log_size': get_log_size(),
}
return render(request, 'sys_config/data_management.html', {'stats': system_stats})
@login_required
@user_passes_test(is_admin)
def backup_db(request):
"""数据库备份"""
# 使用 Django 的 dumpdata 命令导出数据
# 或直接复制 SQLite 文件
return redirect('data_management')
权限控制:
@user_passes_test(is_admin):装饰器确保只有超级用户可访问- 非管理员访问时自动跳转到登录页
系统监控(实际实现):
python
import psutil # 系统监控库
def get_cpu_usage():
"""获取 CPU 使用率"""
return psutil.cpu_percent(interval=1)
def get_memory_usage():
"""获取内存使用率"""
memory = psutil.virtual_memory()
return memory.percent
def get_disk_usage():
"""获取磁盘使用率"""
disk = psutil.disk_usage('/')
return disk.percent
6.10 用户管理

功能说明:
- 用户列表 :管理员查看所有注册用户
- 用户名、邮箱、注册时间
- 最后登录时间
- 用户状态(活跃/禁用)
- 用户操作 :
- 禁用用户:禁止用户登录
- 删除用户:删除用户账户(谨慎操作)
- 重置密码:管理员可重置用户密码
技术实现:
后端实现 (accounts/views.py):
python
@login_required
@user_passes_test(is_admin)
def user_list(request):
"""用户列表视图(管理员)"""
users = User.objects.all().order_by('-date_joined')
return render(request, 'accounts/user_list.html', {'users': users})
6.11 个人信息

功能说明:
- 个人资料 :用户查看和编辑个人信息
- 用户名(不可修改)
- 邮箱地址(可修改)
- 注册时间
- 最后登录时间
- 密码修改:用户可修改登录密码
- 安全设置:双因素认证等(可选功能)
技术实现:
后端实现 (accounts/views.py):
python
@login_required
def profile(request):
"""个人信息视图"""
if request.method == 'POST':
# 更新用户信息
user = request.user
user.email = request.POST.get('email')
user.save()
messages.success(request, '个人信息已更新')
return render(request, 'accounts/profile.html')
7. 关键技术原理
7.1 多线程扫描引擎
7.1.1 设计背景
Web 应用采用同步请求-响应模型,如果扫描任务在主线程中执行,会导致:
- 请求阻塞:用户需要等待扫描完成才能看到响应
- 超时问题:长时间扫描可能导致 HTTP 请求超时
- 用户体验差:界面卡顿,无法进行其他操作
7.1.2 解决方案
采用多线程模型,将扫描任务放到后台线程执行:
python
import threading
from django.db import connection
def trigger_scan(task_id):
"""
启动后台扫描线程(非阻塞)
"""
t = threading.Thread(target=run_scan_async, args=(task_id,))
t.daemon = True # 设置为守护线程,主进程退出时自动结束
t.start() # 立即返回,不等待线程完成
def run_scan_async(task_id):
"""
后台扫描线程执行函数
"""
try:
# 关键步骤 1:关闭旧数据库连接
# Django 的数据库连接是线程局部的,需要在子线程中重新建立
connection.close()
# 关键步骤 2:重新获取任务对象(在新线程中)
task = ScanTask.objects.get(id=task_id)
task.status = 'running'
task.progress = 10
task.logs = f"[{timezone.now()}] 扫描任务已启动\n"
task.save()
# 关键步骤 3:执行扫描逻辑
# 模拟扫描过程(实际应调用 Nmap/OpenVAS API)
time.sleep(0.2)
task.progress = 50
task.save()
# 关键步骤 4:漏洞关联和风险计算
for finding in mock_findings:
# 漏洞-资产关联
asset_match = Asset.objects.filter(ip=target, port=finding['port']).first()
# 风险计算
cvss = finding['cvss']
importance = asset_match.importance if asset_match else 'medium'
coeff = 1.2 if importance == 'high' else (0.8 if importance == 'low' else 1.0)
final_score = cvss * coeff
# 创建漏洞记录
Vulnerability.objects.create(...)
# 关键步骤 5:更新任务状态
task.status = 'finished'
task.progress = 100
task.save()
except Exception as e:
# 错误处理
task.status = 'failed'
task.logs += f"\n错误: {str(e)}\n"
task.save()
7.1.3 关键技术点
-
数据库连接管理:
- Django 的数据库连接是线程局部的,每个线程需要独立的连接
- 子线程中必须调用
connection.close()关闭旧连接,然后 Django 会自动创建新连接 - SQLite 限制:SQLite 不支持并发写入,多线程写入可能导致锁死,生产环境建议使用 MySQL/PostgreSQL
-
任务状态同步:
- 主线程创建任务后立即返回,前端通过轮询获取任务状态
- 子线程定期更新
task.progress和task.logs,前端实时显示
-
错误处理:
- 使用
try-except捕获异常,避免线程崩溃 - 错误信息写入
task.logs,便于排查问题
- 使用
7.2 动态风险计算
7.2.1 设计理念
风险等级不在入库时固定 ,而是在视图层实时计算,具有以下优势:
- 灵活性:可以随时调整重要性系数,无需重新扫描
- 可追溯性:保留原始 CVSS 评分,可以重新计算风险等级
- 可配置性:不同企业可以配置不同的重要性系数
7.2.2 实现方式
方式一:视图层计算(当前实现)
python
# scans/views.py
@login_required
def vuln_dashboard(request):
vulns = Vulnerability.objects.all()
# 实时计算风险等级(如果需要)
for vuln in vulns:
if vuln.asset:
importance = vuln.asset.importance
coeff = 1.2 if importance == 'high' else (0.8 if importance == 'low' else 1.0)
final_score = vuln.cvss * coeff
# 可以动态更新 risk_level(可选)
# vuln.risk_level = calculate_level(final_score)
# vuln.save()
return render(request, 'scans/dashboard.html', {'vulns': vulns})
方式二:入库时计算(当前实现)
python
# scans/utils.py
def run_scan_async(task_id):
# 在创建漏洞记录时计算风险等级
final_score = cvss * coeff
risk_level = 'Low'
if final_score >= 9.0:
risk_level = 'Critical'
elif final_score >= 7.0:
risk_level = 'High'
elif final_score >= 4.0:
risk_level = 'Medium'
Vulnerability.objects.create(
cvss=cvss,
risk_level=risk_level, # 入库时保存
# ...
)
推荐方案 :采用方式二(入库时计算),因为:
- 性能更好:避免每次查询都重新计算
- 数据一致性:风险等级作为数据的一部分,便于统计和查询
- 如果系数调整,可以通过数据迁移脚本批量更新
7.3 前端响应式布局
7.3.1 Bootstrap 5 Grid System
采用 Bootstrap 5 的 12 列网格系统实现响应式布局:
html
<div class="container-fluid">
<div class="row">
<!-- 侧边栏:桌面端占 3/12,移动端隐藏 -->
<div class="col-md-3 d-none d-md-block">
<nav>侧边栏导航</nav>
</div>
<!-- 内容区:桌面端占 9/12,移动端占 12/12 -->
<div class="col-md-9">
<main>主要内容</main>
</div>
</div>
</div>
响应式断点:
d-none d-md-block:移动端隐藏,桌面端(≥768px)显示col-md-3:桌面端占 3/12 宽度col-md-9:桌面端占 9/12 宽度- 移动端自动调整为单列布局(12/12)
7.3.2 玻璃拟态风格 (Glassmorphism)
使用 CSS 实现玻璃拟态效果:
css
/* style.css */
.card {
background: rgba(255, 255, 255, 0.1); /* 半透明背景 */
backdrop-filter: blur(10px); /* 背景模糊 */
border: 1px solid rgba(255, 255, 255, 0.2); /* 半透明边框 */
border-radius: 15px; /* 圆角 */
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); /* 阴影 */
}
7.4 ECharts 数据可视化
7.4.1 图表集成
使用 ECharts 5 实现数据可视化:
javascript
// 1. 初始化图表容器
var chartDom = document.getElementById('riskPieChart');
var myChart = echarts.init(chartDom);
// 2. 配置选项
var option = {
tooltip: { trigger: 'item' },
legend: { bottom: '0%' },
series: [{
type: 'pie',
radius: ['40%', '70%'], // 环形图
data: [
{ value: {{ critical_count }}, name: 'Critical' },
{ value: {{ high_count }}, name: 'High' },
// ...
]
}]
};
// 3. 渲染图表
myChart.setOption(option);
7.4.2 数据传递
Django 模板变量直接嵌入 JavaScript:
html
<!-- templates/scans/dashboard.html -->
<script>
var criticalCount = {{ critical_count }}; // Django 模板变量
var highCount = {{ high_count }};
// ...
</script>
注意事项:
- 数字类型无需引号,字符串需要引号
- 复杂数据结构使用
json_script过滤器转换为 JSON
7.5 邮件预警机制
7.5.1 实现原理
当发现高危漏洞(Critical/High)时,自动发送邮件通知资产负责人:
python
# scans/utils.py
def send_warning_email(vuln, email):
"""
发送预警邮件
"""
subject = f"[警报] 发现高危漏洞: {vuln.name} (IP: {vuln.ip})"
message = f"""
致资产负责人:
系统在您的资产 ({vuln.ip}:{vuln.port}) 上发现了高风险漏洞。
漏洞详情:
- 名称: {vuln.name}
- 风险等级: {vuln.risk_level}
- CVSS评分: {vuln.cvss}
- 发现时间: {vuln.found_at}
请尽快处理!
"""
try:
send_mail(
subject,
message,
settings.DEFAULT_FROM_EMAIL, # 发件人
[email], # 收件人列表
fail_silently=False
)
except Exception as e:
print(f"邮件发送失败: {e}")
7.5.2 邮件配置
在 settings.py 中配置邮件服务器:
python
# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.example.com' # SMTP 服务器地址
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'noreply@example.com' # 发件人邮箱
EMAIL_HOST_PASSWORD = 'password' # 邮箱密码
DEFAULT_FROM_EMAIL = 'noreply@example.com'
7.6 权限控制机制
7.6.1 登录保护
使用 @login_required 装饰器保护需要登录的视图:
python
from django.contrib.auth.decorators import login_required
@login_required
def vuln_dashboard(request):
# 未登录用户访问时自动跳转到 LOGIN_URL
return render(request, 'scans/dashboard.html')
7.6.2 管理员权限
使用 @user_passes_test 装饰器限制管理员功能:
python
from django.contrib.auth.decorators import user_passes_test
def is_admin(user):
return user.is_superuser
@login_required
@user_passes_test(is_admin)
def data_management(request):
# 仅超级用户可访问
return render(request, 'sys_config/data_management.html')
8. 项目部署与运行
8.1 环境要求
- Python:3.8+
- Django:5.2.9
- 数据库:SQLite(开发)/ MySQL(生产)
- 操作系统:Windows / Linux / macOS
8.2 安装步骤
bash
# 1. 克隆项目
git clone <repository_url>
cd program/system
# 2. 创建虚拟环境
python -m venv venv
source venv/bin/activate # Linux/macOS
# 或
venv\Scripts\activate # Windows
# 3. 安装依赖
pip install django
# 4. 数据库迁移
python manage.py migrate
# 5. 创建超级用户
python manage.py createsuperuser
# 6. 运行开发服务器
python manage.py runserver
8.3 生产环境部署
使用 Gunicorn + Nginx:
bash
# 安装 Gunicorn
pip install gunicorn
# 启动 Gunicorn
gunicorn vuln_platform.wsgi:application --bind 0.0.0.0:8000
# Nginx 配置(/etc/nginx/sites-available/vuln_platform)
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
alias /path/to/static/;
}
}
9. 总结
本平台成功实现了从资产录入、自动扫描到风险预警的闭环管理。通过引入资产重要性因子,解决了传统扫描工具"只报漏洞不分轻重"的痛点,为企业提供了一个可视、可控、可管的轻量级安全运营中心 (SOC)。
9.1 项目亮点
- 智能关联:通过 (IP, Port) 精确匹配,实现漏洞与资产的自动关联
- 精准评估:结合 CVSS 和资产重要性,计算最终风险等级
- 自动化预警:高危漏洞自动通知资产负责人,提高处置效率
- 可视化展示:风险看板、图表分析,直观展示安全态势
- 模块化设计:前后端分离,易于扩展和维护
9.2 技术特色
- 多线程扫描:后台异步执行,不阻塞 Web 请求
- 响应式布局:适配桌面端和移动端
- 数据可视化:ECharts 图表,直观展示安全数据
- 权限控制:基于 Django 的细粒度权限管理
9.3 未来改进方向
- 机器学习:使用历史数据训练模型,自动调整重要性系数
- 实时监控:集成 Prometheus + Grafana,实现实时监控
- API 接口:提供 RESTful API,支持第三方系统集成
- 多租户支持:支持多个企业独立使用
- 漏洞修复建议:自动生成漏洞修复建议和补丁链接
附录
A. 参考文献
B. 项目文件清单
system/:Django 项目源码algorithm/algorithm.ipynb:算法评估 Notebookexplaination/详解.md:本文档explaination/images/:项目截图和算法图表