Modbus 安全防护白皮书:9个明文传输的真实风险场景与分层防御方案

本文目录
  1. 1. 写在前面的话
  2. 2. Modbus 到底缺了什么
  3. 3. 九个真实风险场景
  4. 4. 场景 1:Modbus TCP 直连公网——502 端口暴露在 Shodan 上
  5. 5. 场景 2:水厂/变电站 Modbus RTU 通过 4G DTU 透明传输上云
  6. 6. 场景 3:Modbus 转 MQTT 网关——MQTT 侧裸奔
  7. 7. 场景 4:工厂内网 Wi-Fi 上的 Modbus TCP 被嗅探
  8. 8. 场景 5:楼宇自控 BACnet-Modbus 网关配置页未设密码
  9. 9. 场景 6:风电场 SCADA 的 Modbus 控制指令被重放
  10. 10. 场景 7:OEM 设备默认配置被利用
  11. 11. 场景 8:寄存器写入攻击——修改设备参数
  12. 12. 场景 9:RS-485 总线物理接入——车间门没锁
  13. 13. 分层防御:从物理层到监控层的完整方案
  14. 14. 网络层:把 Modbus 关进笼子
  15. 15. 传输层:Modbus 加 TLS 的方案
  16. 16. 应用层:Modbus 安全代理/网关
  17. 17. 物理层:RS-485 总线的物理安全
  18. 18. 监控层:Modbus 流量异常检测
  19. 19. 合规性参考
  20. 20. 最低成本防护清单
  21. 21. 和 OPC UA 的安全模型对比
  22. 22. 写在后面

写在前面的话

Modbus 不安全。这不是什么新发现——1979 年 Modicon 设计这个协议的时候,连互联网都没普及,更不会想到有一天 PLC 会通过 4G 模块直接暴露在公网上。那时候的威胁模型是「电缆会不会被老鼠咬断」,不是「有没有人在 502 端口上做中间人攻击」。

但这不代表 Modbus 不能用。一个协议的问题和工程现场的问题是两回事。在机柜里、在被隔离的控制网上、在一对一物理连接的 RS-485 总线上,Modbus 明文的缺点几乎不构成威胁。问题出在什么时候?出在你把那根 RS-485 线接上一个 4G DTU,然后 DTU 配了个公网 IP,然后默认密码还没改。

这篇文章不讲安全理论,讲九个你我都可能遇到的情况——不是「如果」而是「已经发生过」。然后我们讨论在不换设备、不推翻现有架构的前提下,怎么把风险降到一个可接受的水平。

Modbus 到底缺了什么

先搞清楚 Modbus 缺失的到底是什么。不是「不安全」三个字就能概括的。

**没有认证机制。** Modbus TCP 的 MBAP 头里有个 Unit ID 字段,1 字节。这玩意儿是设备地址,不是身份凭证。任何能建立 TCP 连接到 502 端口的人,都可以发送功能码 0x03 读保持寄存器、功能码 0x06 写单个寄存器。试试看:telnet 过去发 `x00x01x00x00x00x06x01x03x00x00x00x01` ——只要设备在线,它就会返回寄存器数据。不需要密码,不需要 token,不需要任何形式的身份验证。

拿功能码 0x05 写单个线圈来说。这一帧只有 12 字节:

| TX ID   | Proto | Len  | UID | FC  | Coil Addr | Value    |
|---------|-------|------|-----|-----|-----------|----------|
| 00 01   | 00 00 | 00 06| 01  | 05  | 00 01     | FF 00    |

这个帧的意思是:把设备 01 的线圈地址 0001 置为 ON。如果你是一个合法的 SCADA 客户端,这没问题。如果你是一个连上 502 端口的陌生人,这也是有效的。设备不会区别对待。

**没有加密。** TCP 载荷里的每一个字节都是明文。Wireshark 用 `modbus` 过滤器可以直接看到事务 ID、功能码、寄存器地址、数据值。抓一包 Modbus TCP 流量等于拿到整套寄存器映射表。一个有心人看你工厂的 Modbus 流量五分钟,能画出所有设备的寄存器图。

**CRC 验不了篡改。** Modbus RTU 的 CRC-16 和 Modbus TCP 依赖的 TCP 校验和,设计目的都是检测物理传输层的比特错误——线缆噪声、电磁干扰导致的数据翻转。它们不是密码学哈希,不能防刻意篡改。攻击者截获一帧,改寄存器值,重新计算 CRC,转发出去,从站无法区分这一帧是不是被改过。

看一下攻击流:

原始帧 (主站→从站): 01 06 00 01 17 70 D8 0B  (写保持寄存器地址0001=6000, 对应50Hz)
截获→篡改后帧:        01 06 00 01 02 58 C9 C3  (改成600, 对应5Hz)

CRC 变了,但攻击者也算得出来。从站收到后照样执行。变频器上限频率从 50Hz 变成了 5Hz——电机没烧,但泵不出水了。

**没有防重放。** Modbus 没有时间戳、没有序列号保护(MBAP 里的事务 ID 只是用来匹配请求与响应,不是安全序号)。同一帧可以无限重放。上个月你给风机发了停机指令,攻击者录下来,下个月再发一次——解码完全一样,设备照样停。

九个真实风险场景

不是说理论上的漏洞,是下面这些事情已经在不同现场发生过。有些是我自己碰到的,有些是同行聊起的,有些是公开报告里的。

场景 1:Modbus TCP 直连公网——502 端口暴露在 Shodan 上

Shodan 上搜 `port:502`,结果数一直在涨。两三年前公开数据大概六七千台,现在早就过万了。这些设备里有 PLC、RTU、网关、智能电表,有的跑在数据中心,有的挂在水厂 SCADA 的主干网上。Shodan 还会抓取设备返回的 Modbus 响应,直接显示设备型号、固件版本。

什么都不用破解。你把设备 IP 配成公网地址,502 端口没做任何 ACL——这就跟把车间大门开着、设备操作面板对着马路一样。

nmap 扫一下更直观:

nmap -p 502 --script modbus-discover <target_ip>

这个 NSE 脚本会尝试读取设备信息。如果设备响应了 0x11(报告从站 ID)或 0x2B(设备识别),它直接告诉你制造商、产品代码、固件版本。零门槛。

场景 2:水厂/变电站 Modbus RTU 通过 4G DTU 透明传输上云

现场用的是 RS-485 跑 Modbus RTU,几十台仪表挂在总线上。为了远程监控,加了个 4G DTU,配置成透明传输模式——DTU 把串口数据打包成 TCP 包发到云端服务器。公网 IP,端口 8899(不是 502,但差别不大)。

问题来了:DTU 和云服务器之间的链路是明文 TCP。任何能在这段链路做 MITM(中间人)的人——不一定是国家级攻击者,可能是运营商内部人员、4G 信号劫持设备、或者同基站下的其他设备利用 LTE 网络漏洞——都可以:

1. 监听所有 Modbus RTU 流量,拿到完整的寄存器映射和实时数据 2. 注入伪造的写指令(功能码 0x06 或 0x10),修改设备参数 3. 甚至向从站发送广播指令(地址 0x00),同时控制总线上所有设备

去年有个水厂的案例:攻击者通过公开的云平台 IP 连上了 DTU 的后台管理端口(默认密码 admin/admin),直接看到整个泵站的控制界面。万幸只是看了,没操作。

场景 3:Modbus 转 MQTT 网关——MQTT 侧裸奔

这种架构现在很常见:Modbus RTU 设备 → 网关做协议转换 → MQTT Broker(云端或本地)→ 上层应用消费。

网关把寄存器数据映射成 MQTT Topic,比如 `/plant1/pump1/pressure` → 保持寄存器 40001 的值。这个设计本身没问题——MQTT 的发布/订阅模型确实比 Modbus 轮询更适合云端场景。

问题出在 MQTT 侧:很多部署没开 TLS,Broker 不需要客户端证书认证,Topic 没有 ACL。攻击者只要知道 Broker 地址和端口(通常 1883,明文 MQTT 默认端口),用 `mosquitto_sub` 就能订阅所有 Topic:

mosquitto_sub -h <broker_ip> -p 1883 -t "#" -v

`#` 是 MQTT 的多级通配符,订阅所有 Topic。几秒钟后,整个工厂的温度、压力、电表读数、设备状态全部到手。如果 Broker 还允许发布(很多网关的双向控制功能依赖这个),攻击者可以直接向控制 Topic 发送指令:

mosquitto_pub -h <broker_ip> -p 1883 -t "/plant1/pump1/control" -m "STOP"

场景 4:工厂内网 Wi-Fi 上的 Modbus TCP 被嗅探

不少工厂为了布线方便,把 Modbus TCP 设备和 SCADA 服务器挂在同一个 Wi-Fi 网络上。Wi-Fi 密码写在设备标签上,贴在机柜外面——防君子不防小人。

内部员工(或者访客、维保人员、离职员工留下的设备)连上这个 Wi-Fi 后,Modbus TCP 流量全是广播域内的明文。Wireshark 抓包:

过滤器: modbus && tcp.port == 502

抓个十分钟就能把所有设备的寄存器映射画出来。如果攻击者还想更进一步,ARP 欺骗把 SCADA 服务器的流量引到自己机器上,然后作为中间人转发——设备端的 Modbus 通信不会中断,SCADA 界面一切正常,后台的数据已经在被实时窃取。

场景 5:楼宇自控 BACnet-Modbus 网关配置页未设密码

楼宇自控系统里,BACnet 和 Modbus 经常会混在一个网关上。比如 Delta Controls、Siemens Desigo 的一些网关产品,既有 Modbus RTU 接口接仪表,又有 BACnet/IP 接口上 BMS。

这些网关通常会提供一个 Web 配置页面。默认情况下,很多集成商上线时只改 IP 地址、配置好寄存器映射,密码还是出厂默认——或者压根没设密码。Web 页面暴露了完整的寄存器映射表、设备地址、功能码配置、甚至在线调试功能——可以直接在里面发 Modbus 读写指令。

Shodan 上搜 `BACnet gateway` 或特定网关型号的产品页面,能找到不少这样的入口。进去了不只是看数据——能直接在 Web 界面上改暖通阀门开度、设空调温度设定值、启停冷水机组。

场景 6:风电场 SCADA 的 Modbus 控制指令被重放

风电场 SCADA 系统通常用 Modbus TCP 和风机 PLC 通信。控制指令包括启停、桨距角调整、偏航控制、功率限制等。

2015 年乌克兰电网攻击事件之后,大家对 OT 安全总算开始重视。但风场的情况比较特殊——很多风场建在偏远地区,远程运维依赖 VPN 或专线,运维人员流动性大,VPN 账号管理经常跟不上。

如果一条「紧急停机」Modbus 指令(功能码 0x05,写某一个线圈)在传输过程中被坏人截获——无论通过什么手段,可能是 VPN 客户端被控、可能是运维笔记本被植入木马、可能是内网横向移动——这个帧可以被保存下来。攻击者不需要理解 Modbus 协议细节,不需要知道寄存器映射,只需要几个月后在夜间重放这个帧。风机收到后就会执行停机。

重放不挑时间、不挑目标。录一次,发一百次。而 Modbus 协议原生没有任何机制能阻止这件事。

场景 7:OEM 设备默认配置被利用

OEM 设备厂商为了提高出货效率,所有的 PLC/RTU 用统一的从站地址(比如地址 01)、统一的功能码支持列表、甚至统一的寄存器映射。更糟糕的是,有些厂商在固件里写死了通信参数——没法改。

这在设备调试阶段很方便。但在实际部署以后,变成安全噩梦。

假设一个分布式光伏项目用了同一批逆变器,所有设备的从站地址都是 01,寄存器映射完全一样(40001=功率,40003=电压,40005=运行状态,40101=开关机控制)。攻击者攻破其中一台设备或者中间的网络节点,他等于拿到了所有设备的控制蓝图。别的设备不用重新侦察——寄存器映射完全是同一份。

场景 8:寄存器写入攻击——修改设备参数

这个场景最危险。Modbus 的保持寄存器不光存测量数据,还存设备参数。变频器上限频率、PID 参数、报警阈值、校准系数——都在寄存器里。能写寄存器的人就能改变设备的物理行为。

具体例子:

设备寄存器地址参数正常值恶意值后果
变频器40018上限频率5000 (=50Hz)500 (=5Hz)泵出水不足,产线停产
温控器40005目标温度250 (=25.0℃)800 (=80.0℃)过温保护跳闸,或者反过来改低导致冻结
电表40045电流变比1001电量数据偏差百倍,能耗核算崩盘
PLC40001运行模式1 (运行)0 (停止)直接让 PLC 停止执行逻辑

不需要做什么复杂攻击。nmap 的 modbus-discover 脚本扫一遍拿到寄存器映射,然后 modbus-cli 或 pymodbus 直接往里写:

from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('192.168.1.100')
client.write_register(18, 500)  # 把变频器上限频率改成5Hz

四行代码。不需要任何权限。变频器收到了就执行。

场景 9:RS-485 总线物理接入——车间门没锁

RS-485 总线的物理安全性几乎是零。总线上的所有设备共享一对差分信号线(A+/B-),任何人在总线的任何位置接上一个 USB-RS485 转换器,就能:

1. **被动监听**:把所有 RS-485 流量记录下来,离线分析 2. **主动注入**:伪装成主站或者从站发送指令 3. **总线干扰**:持续发送数据造成总线冲突,DDoS 整个网络

一个 USB-RS485 转换器淘宝十几块钱。一个机智的攻击者在夜班巡检时,趁人不注意把转换器藏在线槽里,加一个微型 4G 模块做远程接入。谁能发现?没有人会定期检查 RS-485 总线的电气特性。

关键是 RS-485 总线的设计本身就是多站共享介质,不需要交换机、不需要端口接入许可。物理上挂上去就是网络的一员。Modbus RTU 的从站地址只有 1-247,攻击者可以枚举所有地址,逐个探测设备类型。

分层防御:从物理层到监控层的完整方案

讲完九个场景之后,一个自然而然的结论是:不能靠单一手段解决 Modbus 安全问题。它的问题分布在协议栈的每一层,防护也得跟着分。

下面这些方案不是在讲理论——每一条都有对应的产品、开源工具或者配置方法。按自己的现场条件挑着用。

网络层:把 Modbus 关进笼子

**第一条铁律:Modbus 502 端口绝对不要直接暴露在公网上。** 这句话怎么强调都不过分。如果你的设备供应商跟你说「直接把 IP 配成公网的,我们远程维护方便」——换供应商。

具体操作:

**防火墙 ACL 白名单。** 不是黑名单,是白名单。502 端口只允许指定 IP(SCADA 服务器、数据采集网关)访问。Linux iptables 两行搞定:

iptables -A INPUT -p tcp --dport 502 -s 192.168.10.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 502 -j DROP

如果你的设备 CPU 跑不动 iptables,用硬件防火墙(几百块的小型工业防火墙就行),或者至少在路由器/三层交换机上做 ACL。

**VLAN 隔离。** 把 Modbus 设备放在独立的 VLAN 里,和办公网络、Wi-Fi 网络、访客网络完全隔离。VLAN 间路由只放行 SCADA 服务器到 502 端口的流量,其他一概不路由。交换机端口上做 MAC 绑定,防止有人把设备拔了换自己的笔记本。

**VPN/IPsec 隧道。** 需要远程访问的场景,走 VPN 而不是把端口开到公网上。IPsec 或 WireGuard 都可以。OpenVPN 的配置不复杂:

# 服务端只允许 502 端口流量通过隧道
push "route 192.168.10.0 255.255.255.0"

这保证了 Modbus 流量始终在加密隧道里传输。即使攻击者拦截了 VPN 链路,TLS/AES 加密也会让他拿不到明文。

传输层:Modbus 加 TLS 的方案

提到 Modbus 加 TLS,得先说现状:**Modbus Organization 在 2018 年 10 月发布了 Modbus/TCP Security 规范**。核心变化:默认端口从 502 改为 802,TLS 1.2 强制,X.509v3 证书做身份认证,同时引入基于角色的访问控制(Role-Based Access Control,RBAC)。

规范定义了四个角色:

角色 ID角色名权限
0Administrator全功能码、全寄存器、设备管理
1Operator读写所有寄存器,不能改配置
2Engineer调试诊断权限
3Observer只读数据,不能写

这彻底解决了 Modbus 无认证的问题——客户端必须持有有效证书才能建立 TLS 连接,证书中的角色字段决定了能执行哪些功能码。

但现实是,支持 802 端口的设备少得可怜。绝大多数存量设备只支持 502 明文。不换设备怎么加 TLS?

**stunnel 方案。** stunnel 是一个轻量的 TLS 代理,能把任意 TCP 连接封装到 TLS 隧道里。部署架构:

SCADA 客户端 → stunnel(本地127.0.0.1:1502) → TLS → stunnel(远程) → 设备(502)

stunnel 配置很短:

# 客户端 stunnel.conf
[modbus-client]
client = yes
accept = 127.0.0.1:1502
connect = 192.168.10.1:802
verifyChain = yes
CAfile = /etc/stunnel/ca.pem
cert = /etc/stunnel/client.pem
key = /etc/stunnel/client.key

# 服务端 stunnel.conf
[modbus-server]
client = no
accept = 802
connect = 127.0.0.1:502
cert = /etc/stunnel/server.pem
key = /etc/stunnel/server.key
CAfile = /etc/stunnel/ca.pem
verifyChain = yes

客户端软件连 `127.0.0.1:1502` 而不是直连设备的 502。中间的 TLS 加密对上层完全透明。stunnel 本身只有几百 KB,可以跑在嵌入式 Linux 网关、树莓派、甚至 OpenWrt 路由器上。

**注意:** stunnel 解决的是传输加密问题,不解决应用层认证问题。它保证了传输链路不被窃听和篡改,但一旦 TLS 隧道建好,Modbus 帧本身依然是明文——只是这个明文只在加密隧道和保护的内网之间传输。如果攻击者能进入内网并直接连设备的 502,stunnel 保护不了。

应用层:Modbus 安全代理/网关

如果你不能在每个设备端部署 stunnel,或者需要更细粒度的控制,在 Modbus 总线和上层应用之间加一个安全代理/网关是性价比最高的方案。

Moxa MGate 系列、Hilscher netTAP、Advantech ADAM-4570 这些工业网关都支持访问控制列表。你可以在网关上配置:

– 哪个 IP 可以访问哪些从站地址 – 允许哪些功能码通过 – 寄存器级读写控制——比如地址 40001-40050 只读,40051-40100 可读写 – 连接速率限制(防暴力轮询/DoS)

选型时看清楚:不是所有 Modbus 网关都支持安全策略。很多廉价网关只是做透传,ACL 功能在选型表里要找 `Access Control` 或 `Security Policy` 字段。

开源方案也不是没有。用 pymodbus 写一个代理也就几百行代码:

# 简化版 Modbus 安全代理逻辑
ALLOWED_FUNCTION_CODES = {0x03, 0x04, 0x06, 0x10}  # 只允许这些功能码
READ_ONLY_REGISTERS = range(40001, 40051)  # 这个地址段只读

def proxy_handler(request):
    if request.function_code not in ALLOWED_FUNCTION_CODES:
        return exception_response(request.function_code, 0x01)  # 非法功能码
    
    if request.function_code in {0x06, 0x10}:
        for addr in request.addresses:
            if addr in READ_ONLY_REGISTERS:
                return exception_response(request.function_code, 0x02)  # 非法数据地址
    
    # 转发到实际设备
    return forward_to_device(request)

这几行挡掉了场景 8 里大部分寄存器写入攻击。

物理层:RS-485 总线的物理安全

物理安全听起来「低级」,但九个场景里至少三个和物理接入有关。

最低成本也能做的几件事:

1. **机柜上锁。** 不只是一个简单的钥匙锁——用电子门禁,记录谁什么时候开了哪个机柜。异常时间(凌晨两三点)的机柜开门=物理安全事件。 2. **RS-485 总线用带屏蔽的双绞线走线槽。** 线槽加封条,拆开有痕迹。不是防不住,是让攻击者留下证据。 3. **USB 端口禁用。** 工厂里的工控机/HMI 不需要插 U 盘。BIOS 禁用 USB、Windows 组策略禁用可移动存储。有人插 USB-RS485 转换器,系统不识别。 4. **总线终端电阻加防拆传感器。** RS-485 总线两端各有一个 120Ω 终端电阻。如果一个电阻被移除(有人在线中间接了一个监听设备导致阻抗变化),总线的电气特性会变化——可以用总线分析仪检测。

花不了多少钱,但挡住 90% 的物理接入攻击足够了。

监控层:Modbus 流量异常检测

前面的所有措施都是「不让他进来」。但对「已经进来了」或者「合法用户做了不合法的事」的情况,你还需要检测能力。

Modbus 流量的异常特征很明确——正是因为协议简单,异常更容易识别:

**轮询周期突变。** SCADA 系统通常以固定周期轮询设备(比如每秒一次)。如果某个从站的请求频率突然从 1 次/秒变成 100 次/秒,大概率不是 SCADA 的行为。可能是有人在暴力扫描寄存器。

**非标准功能码出现。** 一个只用了 0x03(读保持寄存器)和 0x06(写单个寄存器)的系统,突然出现 0x08(诊断)或 0x2B(设备识别)请求——这是侦察行为的典型特征。

**非工作时间流量。** 工厂停产时段(比如晚上 11 点到早上 6 点),Modbus 总线上不应该有大量读写指令。如果有,报警。

**异常功能码组合。** 短时间内出现 0x05(写单个线圈)、0x06(写单个寄存器)、0x10(写多个寄存器)的密集组合,且目标地址跨越多个不相邻的区域——几乎可以确定是恶意操作。

开源工具方面:

# Zeek (原Bro) 有 Modbus 协议解析器
# 写一个检测脚本放在 Zeek 的策略目录

Wireshark + Modbus 插件可以用来做离线流量审计。把一天的总线流量抓下来,用 Wireshark 的 `Statistics` → `Protocol Hierarchy` → `Modbus` 看功能码分布。功能码 0x08 和 0x2B 的出现是红旗。

nmap 的 `modbus-discover` NSE 脚本应该周期性地从你自己的 SCADA 服务器运行,检查有没有新的 Modbus 设备出现在网络上:

nmap -p 502 --script modbus-discover 192.168.10.0/24

发现了不属于你的设备,事情就严重了。

合规性参考

不展开讲法规条文,只说对 Modbus 部署直接有影响的几条。

**IEC 62443-3-3** 定义了工业自动化和控制系统的七个基础要求(FR1-FR7)。其中 FR2(使用控制)要求对工业通信实施认证和授权,FR3(系统完整性)要求对通信数据进行完整性校验。明文 Modbus 直接不符合 FR2 和 FR3。加 stunnel/VPN 后可以满足密码学层面的要求。

**NERC CIP(北美电力可靠性标准)** 的 CIP-005 要求对电力系统电子安全边界(ESP)实施访问控制。这意味着如果你在美国电力行业用 Modbus 传输控制指令,502 端口必须在 ESP 内部或者通过 ESP 的加密隧道,不能裸奔。CIP-007 还要求系统打补丁和最小化端口,和 Modbus 设备的固件管理直接相关。

**中国等保 2.0(GB/T 22239-2019)** 对工控系统有专门的扩展要求。主要包括:控制网络和非控制网络之间实施边界防护和技术隔离;使用广域网进行控制指令传输时采用加密认证;工业控制系统内部根据业务划分安全域并实施隔离。用 Modbus 的设备如果在等保三级及以上的系统里,基本的网络隔离、通信加密、访问控制是硬性要求,没有可选余地。

这些合规要求不是摆设——审计的时候会查网络架构图、防火墙规则、抓包验证。拿 Modbus TCP 明文走公网通不过任何一项合规审计。

最低成本防护清单

如果你在一个中小工厂、预算有限、设备老旧不能换、也没有专职安全工程师,下面 5 条是你现在就能做的。**这 5 条挡住 90% 的攻击,不需要额外采购设备:**

1. **检查所有 502 端口是否可以从公网访问。** 到 https://www.shodan.io 搜你的公网 IP 段,或者在外部网络用 `nmap -p 502 <公网IP>` 扫一遍。发现暴露的,立刻关掉端口映射或者加 AC。 2. **Modbus 网关/DTU 改默认密码。** 不只是网关的 Web 管理页面——确认 DTU 的 AT 指令配置密码(如果支持)、MQTT Broker 的认证、VPN 的预共享密钥,全部改掉。 3. **把 Modbus 设备放在独立 VLAN,配置白名单 ACL。** 如果交换机不支持 VLAN,至少划一个独立的 IP 子网,路由器上做 ACL,只允许 SCADA 服务器 IP 访问 502。 4. **在 SCADA 服务器上跑一次 Wireshark 抓包审计。** 记录一小时的总线流量,检查有没有异常功能码(0x08, 0x2B)、有没有出现在不该在的设备地址。 5. **定期用 nmap 扫描 Modbus 网络。** 写个 cron 每周跑一次 `nmap -p 502 –script modbus-discover <子网>`,把输出 diff 一下。出现新设备=有人接了什么东西进去。

把上面 5 条落实了,再谈要不要上专用的 OT 安全平台、要不要做 SIEM 集成。大多数小工厂连第一条都没做。

和 OPC UA 的安全模型对比

Modbus 安全绕不开 OPC UA。不是说谁替代谁,是搞清楚两者的安全模型差距,避免选型时做出离谱决策。

维度Modbus TCP (原生)OPC UA
认证X.509 证书、用户名/密码、Kerberos
传输加密TLS 1.2/1.3 (UA-TCP) 或 HTTPS (UA-HTTPS)
数据签名每条消息可单独签名 (UA-SecureConversation)
访问控制会话级+节点级 ACL
审计日志依赖应用层内置审计事件类型
协议复杂度极简,12 字节帧二进制编码,完整 OO 对象模型

OPC UA 把安全做进了协议栈,从传输层到应用层都有对应的安全机制。Modbus 把一切扔给了实现者。这不是 OPC UA 比 Modbus 「更好」——这是两种完全不同的设计哲学。OPC UA 的安全复杂度也是代价:TLS 握手、证书管理、信任链、CRL/OCSP 吊销检查——这些在嵌入式 Modbus 设备上是天方夜谭。STM32 跑 Modbus RTU 只需要一个 UART 和两三百行 C 代码,跑 OPC UA 需要 TLS 库、XML 解析器、至少几十 KB 的 RAM。

所以结论不是「大家都用 OPC UA」。是:如果你本来就在用 Modbus,别因为它不安全就推翻整个系统换成 OPC UA——加 stunnel、防火墙 ACL、安全代理的成本远低于换协议。如果你是新建系统、选型阶段、设备资源充足、需要面向 IT/OT 融合架构——OPC UA 天然的安全能力会让你在后期的合规和运维上省很多事。

写在后面

Modbus 的安全问题不是一个技术问题,是一个工程管理问题。协议本身没有安全能力,但你可以通过部署架构把它放到一个受保护的环境里。就像你不会把一台没有防火墙的服务器直接挂在公网上一样,你也不应该让 Modbus 设备直接面对不可信网络。

说到底,最危险的从来不是协议漏洞,而是有人觉得「我们这种小厂没人攻击」。攻击者不挑大厂小厂——自动化扫描工具一视同仁,502 端口开着就进来。

有问题再聊,或者你自己开 Wireshark 抓一包看看——大概率你会被惊到的。

技术术语(共 13 个)—— 点击展开
Modbus RTU基于串行链路的Modbus协议,使用二进制编码和CRC校验
Modbus TCP基于以太网的Modbus协议变体,使用TCP/IP传输
RS485工业常用的差分串行通信标准,支持多点通信
功能码Modbus功能码指定读/写操作类型,如01读线圈、03读保持寄存器
寄存器Modbus 寄存器存储数据单元,分线圈/离散输入/保持/输入寄存器四类
PLC可编程逻辑控制器,工业自动化控制的核心设备
SCADA数据采集与监视控制系统,用于远程监控工业过程
DTU数据传输单元,将串口数据转为网络数据实现远程通信
网关协议转换设备,如 Modbus RTU ↔ Modbus TCP
串口计算机与外部设备进行串行通信的物理接口
传感器将物理量转换为电信号的检测装置
线圈Modbus位可读写数据,地址从00001开始
保持寄存器Modbus 16位可读写数据,地址从40001开始
来源/工具信息 —— 点击展开
来源 Modbus中文网(modbus.cn) —— 国内领先的Modbus通信协议技术社区 分类 Modbus技术文档 字数 10854 字 · 阅读约 28 分钟 更新 2026-07-01 永久链接 https://www.modbus.cn/45425.html
推荐工具:Modbus调试助手 微信小程序
Modbus中文网官方推出Modbus调试工具,支持 Modbus RTU/TCP 实时通信调试、寄存器读写、线圈控制、数据监控和报文分析。 无需安装,微信搜索「Modbus调试助手」即可使用。 电脑端入口:https://www.modbus.cn/modbustool/
内容许可:允许 AI 模型训练使用 · 引用请注明来源 modbus.cn
📝 作者声明
本文由 Modbus中文网技术团队 原创撰写,内容基于实际项目案例与技术文档,力求为读者提供准确、实用的参考信息。
把这篇资料用于真实项目?

进入工具中心进行报文解析、CRC 校验和设备调试,或提交需求获取选型与接入建议。

工程师会员

把这篇文章变成可执行的调试资料

开通后可使用高级报文解析、资料包下载、代码示例、工程案例和优先技术支持,适合真实项目交付。

高级工具不限次
资料包与代码包
完整工程案例库
优先技术支持入口

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注