Craton Shield
vs-s7comm-monitor
Siemens S7comm / S7comm-plus intrusion detection for Craton Shield (IEC 62443).
Overview
Monitors S7comm traffic for security anomalies in industrial control systems. Designed for industrial gateways and PLCs.
MSRV: 1.82 | Environment: #![no_std], zero heap allocation
Features
- Variant awareness -- classic S7comm (
0x32) and S7comm-plus (0x72) are parsed and policed as distinct dialects. A TCP connection is pinned to the first variant it presents; later frames whose variant differs are blocked as a high-severity MITM indicator. - Connection-keyed PDU-reference replay defense -- per-
connection_idsession table with an 8-slot(pdu_ref, timestamp)ring. Duplicates within the configurable replay window are blocked atHighseverity. - SF 0x29 (Security) session-type restriction -- per-rule allowlist of
session types (
PG/HMI/OP) in which theSecurityfunction group may be issued. Defaults to PG-only. - PDU-type allowlist -- restrict allowed PDU types (JobRequest, AckData, UserData)
- Function code filtering -- per-rule bitmask of allowed S7comm function codes with wildcard support
- Write protection -- block write operations (WriteVar, RequestDownload, DownloadBlock, DownloadEnded, PlcControl, Security)
- SZL filtering -- block UserData PDU type to prevent device capability enumeration
- Rate limiting -- per-function-code token bucket with LRU eviction
- PDU-reference replay defense -- alert (High severity), block the frame when the same
pdu_refis seen twice within a 5 s window on JobRequest traffic on the same connection
Layer assumptions
The monitor assumes COTP class 0 (TPKT/ISO 8073 over TCP/102), which is
the only class used by S7 communication in practice. Frames in other COTP
classes must be rejected by the parser layer before being passed to
inspect.
The PDU-reference replay defense is connection-keyed: each TCP
connection (connection_id) gets its own per-session ring of recently
observed (pdu_ref, timestamp) values. A duplicate pdu_ref observed
within the configured replay window on the same connection raises a
High-severity alert and blocks the frame. Replay across distinct
connections is not flagged, because pdu_ref is legitimately per-session.
Stack Budget
~3.5 KiB
Usage
use vs_s7comm_monitor::{
S7commMonitor, S7commFrame, S7commPduType, S7commFunction,
S7CommVariant, S7SessionType,
};
let mut monitor = S7commMonitor::new_strict();
// Allow ReadVar (raw 0x04), fc_mask = any, read-only, do not block SZL,
// max 50 req/sec.
monitor.add_rule(0x04, 0xFFFF_FFFF, true, false, 50).unwrap();
let result = monitor.inspect(&frame);
if !result.allowed {
// frame was blocked
}
License
Apache-2.0. See LICENSE.