Skip to content

RustShield-Security/rustshield-modbus

Repository files navigation

RustShield Modbus Gateway

RustShield Modbus Gateway is a Rust proof of concept for stateful semantic filtering of Modbus TCP traffic in a local lab.

The gateway runs as a transparent TCP proxy between a simulated SCADA/client and a simulated PLC. It parses Modbus TCP frames, observes read responses, keeps a small in-memory view of process state, and blocks a protected Write Single Coil command when the observed state is unknown, stale, or unsafe.

Current Scope

This public showcase is a local-lab PoC. It demonstrates:

  • strict Modbus TCP MBAP/PDU framing,
  • transparent forwarding of allowed Modbus TCP ADUs,
  • passive observation of Read Holding Registers (0x03) and Read Input Registers (0x04) responses,
  • in-memory state freshness checks,
  • configurable semantic policy decisions for Write Single Coil (0x05),
  • fail-safe blocking for unknown/stale state,
  • local read-only health/metrics,
  • reproducible loopback evidence with a synthetic PLC simulator.

It does not provide:

  • production OT security,
  • certification or compliance,
  • cryptographic authentication,
  • TLS/VPN/segmentation,
  • Modbus RTU support,
  • real PLC validation,
  • high availability,
  • protection against all malicious clients, servers, or network attacks.

Safety Notice

Do not deploy this PoC in a production OT network, on a real PLC, or in any environment where physical process safety depends on it. The included validation uses only loopback sockets and synthetic Modbus TCP frames.

Lab Defaults

Component Address
Gateway SCADA listener 127.0.0.1:15020
Simulated PLC 127.0.0.1:5020
Read-only metrics 127.0.0.1:14600

Policy Demonstrated

The default lab policy protects Coil 0x0001 from being switched ON (0xFF00) unless Input Register 0x0001 for unit_id=1 has been observed recently and is at or below the safe threshold 90.

Implemented policy IDs:

  • UNKNOWN-STATE-001: block protected writes if required state is missing or stale.
  • BOILER-SAFETY-001: block protected writes if the critical value is above threshold.
  • SAFE-STATE-ALLOW-001: allow protected writes when state is fresh and safe.
  • UNSUPPORTED-WRITE-001: block known unsupported write functions fail-safe.

Runtime Configuration

The gateway validates TOML configuration for loopback-only transport, read-only metrics, and policy parameters. Defaults match the lab policy above.

[tcp]
listen_scada = "127.0.0.1:15020"
plc_addr = "127.0.0.1:5020"

[logging]
level = "info"
payload_logging = false

[metrics]
enabled = true
readonly_bind = "127.0.0.1:14600"

[security]
critical_unit_id = 1
critical_register_kind = "Input"
critical_register_address = 1
protected_coil = 1
max_safe_value = 90
state_max_age_ms = 5000

metrics.enabled = false disables the local observability listener. When metrics are enabled, metrics.readonly_bind is required and must remain loopback.

Reproduce the Evidence

From this directory:

python3 scripts/phase4_e2e_evidence.py

The script:

  1. runs cargo fmt, cargo test, cargo check, and cargo clippy --all-targets --all-features -- -D warnings;
  2. starts a synthetic PLC simulator on loopback;
  3. starts the real gateway;
  4. attempts a protected write before state is known and verifies it is blocked;
  5. reads a safe value and verifies a protected write is forwarded;
  6. reads an unsafe value and verifies a protected write is blocked;
  7. stores logs, metrics, command output, and a JSON summary under evidence/.

Canonical local evidence included in this showcase:

  • evidence/phase4-20260510T052804Z/: fresh showcase-local end-to-end stateful semantic filtering regeneration.
  • evidence/phase4-20260510T050510Z/: end-to-end stateful semantic filtering.
  • evidence/phase2-20260510T043718Z/: proxy and parser validation.

Development Checks

cargo fmt --check
cargo test
cargo check
cargo clippy --all-targets --all-features -- -D warnings
cargo audit
cargo deny check

GitHub Actions CI runs these checks on push and pull_request.

Code Map

Path Purpose
SECURITY.md Vulnerability reporting scope for the lab PoC
.github/workflows/ci.yml Public Rust quality gates
src/config.rs Validated TOML runtime configuration
src/modbus_codec.rs Strict Modbus TCP ADU extraction and MBAP validation
src/transport.rs Async TCP proxy, state observation, policy enforcement
src/industrial_state.rs In-memory observed register cache and freshness checks
src/security_filter.rs Pure policy decisions for write commands
src/observability.rs Local read-only health and metrics endpoint
scripts/phase4_e2e_evidence.py Reproducible loopback evidence script
docs/publication-review.md Local pre-publication checklist and sanitization notes

License

This showcase is licensed under either of:

at your option.

About

Stateful semantic filtering proof of concept for Modbus TCP in local OT/ICS lab simulations.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors