工业防火墙 - 工控网络保护 (模拟)
概述
这是一个交互式的 Web 组件,旨在模拟工业防火墙在保护关键工控网络(特别是 DCS - 分布式控制系统)免受网络攻击(如勒索软件传播)方面的核心功能。组件通过可视化简化的网络拓扑、模拟网络流量、应用防火墙规则,并记录流量日志和安全告警,来演示基本的网络安全防护概念。
请注意:这是一个高度简化的前端模拟演示,不执行真实的防火墙策略或网络数据包分析。所有网络流量、攻击模式、规则匹配和阻止行为都是基于预设逻辑和随机性在浏览器端模拟生成的。
主要功能
- 网络拓扑可视化 (简化):
- 展示典型的工业网络分层结构:IT 网络、DMZ (隔离区) 和 OT 网络 (DCS)。
- 清晰标示防火墙在 IT/DMZ 之间和 DMZ/OT 之间的位置。
- 通过简单的动画点模拟网络流量在区域间的流动(绿色表示允许,红色表示被阻止)。
- 防火墙规则列表 (概念性):
- 展示一组典型的工业防火墙规则示例,涵盖允许特定工控协议(S7, Modbus, EtherNet/IP)在 OT 网络内部或从受信任源(如 DMZ 特定服务器)访问,以及阻止高风险协议(如 SMB, RDP)跨区域传输或拒绝来自 IT 的直接访问 OT 等。
- 显示规则的描述和状态(启用/禁用,当前均为启用)。
- 提供规则搜索功能。
- 实时流量日志:
- 以表格形式实时记录模拟的网络流量事件。
- 包含信息:时间戳、源区域/IP (简化)、目标区域/IP (简化)、协议/端口、防火墙动作(ALLOW / BLOCK)。
- 允许/阻止的动作以不同颜色高亮显示。
- 提供按动作(允许/阻止)和区域(IT/DMZ/OT)过滤流量日志的功能。
- 安全告警日志 (阻止攻击):
- 当防火墙根据规则阻止了模拟的攻击流量(如来自 IT 的 SMB 访问 OT、外部网络扫描 OT 端口、IT 到 OT 的 RDP 尝试)时,在此面板生成安全告警。
- 告警信息包含时间戳、检测到的攻击类型、源/目标信息以及被触发的阻止规则(概念性)。
- 提供清除当前告警列表的功能。
- 防火墙状态指示:
- 页眉实时显示防火墙的整体状态:
ACTIVE
(运行中),WARNING
(警告,暂未使用),ATTACK BLOCKED
(检测到并阻止攻击)。 - 当有攻击被阻止时,状态变为
ATTACK BLOCKED
,并出现一个醒目的红色告警徽章。
- 页眉实时显示防火墙的整体状态:
- 界面风格: 采用苹果科技工业风格,三栏布局,强调安全、监控和信息的清晰展示,支持响应式设计。
如何使用
- 打开页面: 在浏览器中打开
index.html
。 - 观察拓扑与规则: 在左侧面板查看简化的网络拓扑和防火墙规则列表。
- 监控实时流量: 在中间面板观察实时生成的网络流量日志。注意区分允许 (绿色标识) 和阻止 (红色标识) 的流量。
- 过滤流量: 使用流量日志上方的下拉菜单按动作(允许/阻止)或区域进行过滤,以关注特定类型的流量。
- 识别攻击与告警:
- 观察是否有红色的阻止流量出现在日志中,特别是那些涉及高风险协议(如 SMB)或跨越 IT/OT 边界的流量。
- 当模拟的攻击流量被阻止时,右侧"安全告警"面板会新增一条告警记录。
- 同时,页眉的状态指示灯会变红闪烁,文字变为"检测到并阻止攻击!",并出现红色告警徽章
!
。
- 查看告警详情: 阅读右侧面板中的告警信息,了解模拟的攻击类型、来源、目标和阻止原因。
- 清除告警: 点击告警面板右上角的"清除告警"按钮,将清空告警列表,页眉状态也会恢复(如果之后没有新的攻击被阻止)。
- 搜索规则: 在规则列表上方的搜索框输入关键字过滤规则描述。
模拟细节
- 网络区域与 IP: 定义了 IT, DMZ, OT 三个区域,并为每个区域设定了简化的代表性 IP 地址或地址段。
- 协议: 定义了一系列常见 IT 和 OT 协议及其标准端口和概念性风险等级。
- 防火墙规则: 预设了一组规则,采用自顶向下、首个匹配即生效的简化逻辑。规则包含源/目标区域、源/目标 IP (支持 ‘any’ 和简单的地址段匹配)、协议和动作 (allow/block)。包含了一些关键的默认阻止规则,如阻止 IT->OT 直接访问、阻止跨区域 SMB 等。
- 流量生成: 定时生成"正常"流量,模拟允许的通信模式(如 OT 内部通信、IT 访问 DMZ、受限的 DMZ 访问 OT)。
- 攻击模拟: 以较低频率随机生成几种典型的攻击流量:
- 勒索软件传播尝试: IT -> OT 的 SMB 流量。
- 网络扫描尝试: 外部 IP -> OT 的未知高位端口流量。
- 未授权访问尝试: IT -> OT 的 RDP 流量。
- 流量处理: 每条生成的流量(无论正常或攻击)都会经过规则匹配逻辑,确定最终动作 (allow/block)。
- 告警触发: 当攻击类型的流量被规则阻止时,触发安全告警。
- 状态更新: 防火墙全局状态根据是否有攻击被阻止来更新。
- 流量可视化: 通过在网络拓扑图上动态添加和移除 CSS 动画的"点"来模拟流量,点的颜色和动画路径/终点根据允许/阻止状态变化。
文件结构
安全与维护组件/industrial-firewall-dcs-protection/
├── index.html # 组件的 HTML 结构
├── styles.css # 组件的 CSS 样式
├── script.js # 组件的 JavaScript 逻辑 (模拟流量, 规则匹配, 攻击防御)
└── README.md # 本说明文件
技术栈
- HTML5
- CSS3 (使用了 CSS 变量, Grid 布局, Flexbox, 动画, 媒体查询)
- JavaScript (原生 JS, 无外部库依赖)
效果展示
源码
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>工业防火墙 - 工控网络保护</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="firewall-container">
<header class="main-header">
<h1>工业防火墙 - DCS 网络保护</h1>
<div class="header-status">
<span class="status-indicator" id="firewallStatusIndicator"></span>
<span id="firewallStatusText">初始化中...</span>
<span class="attack-blocked-badge is-hidden" id="attackBlockedBadge">!</span>
</div>
</header>
<main class="main-content">
<!-- Column 1: Topology & Rules -->
<section class="topology-rules-panel panel">
<div class="topology-section">
<h2><i class="icon icon-network"></i> 网络拓扑与防火墙</h2>
<div class="network-topology" id="networkTopology">
<div class="zone it-zone">IT 网络</div>
<div class="zone dmz-zone">DMZ</div>
<div class="zone ot-zone">OT 网络 (DCS)</div>
<div class="firewall-line fw-it-dmz"></div>
<div class="firewall-icon fw-it-dmz-icon">FW</div>
<div class="firewall-line fw-dmz-ot"></div>
<div class="firewall-icon fw-dmz-ot-icon">FW</div>
<!-- Traffic paths/dots added by JS/CSS -->
</div>
</div>
<div class="rules-section">
<h2><i class="icon icon-rules"></i> 防火墙规则 (概念)</h2>
<div class="panel-toolbar">
<input type="search" id="ruleSearch" placeholder="搜索规则...">
<span class="rule-count" id="ruleCount">加载中...</span>
</div>
<ul id="firewallRuleList" class="rule-list">
<li class="placeholder">加载规则中...</li>
<!-- Rules populated by JS -->
</ul>
</div>
</section>
<!-- Column 2: Live Traffic Log -->
<section class="traffic-log-panel panel">
<h2><i class="icon icon-traffic"></i> 实时流量日志</h2>
<div class="panel-toolbar">
<select id="trafficFilterAction">
<option value="all">所有动作</option>
<option value="allowed">允许</option>
<option value="blocked">阻止</option>
</select>
<select id="trafficFilterZone">
<option value="all">所有区域</option>
<option value="IT">IT</option>
<option value="DMZ">DMZ</option>
<option value="OT">OT</option>
</select>
</div>
<div class="traffic-table-container">
<table id="trafficLogTable">
<thead>
<tr>
<th>时间</th>
<th>源区域/IP</th>
<th>目标区域/IP</th>
<th>协议/端口</th>
<th>动作</th>
</tr>
</thead>
<tbody id="trafficLogTBody">
<tr class="placeholder-row"><td colspan="5">等待流量数据...</td></tr>
<!-- Traffic logs populated by JS -->
</tbody>
</table>
</div>
</section>
<!-- Column 3: Security Alerts Log -->
<section class="alerts-log-panel panel">
<h2><i class="icon icon-shield"></i> 安全告警 (已阻止攻击)</h2>
<div class="panel-toolbar">
<button class="action-button clear-alerts-btn" id="clearAlertsBtn"><i class="icon icon-clear"></i> 清除告警</button>
<span class="alert-count" id="alertCount">0 条告警</span>
</div>
<ul id="alertLogList" class="alert-log-list">
<li class="placeholder">暂无安全告警</li>
<!-- Alerts populated by JS -->
</ul>
</section>
</main>
<footer class="main-footer">
<p>© 2024 工业防火墙模拟系统. 概念演示.</p>
</footer>
</div>
<script src="script.js"></script>
</body>
</html>
styles.css
:root {
--bg-color-light: #f9f9f9;
--bg-color-container: #ffffff;
--header-bg: #f5f5f7;
--panel-bg: #ffffff;
--border-color: #d1d1d6; /* Slightly darker border for structure */
--border-color-subtle: #e5e5ea;
--text-primary: #1d1d1f;
--text-secondary: #515154;
--text-label: #6e6e73;
--accent-blue: #007aff;
--accent-green: #34c759;
--accent-orange: #ff9500;
--accent-red: #ff3b30;
--accent-teal: #5ac8fa; /* For network elements */
--accent-grey: #8e8e93;
--status-active: var(--accent-green);
--status-warning: var(--accent-orange);
--status-error: var(--accent-red); /* Could be used for FW error */
--status-attack-blocked: var(--accent-red);
--action-allowed: var(--accent-green);
--action-blocked: var(--accent-red);
--rule-enabled: var(--accent-green);
--rule-disabled: var(--accent-grey);
--zone-it-bg: rgba(0, 122, 255, 0.05);
--zone-dmz-bg: rgba(255, 149, 0, 0.05);
--zone-ot-bg: rgba(52, 199, 89, 0.05);
--list-item-hover-bg: #f0f0f0;
--table-row-hover-bg: #f5faff;
--input-bg: #f0f2f5;
--input-border: transparent;
--input-focus-border: var(--accent-blue);
--placeholder-text: #aaaaaa;
--shadow-color: rgba(0, 0, 0, 0.05);
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--font-monospace: "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--border-radius: 8px;
--border-radius-small: 4px;
--transition-speed: 0.2s;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: var(--font-family);
background-color: var(--bg-color-light);
color: var(--text-primary);
line-height: 1.4;
overflow-x: hidden;
}
.firewall-container {
max-width: 1800px;
margin: 1rem auto;
background-color: var(--bg-color-container);
border-radius: var(--border-radius);
box-shadow: 0 4px 12px var(--shadow-color);
overflow: hidden;
display: flex;
flex-direction: column;
height: calc(100vh - 2rem); /* Limit height */
min-height: 700px; /* Minimum reasonable height */
}
/* Header */
.main-header {
background-color: var(--header-bg);
padding: 0.75rem 1.5rem;
border-bottom: 1px solid var(--border-color);
flex-shrink: 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.main-header h1 {
font-size: 1.3rem;
font-weight: 600;
color: var(--text-primary);
}
.header-status {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
color: var(--text-secondary);
}
.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
background-color: var(--accent-grey); /* Initial */
transition: background-color var(--transition-speed);
}
.status-indicator.active {
background-color: var(--status-active);
}
.status-indicator.warning {
background-color: var(--status-warning);
animation: pulse-orange 1.5s infinite ease-in-out;
}
.status-indicator.attack-blocked {
background-color: var(--status-attack-blocked);
animation: pulse-red 1s infinite ease-in-out;
}
.attack-blocked-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: 50%;
background-color: var(--status-attack-blocked);
color: white;
font-size: 0.8rem;
font-weight: bold;
margin-left: 0.2rem;
animation: badge-pop 0.5s ease-out;
}
.attack-blocked<