# 采集网只读隔离与网闸配置 > 对应 EPIC #3「① 边缘采集网关」子任务 **#27**(0.5d,docs): > 现场勘查拓扑与隔离策略(`docs/网络拓扑与隔离策略.md`,#19)的**网关侧落地**—— > 网闸/防火墙**具体配置**、**规则集**、**验证脚本**。 > 安全红线(PRD 5.1 / 9 章):边缘网关**严格只读、不反控、零控制指令下发**。 --- ## 1. 目的与范围 - **目的**:把 #19 的三网隔离策略落为可执行配置(网闸规则 + 驱动只读约束 + 验证方法); - **范围**:边缘网关(采集侧)与网闸/工业防火墙(边界)的配置; - **配套**:拓扑与隔离策略总览见 `docs/网络拓扑与隔离策略.md`; 点位/采样率/协议规范见 `docs/DCS点表需求模板.md`(#16)。 --- ## 2. 只读隔离设计(网关侧) 1. **驱动层只读**:所有采集驱动(`core/edge-gateway/drivers/`)仅暴露 `connect() / read_points() / close()`,**无任何写/控制方法** (`base.py` 安全约束;新增驱动必须遵守,测试含「只读约束」用例)。 2. **协议只读会话**: - OPC UA:只读会话 + 只读账号(如 `iaop_read`,仅授予 Read/Subscribe 权限); - S7:仅建立只读连接(不绑定写数据块); - Modbus:仅功能码 01/02/03/04(读),**禁止** 05/06/0F/10(写)。 3. **零反控通道**:网关进程不配置任何到 DCS/PLC 的写寄存器映射, 点位字典 `protocol` 维度不含写指令(`point_dict/validator.py` 校验)。 --- ## 3. 单向网闸配置 **拓扑**(详见 #19 §2):`采集网 → 单向网闸 → 工业环网`,仅数据外发。 | 配置项 | 值 | 说明 | | --- | --- | --- | | 部署位置 | 采集网出口 / 工业环网入口 | 单向模块(发送) | | 数据方向 | 采集网 → 工业环网(单向) | 反向物理阻断或规则拒绝 | | 白名单源 | 边缘网关 IP(如 `10.20.1.100`) | 仅网关可出 | | 白名单目的 | 数据总线(Kafka)IP/端口 | `10.20.0.10:9093`(mTLS) | | 允许协议 | TCP(Kafka 9093 / 健康上报 443) | 白名单外全拒绝 | | 反向规则 | 工业环网 → 采集网:**DROP** | 杜绝远程控制通道 | > 网闸具体型号规则录入厂商控制台(天融信/网御星云/奇安信等按型号提供 CLI 模板); > 本表为通用配置语义,实施时按现场设备映射。 --- ## 4. 防火墙规则集示例(iptables 风格) ```bash # ---- 采集网侧(边缘网关主机)---- # 默认拒绝 iptables -P INPUT DROP; iptables -P FORWARD DROP; iptables -P OUTPUT DROP # 回环与本机管理 iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A INPUT -s 10.20.1.0/24 -p tcp --dport 22 -j ACCEPT # 运维 SSH(堡垒机) # 只读采集出站:DCS OPC UA(4840)与 S7(102) iptables -A OUTPUT -d 10.20.1.10 -p tcp --dport 4840 -j ACCEPT # 和利时 OPC UA iptables -A OUTPUT -d 10.20.1.20 -p tcp --dport 102 -j ACCEPT # S7-1200 只读 # 数据上行:Kafka(mTLS 9093)与健康上报 iptables -A OUTPUT -d 10.20.0.10 -p tcp --dport 9093 -j ACCEPT iptables -A OUTPUT -d 10.20.0.20 -p tcp --dport 443 -j ACCEPT # 入站写控制:全部拒绝(无任何入站控制通道) # (INPUT 默认 DROP 已覆盖;如需例外必须评审并记录) ``` > 关键点:**出站只放行读采集与数据上行;入站除运维外全拒绝**, > 从网络层再次封死"反控"路径。 --- ## 5. 验证方法 **负向用例(必须零通过)——验证"写不进去"**: | # | 验证项 | 方法 | 期望 | | --- | --- | --- | --- | | V1 | Modbus 写寄存器 | 尝试功能码 05/06/0F/10 写保持寄存器 | 连接被拒/超时/无响应(**零通过**) | | V2 | OPC UA 写节点 | 尝试 `write_value()` 写测点节点 | 权限拒绝(只读账号) | | V3 | S7 写数据块 | 尝试写 DB | 连接不支持/异常 | | V4 | 反向连通性 | 工业环网 → 采集网扫描网关端口 | 全部拒绝 | | V5 | 控制指令下发 | 全链路模拟下发指令 | 网关无对应实现,零指令出站 | **正向用例**: - 采集链路健康:600 点位 1Hz,丢失率 ≤ 0.02%、P99 ≤ 1.8s(`collector/metrics.py`); - mTLS 双向证书验证通过(Kafka 9093,`upstream/kafka_sink.py`)。 **自检命令**(网关侧): ```bash python -m unittest discover -s tests -p "test_*.py" # 驱动只读约束用例 python scripts/check_readonly.py --points point_dict.csv # 点位字典写指令扫描(见 §6) ``` --- ## 6. 只读自检脚本(check_readonly) 随本任务提供轻量自检:扫描点位字典与驱动实现,确认**零写指令**: | 检查项 | 实现 | | --- | --- | | 点位字典 | 校验 `protocol`/`opcNode` 不含写指令语义(无 `write`/`set`/`control` 关键字) | | 驱动代码 | 扫描 `drivers/` 源码不含写方法名(`write`/`set_value`/`control`) | | 配置 | `gateway.yaml` 不含反向/控制通道配置 | > 落地形式:`docs/_check_isolation_doc.py` 附带代码级自检函数 > (也可作为 CI 检查脚本复用)。 --- ## 7. 部署检查清单 - [ ] 网闸规则已录入:单向数据外发、白名单 IP/端口、反向 DROP; - [ ] 边缘网关 iptables 规则集生效(§4 示例); - [ ] 驱动只读:无写方法;OPC UA 只读账号、S7 只读连接、Modbus 仅读功能码; - [ ] 负向用例 V1–V5 全部**零通过**(写不进、连不通); - [ ] 正向用例:丢失率 ≤ 0.02%、P99 ≤ 1.8s、mTLS 验证通过; - [ ] 自检脚本(§6)零告警;审计日志记录规则变更。 --- ## 8. 关联 - `docs/网络拓扑与隔离策略.md`(#19):本配置的上层策略; - `core/edge-gateway/`:驱动只读实现(base.py / drivers / validator); - `docs/DCS点表需求模板.md`(#16):点位/协议字段规范; - PRD 5.1(只读采集)、9 章安全-网络(零控制指令)、12 章等保三级。