一、概念理解
1.PDU
PDU = Protocol Data Unit,协议数据单元,表示 某一层协议认为的"数据单位"。
例如:
对 HTTP
一个 HTTP 请求报文 = 一个 PDU
一个 HTTP 响应报文 = 一个 PDU
对 DNS(UDP)
一个 DNS 查询 = 一个 PDU
一个 DNS 响应 = 一个 PDU
对 TLS
一个 TLS Record = 一个 PDU
对 Modbus、DNP3 等 SCADA 协议
一个 Modbus ADU = 一个 PDU
PDU 在 TCP 流中的特殊点:
TCP 是流式的,没有边界,因此 PDU 边界需要由解析器自己识别,例如:
HTTP 通过 CRLF、Content-Length、chunked 等判断一个 PDU 的结束。
TLS 根据 Record Header(5 bytes)得知一个 Record 的长度,从而识别一个 PDU。
DNS over TCP 依靠前两个字节的 length prefix 决定 PDU 边界。
Suricata 的 parser 会做:stream data → reassembly → detect protocol → parse PDU。
一句话总结
PDU 是某一层协议的"完整数据单元"。
Suricata 解析器按 PDU 切片 TCP/UDP 流,并以 PDU (泛指)为单位生成 TX(事务)用于规则匹配。
**
二、Modbus ADU
**
ADU = Application Data Unit(应用数据单元),它是 Modbus 协议实际在网络上传输的完整数据单位,包含 Modbus 报文头 + PDU。
PDU(Protocol Data Unit)是 Modbus 通用的部分,格式是:Function Code + Data,全世界的 Modbus 都使用相同的 PDU。
Modbus 的三种主要传输方式:
| 传输类型 | ADU 结构 | 说明 |
|---|---|---|
| Modbus TCP | MBAP Header + PDU | 在 TCP 上,无 CRC |
| Modbus RTU | Addr + PDU + CRC | 定长 CRC |
| Modbus ASCII | Start + Addr + PDU + LRC + End | 文本编码 |
Suricata 只支持解析 Modbus TCP,不解析 Modbus RTU / Modbus ASCII,因为Modbus RTU 与 ASCII都是通过串口传输的。
Modbus TCP 的 ADU = MBAP Header + PDU。
1)MBAP Header(7 字节)
| 字段 | 长度 | 说明 |
|---|---|---|
| Transaction ID | 2 bytes | 请求/响应匹配 |
| Protocol ID | 2 bytes | 一般为 0 |
| Length | 2 bytes | 后续 PDU 的长度 |
| Unit ID | 1 byte | 设备地址(从站地址) |
2)Modbus PDU
Function Code (1 byte)
Data (N bytes)
完整例子(Modbus TCP ADU)
一个读取寄存器(Function Code = 0x03)的请求如下:
bash
00 01 # Transaction ID
00 00 # Protocol ID
00 06 # Length
01 # Unit ID
03 # Function Code
00 6B 00 03 # Data (address 0x006B, count 3)
这里整段数据 = ADU
后面那部分(03 006B 0003)就是 PDU。
Suricata 中 Modbus ADU 的意义
Suricata app-layer parser 会解析:
①MBAP Header(用于判断 PDU 长度、TX 切分)
②PDU(用于提取寄存器地址、数量、响应值等)
③每一个 ADU 都会作为一个 TX(事务) 交给规则引擎匹配
suricata以PDU为单位生成TX(事务),Modbus TCP中,ADU就相当于PDU。