公司动态
水务系统网络安全防护:从攻击面到落地配置
近年来针对关键基础设施的网络攻击事件明显增多其中水务系统已经成为重点攻击目标之一。就在前不久纽约州宣布拨款 900 万美元用于保护全州范围内的水务系统起因正是其他州接连遭遇了针对水处理设施的恶意攻击。这一事件给所有从事工控系统、水务信息化和 OT 安全的开发者与运维人员敲响了警钟水厂不再是“物理隔离就安全”的传统工业环境它已经深度连接进 IT 网络面临真实的网络威胁。这篇文章不打算停留在新闻解读层面而是围绕“水务系统如何做网络安全防护”这个核心展开。我会先拆解当前水务系统面临的攻击面然后给出基于 OT/IT 融合场景的防护架构再通过可落地的配置与代码示例演示网络分段、访问控制、日志监控、异常检测和数据备份等关键措施。无论你是水务公司的信息化负责人、工控安全工程师还是正在学习关键基础设施安全的开发者这篇文章都能给你一套可以照着做的防护思路。1. 水务系统为何会成为网络攻击目标1.1 水务系统的“脆弱性”从何而来很多人对水务系统的印象还停留在“PLC 控制水泵、氯气消毒、人工抄表”的传统阶段。实际上现在的水务系统已经高度数字化普遍使用 SCADA数据采集与监控系统进行远程监控和调度PLC可编程逻辑控制器、RTU远程终端单元、智能水表、水质在线监测仪等设备都接入了工业网络。更关键的是为了提升管理效率很多水务公司会把 SCADA 网络与办公网络、营业收费系统、云平台进行打通。这让原本“物理隔离”的工控环境变成了一个可被远程触达的数字系统攻击链也随之展开。从真实攻击案例来看水务系统遭受攻击的路径通常有以下几条暴露在公网的 SCADA/HMI 服务存在弱口令或未授权访问漏洞办公网被钓鱼邮件攻陷后攻击者通过 IT/OT 网络边界横向渗透至工控网络水务系统使用的第三方软件存在已知漏洞且长期未修补监控设备、传感器、通信网关的默认密码未修改内部人员误操作或恶意行为导致水处理参数被篡改。1.2 攻击水务系统的后果不仅仅是“停水”攻击水务系统造成的直接影响首先是供水服务中断。更进一步如果攻击者篡改了水处理工艺参数比如氯气投加量、pH 值调节剂用量、沉淀池停留时间等就可能影响出厂水质严重时甚至威胁公共健康。这里要特别说明一点工控系统的攻击后果和传统 IT 系统有很大区别。IT 系统被攻击通常是数据泄露、业务中断而 OT 系统被攻击往往会造成物理设备损坏、环境安全事故、人员伤害。这也是为什么水务系统、电力系统、燃气系统的网络安全防护需要放在“生产安全”的高度来对待。1.3 纽约州 900 万美元拨款背后的行业信号纽约州这 900 万美元拨款本质上是在释放一个明确信号水务系统的网络安全防护已经从“可选项”变成“必选项”。这笔资金主要覆盖的方向通常包括对水务设施进行网络安全风险评估升级老旧的工业控制系统和远程监控设备部署网络分段、入侵检测和日志审计系统为水务公司提供安全培训和应急演练支持。对技术人员来说这意味着岗位需求也会从“懂水处理工艺”向“懂工艺且懂安全”的复合方向转变。无论你是负责 SCADA 系统的工程师还是做水务信息化的开发人员都有必要系统性地掌握工控安全基础。2. 水务系统网络安全防护的整体思路2.1 OT 安全与 IT 安全的区别在正式讲技术方案之前先简单理清 OT 安全和 IT 安全的核心差异。IT 安全的保护对象是数据核心目标是机密性、完整性、可用性优先级通常是“机密性 完整性 可用性”。而 OT 安全的保护对象是物理设备和生产过程核心目标优先级完全不同通常是“可用性 完整性 机密性”。也就是说对于水务系统来说哪怕暂时牺牲一些数据机密性也不能让供水中断。这决定了我们在部署安全设备、安全策略时必须优先考虑对生产连续性的影响。比如SCADA 网络中的防火墙规则不能随便调整因为一旦误阻断可能导致现场设备与调度中心失联。2.2 水务系统安全防护的四个层次根据我接触过的水厂、水务集团项目经验一套相对完整的水务安全防护体系可以拆成四个层次边界防护通过防火墙、工业网闸、VLAN 隔离划分 IT 网络、OT 网络、现场设备层网络身份与访问控制对远程运维、SCADA 操作、PLC 程序上下装进行严格的认证授权推行最小权限原则监测与响应部署日志采集、流量审计、异常告警及时发现入侵行为和工艺参数异常恢复与容灾建立关键设备的配置备份、数据备份机制确保发生攻击后能快速恢复生产。2.3 推荐的安全架构参考下面是一个简化但实用的水务系统安全架构分层图不涉及具体品牌重点看层次划分和防护思路┌──────────────────────────────────────────────┐ │ 企业管理网IT 网络 │ │ 办公终端 / 营业系统 / 邮件系统 / 数据库 │ └──────────────────┬───────────────────────────┘ │ 工业防火墙 / 网闸 │只放行白名单协议 ┌──────────────────▼───────────────────────────┐ │ 生产调度网OT 网络 │ │ SCADA服务器 / 历史数据库 / 操作员站 / 工程师站 │ └──────────────────┬───────────────────────────┘ │ 工业交换机 / VLAN 隔离 ┌──────────────────▼───────────────────────────┐ │ 现场设备层Field 网络 │ │ PLC / RTU / 智能仪表 / 变频器 / 水质传感器 │ └──────────────────────────────────────────────┘在这个架构中每一层之间都要有边界防护每一层的设备都要有身份认证和操作审计。下面我们通过实际配置来演示如何落地。3. 环境准备与版本说明为了便于演示本文选择一套常见的水务监控系统轻量模拟环境。你不需要完全照着我的环境来但核心思路是通用的。建议环境如下组件说明操作系统CentOS 7.9 或 Ubuntu 20.04用于部署监控和日志服务SCADA 服务以 Modbus TCP 模拟水务工艺数据采集演示用数据库MySQL 8.0 或 PostgreSQL 14.x用于存储报警与日志日志采集Filebeat Elasticsearch或简单的 Python 日志采集脚本防火墙iptables / firewalldLinux 环境演示编程语言Python 3.8编写异常检测与告警脚本版本需要根据你的项目实际情况调整本文示例以常见环境为例重点演示配置思路。实际生产环境中的 SCADA 软件、PLC 型号、工业防火墙品牌可能完全不同但网络分段、访问控制、日志监控的底层逻辑是一致的。4. 核心防护技术实操下面进入本文最重要的部分如何从技术层面保护水务系统。我会选取五个最关键的场景分别给出可操作的方案和代码示例。4.1 网络分段用防火墙规则隔离 IT 与 OT 网络网络分段是整个 OT 安全的地基。没有分段所有设备都在一个大二层网络里横向裸奔一旦办公网被攻破攻击者可以直接访问 SCADA 服务和 PLC。在 Linux 环境里我们可以用 iptables 模拟一个简单的三段网络隔离方案。假设网络接口如下eth0连接管理网IT 网络网段 192.168.10.0/24eth1连接生产调度网OT 网络网段 192.168.20.0/24eth2连接现场设备网Field 网络网段 192.168.30.0/24实际生产环境通常用硬件工业防火墙做这件事但策略逻辑一样。下面用 iptables 演示如何实现“IT 网络不能主动访问 OT 网络OT 网络可以有限访问 IT 网络”的规则。# 清理默认规则 iptables -F iptables -X iptables -t nat -F iptables -t mangle -F # 设置默认策略 iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 允许本地回环 iptables -A INPUT -i lo -j ACCEPT # 允许已建立的连接返回 iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # 管理网访问生产调度网默认禁止 # 只允许管理网访问 SCADA 服务器的特定端口例如 502Modbus TCP和 443HTTPS iptables -A FORWARD -i eth0 -o eth1 -d 192.168.20.10 -p tcp --dport 502 -j ACCEPT iptables -A FORWARD -i eth0 -o eth1 -d 192.168.20.10 -p tcp --dport 443 -j ACCEPT iptables -A FORWARD -i eth0 -o eth1 -j DROP # 生产调度网访问现场设备网只允许 SCADA 服务器访问 PLC iptables -A FORWARD -i eth1 -o eth2 -s 192.168.20.10 -d 192.168.30.0/24 -p tcp --dport 502 -j ACCEPT iptables -A FORWARD -i eth1 -o eth2 -j DROP # 现场设备网不能主动访问生产调度网和管理网 iptables -A FORWARD -i eth2 -o eth1 -j DROP iptables -A FORWARD -i eth2 -o eth0 -j DROP # 保存规则以 CentOS 7 为例 service iptables save这里需要注意一个非常关键的细节现场设备网不能主动访问上层网络。实际攻击中攻击者常常通过攻陷现场智能设备比如某台暴露在公网的摄像头作为跳板再横向渗透到调度网。把上行访问全部阻断等于切断了一条重要的横向移动路径。如果公司用的不是 iptables而是硬件工业防火墙配置思路完全一样只是操作界面不同划分安全域、定义白名单访问规则、默认拒绝、只放行业务必需流量。4.2 访问控制为 SCADA 和 PLC 增加认证与最小权限水务系统特别容易出问题的地方是很多老旧的 SCADA 系统没有完善的账号体系甚至存在“一套工程师账号所有人共用”的情况。这在安全上是非常危险的。这里我从两个层面给出建议第一应用层。如果 SCADA 软件本身支持用户权限管理务必启用并且按照岗位分配角色。角色划分建议 - 操作员只能查看实时数据、确认报警、下发预设模式指令 - 工程师可以修改工艺参数、上下装 PLC 程序、修改组态 - 管理员负责账号管理、系统配置、日志审计。第二网络层。针对远程运维场景推荐启用跳板机堡垒机机制。所有工程师远程登录 SCADA 或 PLC 时都必须经过跳板机认证并且全程录屏审计。下面是一个简单的 OpenSSH 配置示例用于限制远程运维只能通过专用跳板机访问生产网络。编辑/etc/ssh/sshd_config# 仅允许 JumpServer 用户登录 AllowUsers jumpadmin # 限制 SSH 登录来源 IP仅允许堡垒机地址 Match Address 192.168.10.100 PermitRootLogin no AllowUsers jumpadmin # 开启详细日志便于审计 LogLevel VERBOSE对于 PLC 的维护口如果暂时没有硬件级防护至少要做到物理隔离管理比如把编程口放在带锁的机柜内并严格登记使用记录。4.3 安全基线修改默认密码与最小化服务水务项目中很多安全问题并不是因为攻击手段多么高明而是因为基础工作没做到位。最常见的三个问题是PLC/HMI 默认密码未修改SCADA 服务器开启了多余的服务端口操作员站安装了与生产无关的软件。针对这些基础问题应该制定一份安全基线检查表。下面是一份参考清单检查项合格标准整改建议设备默认密码已全部修改为强密码按设备型号逐一核对修改后密码纳入密码保险箱管理多余服务端口只保留业务必需端口关闭 RDP、Telnet、FTP 等不安全服务操作员站软件安装只安装生产必需软件禁止安装游戏、浏览器插件、未知来源软件操作系统补丁已安装安全补丁在停机窗口内分批进行补丁更新USB 接口管控已禁用非授权 USB 存储通过组策略或设备管控软件限制 USB 存储设备4.4 日志监控与异常检测光有边界防护和访问控制还不够还必须能够“看见”攻击行为。这里分享一个轻量级的水务系统安全监控方案Python 脚本定时拉取 SCADA 数据、解析关键工艺参数当发现异常时触发告警。先看核心代码。假设我们通过 Modbus TCP 读取现场 PLC 中的几个关键寄存器比如加氯量、pH 值、余氯浓度。以下脚本会周期性拉取数据并进行阈值判断# 文件路径water_monitor.py import time import logging from pyModbusTCP.client import ModbusClient # 日志配置 logging.basicConfig( filename/var/log/water_monitor.log, levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s ) # PLC 连接配置 PLC_HOST 192.168.30.10 PLC_PORT 502 REGISTER_ADDR { chlorine_dosage: 0, # 加氯量 ph_value: 1, # pH 值 residual_chlorine: 2 # 余氯浓度 } # 工艺参数阈值 THRESHOLDS { chlorine_dosage: (0.5, 5.0), # 单位 mg/L范围下上限 ph_value: (6.5, 8.5), residual_chlorine: (0.3, 1.0) } def read_register(addr, quantity1): 读取 PLC 保持寄存器 try: client ModbusClient(hostPLC_HOST, portPLC_PORT, timeout5) if not client.open(): raise ConnectionError(无法连接 PLC) regs client.read_holding_registers(addr, quantity) if regs is None: raise ValueError(读取寄存器失败) # 将原始整数值转换为浮点数按 0.01 缩放具体缩放系数以现场仪表为准 return regs[0] / 100.0 finally: client.close() def check_threshold(param, value): 检查工艺参数是否越限 low, high THRESHOLDS[param] if value low or value high: logging.warning(f参数 {param} 越限: {value}, 正常范围: {low}-{high}) return False return True def main(): while True: try: for param, addr in REGISTER_ADDR.items(): val read_register(addr) check_threshold(param, val) print(f{param}: {val}) except Exception as e: logging.error(f采集异常: {e}) time.sleep(10) if __name__ __main__: main()这个脚本的监控逻辑并不复杂但实际项目中有一个很重要的点阈值不能写死。水处理工艺参数会随着水源水质、季节、用水量变化而变化。如果只是固定阈值很容易出现大量误报导致运维人员产生告警疲劳。更合理的做法是引入“基线漂移检测”。比如取最近 24 小时的同一时段数据作为基线如果当前值偏离基线超过设定比例才触发告警。下面是这个思路的简化示例# 文件路径baseline_check.py from collections import deque import statistics class BaselineDetector: 基于历史基线的异常检测器 def __init__(self, window_size144, deviation_ratio0.2): # window_size 表示保留最近多少个数据点144 个点按 10 分钟一个点计算约等于 24 小时 self.history deque(maxlenwindow_size) self.deviation_ratio deviation_ratio def add_sample(self, value): self.history.append(value) def is_anomaly(self, value): if len(self.history) 30: # 数据不足时不判定异常先积累基线 return False, 0.0 base_mean statistics.mean(self.history) if base_mean 0: return False, 0.0 deviation abs(value - base_mean) / base_mean return deviation self.deviation_ratio, deviation # 使用示例 detector BaselineDetector(window_size144, deviation_ratio0.2) detector.add_sample(0.85) detector.add_sample(0.87) detector.add_sample(0.82) # 某一次采集到异常偏大的加氯量 is_anomaly, dev detector.is_anomaly(1.50) print(f是否异常: {is_anomaly}, 偏离率: {dev:.2%})这种基线检测方式更贴近实际生产场景。如果配合 Kafka、Elasticsearch 这类大数据组件还可以做更复杂的时序异常检测但对于大多数水务公司来说一个能正确理解工艺的规则引擎比一堆复杂的 AI 模型更实用。4.5 数据备份与灾难恢复攻击者一旦成功进入工控网络很多会选择加密数据勒索。对水务系统来说最怕的不是数据丢了而是 PLC 程序、SCADA 组态、历史数据库全部被毁导致整个水厂瘫痪。因此备份策略是水务系统网络安全的最后一道防线。建议对以下几类数据进行定期备份PLC 程序源文件和编译后的工程文件SCADA 组态工程、画面、变量定义、报警配置历史数据库包含工艺参数、报警记录、操作记录网络设备、防火墙、交换机的配置文件。下面是一个简单的定时备份脚本示例将 SCADA 工程目录打包并同步到异地备份服务器#!/bin/bash # 文件路径backup_scada.sh BACKUP_SRC/opt/scada_project BACKUP_DST/backup/scada BACKUP_REMOTEbackup192.168.50.20:/backup/scada DATE$(date %Y%m%d_%H%M%S) # 创建本地备份目录 mkdir -p $BACKUP_DST # 打包 SCADA 工程排除临时文件 tar czf $BACKUP_DST/scada_$DATE.tar.gz \ --exclude*.tmp \ --exclude*.log \ $BACKUP_SRC # 保留最近 30 天备份清理更早的备份 find $BACKUP_DST -name scada_*.tar.gz -mtime 30 -delete # 同步到异地备份服务器 rsync -avz --timeout30 $BACKUP_DST/ $BACKUP_REMOTE/ # 记录备份日志 echo $(date %Y-%m-%d %H:%M:%S) 备份完成: $BACKUP_DST/scada_$DATE.tar.gz /var/log/backup_scada.log需要强调的是备份数据本身也应该受到保护。建议对备份文件进行加密并且备份服务器与生产网络隔离避免攻击者进入系统后把备份一并删除。5. 完整实战案例为一个小型水务监控系统做安全加固为了让你更好地理解这些技术在真实环境中的组合应用下面用一个模拟场景串联起来。5.1 场景描述某小型水厂当前架构如下一台 SCADA 服务器IP192.168.20.10运行组态软件通过 Modbus TCP 采集现场 PLC 数据三台 PLCIP192.168.30.11 ~ 192.168.30.13分别控制加药间、泵房和消毒间办公网终端可以直连 SCADA 服务器登录无二次认证服务器开放了 3389 端口允许远程桌面直接管理现场工程师使用 U 盘进行 PLC 程序上下装无病毒查杀。要求在不影响生产的前提下逐步完成安全加固。5.2 加固步骤第一步先做网络分段。在边界防火墙配置中禁止办公网终端直连 SCADA 的 3389、23Telnet等不安全端口只允许通过堡垒机远程运维。# 拒绝办公网直连 SCADA 的远程桌面端口 iptables -A FORWARD -i eth0 -o eth1 -d 192.168.20.10 -p tcp --dport 3389 -j DROP # 拒绝办公网直连 SCADA 的 Telnet 端口 iptables -A FORWARD -i eth0 -o eth1 -d 192.168.20.10 -p tcp --dport 23 -j DROP第二步在 SCADA 服务器上关闭非必需服务。以 CentOS 7 为例systemctl stop telnet.socket systemctl disable telnet.socket systemctl stop vsftpd systemctl disable vsftpd第三步部署工艺参数监控脚本将采集到的数据存入本地日志并设置告警通道邮件或企业微信机器人。第四步修改所有 PLC 的默认密码并将编程口从“常开”改为“使用时打开、用后关闭”。第五步制定备份计划。每周日凌晨 2 点自动备份 SCADA 工程和 PLC 程序备份文件加密后同步到异地。5.3 验证加固效果加固后可以通过以下方式验证效果在办公网终端尝试 ping SCADA 服务器确认无法访问非白名单端口尝试用 Telnet 连接 SCADA 服务器确认连接被拒绝故意将模拟加氯量数据调高超过阈值确认监控脚本能产生告警日志将备份目录中的老备份文件删除确认异地备份仍可恢复。6. 常见问题与排查思路在实际落地水务系统安全防护时技术和业务上会遇到各种各样的问题。下面整理几个高频问题。问题现象常见原因解决思路加了防火墙规则后 SCADA 通信中断防火墙规则放行了 Modbus TCP 502 端口但 PLC 可能使用多端口或动态端口使用白名单时先用抓包工具确认双方通信的完整端口和协议再逐步收紧规则监控脚本频繁误报阈值设置过于严格未考虑水源季节性变化引入基线漂移检测按时间段动态计算阈值操作员反映登录认证影响工作效率认证流程设计不合理比如每次操作都要求输入复杂密码采用“登录一次 会话空闲锁屏”的模式平衡安全与效率备份文件无法恢复备份脚本只备份了软件工程没有备份 PLC 程序或数据库把备份内容按“系统配置、应用程序、工艺数据、设备固件”分类逐一确认恢复流程远程运维通道被攻击堡垒机账号被盗或弱口令启用多因素认证定期更换密码并严格审计所有登录会话PLC 程序上下装时被杀毒软件误报工业软件与主机防护软件存在兼容性问题在操作员站上设置白名单目录对工业软件目录做排除扫描同时保留系统盘扫描策略7. 最佳实践与工程建议7.1 用“最小权限”原则重新审视每一个操作在做水务系统安全方案的时候我建议把“最小权限”这四个字刻在脑海里。每一个账号、每一个服务、每一个防火墙规则都应该回答一个问题如果这个权限被滥用攻击者能造成多大影响例如现场仪表的维护账号不应该拥有修改 PLC 程序的权限普通操作员账号不应该有修改工艺参数的权限即使是工程师账号也应该通过堡垒机操作确保所有变更都有审计记录。7.2 不要把“合规检查”当成“安全建设”很多水务公司做安全是为了应付等保测评或集团检查。检查一过配置又改回原样监控系统关闭备份任务停止。这种做法是最危险的。安全建设是一个持续运营的过程不是一次性的项目。建议设立月度安全巡检机制至少检查以下内容防火墙规则是否有未使用的放行策略是否新增了未登记的设备或服务账号权限是否发生变化日志审计是否正常备份任务是否成功执行是否存在默认密码或长期未修改的账号。7.3 与工艺部门建立协作机制这一条可能是技术人员最容易忽略的。工控安全工程师往往只关注攻击检测、漏洞修复却忽略了与工艺工程师的协作。实际上工艺工程师最清楚哪些参数异常是“设备故障”哪些参数异常是“攻击行为”。举个例子加氯量突然升高可能是 PLC 程序被篡改也可能是加药泵故障导致反馈错误。如果安全团队不理解工艺就很容易误判。因此建议建立“安全-工艺”联合值班机制在监控平台上把安全告警和工艺报警打通由双方共同研判。7.4 重视供应链安全水务系统使用的 PLC、SCADA 软件、传感器、交换机等设备很多来自不同厂商。第三方设备的固件后门、默认口令、已知漏洞都是潜在风险。采购阶段就应该要求厂商提供安全配置清单和漏洞通报渠道运维阶段要定期检查设备固件版本在停机窗口内及时更新。8. 总结回到开头的新闻纽约州拨出 900 万美元保护水务系统是因为其他州已经发生了针对水处理设施的真实攻击。这个信号值得所有关键基础设施领域的技术人员重视。水务系统的网络安全不再是“将来可能遇到的问题”而是“现在必须解决的问题”。这篇文章围绕水务系统安全防护介绍了 OT 与 IT 安全的区别、四层防护架构、网络分段配置、访问控制、安全基线、日志监控与异常检测、备份恢复等核心内容。如果你所在的公司或单位有类似的水务系统、工控系统建议先从最基础的三件事入手修改所有默认密码、梳理网络边界并配置白名单规则、建立至少一套可靠的备份恢复机制。这三件事做完你已经能挡住绝大多数“碰运气”式的攻击。接下来再逐步完善监控告警和应急演练就能形成持续运营的安全能力。后续如果时间充裕我建议你再深入了解一下等保 2.0 对工控系统的具体要求、IEC 62443 工控安全标准以及 SCADA 协议如 Modbus TCP、OPC UA、DNP3本身的安全机制。这些内容结合起来能够帮助你在水务安全这个细分领域建立起更完整的知识体系。