Skip to the content.

OT-Security-Lab: Integrated Industrial Control System (ICS) Security Environment

Compliance Framework License: MIT CI Compliance Gate Site Contributing Security

Category Specification
Industry Water Treatment & Filtration
Frameworks IEC 62443, MITRE ATT&CK for ICS, ISA-95 Purdue Model
Environment 4-Zone Segmented Docker Lab (L1–L4) + simulated L0
Monitoring Protocol-aware anomaly detection (Modbus/TCP, DNP3, OPC UA, S7comm)
Evidence Verified Attack Simulation Logs

Project Overview

This repository contains a full-scale, simulated industrial environment designed to demonstrate the implementation of robust security controls within an Operational Technology (OT) context. The project encompasses the entire lifecycle of an IT/OT Security Engineer’s responsibilities: from architectural design and network segmentation based on the Purdue Model, to threat modeling, detection engineering, and IEC 62443 compliance mapping.

The lab simulates a Water Treatment & Filtration Facility, facilitating a hands-on platform for validating security configurations and detection rules against realistic ICS attack vectors.


2. Architecture: The Purdue Model

The environment is segmented into logical levels according to the ISA-95 Purdue Model, ensuring strict isolation of critical control processes.

graph TD
    %% Level Definition
    subgraph L4_5 ["Level 4 & 5: Enterprise"]
        A[Attacker Simulation]
        B[Corporate Workstation]
    end

    subgraph DMZ ["Industrial DMZ"]
        JH[Jump Host / Bastion]
        RP[Reverse Proxy]
    end

    subgraph L3 ["Level 3: Operations"]
        C[Historian - InfluxDB]
        D[Engineering Workstation]
    end

    subgraph L2 ["Level 2: Supervisory"]
        E[SCADA / HMI Server]
    end

    subgraph L1 ["Level 1: Control"]
        F1[PLC-01: Intake]
        F2[PLC-02: Treatment]
        F3[PLC-03: Distribution]
    end

    subgraph L0 ["Level 0: Field Devices"]
        G[Sensors/Actuators]
    end

    %% Conduits
    B ---|VPN/HTTPS| JH
    JH ---|RDP/SSH| D
    D ---|S7/Modbus| F1
    E ---|Modbus/TCP| F1
    E ---|Modbus/TCP| F2
    E ---|Modbus/TCP| F3
    F1 ---|Process Flow| F2
    F2 ---|Process Flow| F3
    F3 ---|Hardwired| G

    %% Styling
    style DMZ fill:#fff2cc,stroke:#d6b656,stroke-width:2px
    style L1 fill:#fdb,stroke:#333,stroke-width:2px

Purdue Levels Mapping:

Note: the Industrial DMZ is implemented: a jump host/bastion (ot_bastion, SSH) and a reverse proxy (ot_reverse_proxy) publish the operator interface to the Enterprise zone, and a corporate workstation exercises the DMZ access path. The gateway enforces the DMZ conduits (C9/C10). L0 field devices are simulated by the controllers.


3. Table of Contents

  1. Architecture & Design
  2. Lab Environment
  3. Asset Inventory
  4. Threat Model & Risk Analysis
  5. Detection & Monitoring

Physics-Aware Violation Demo

* [Modbus Anomaly Detection](./detection/rules/modbus_anomaly.py)
* [**Physics-Aware Safety Monitor**](./detection/rules/process_safety_violation.py)
* [Cross-Zone Traffic Alerter](./detection/rules/cross_zone_traffic.py)
*   [Brute Force Detection](./detection/rules/ot_brute_force.py)
*   [DNP3 Telemetry & Detections](./detection/rules/dnp3_dpi.py) — real opendnp3 outstation
*   [OPC UA Telemetry & Detections](./detection/rules/opcua_dpi.py) — real asyncua server
*   [S7comm Telemetry & Detections](./detection/rules/s7comm_dpi.py) — real S7 server
*   [**Live Detection Evidence (JSON Logs)**](./detection/logs/alerts.json) — refreshed automatically by the Compliance Gate on every green run 6.  [Hardening & Compliance](./hardening/)
*   [Security Hardening Checklist](./hardening/HARDENING_CHECKLIST.md)
*   [IEC 62443 Gap Analysis](./iec62443/gap-analysis.csv) 7.  [Incident Response](./incident-response/)
*   [PLC Unauthorized Change Playbook](./incident-response/ir-playbook-unauthorised-plc-change.md) 8.  [Engineering Post-Mortem](./LESSONS_LEARNED.md)

Integrated SIEM Dashboard (Loki & Grafana)

SOC Overview Dashboard

Forensic Log Analysis (MITRE ATT&CK Mapping)

Loki Raw Logs

The images above are illustrative UI snapshots. The authoritative runtime evidence is evidence/runtime_evidence.json — machine-generated from the running lab (Loki alert counts by type, ruler rule states, Grafana datasources, historian last values) by governance/testing/capture_evidence.py. Regenerate it after make up.


4. Governance, Risk & Compliance (GRC)

To bridge the gap between technical implementation and industrial standards (Exceltic/ISA-62443 requirements), this lab includes formal documentation:


5. Scalability & Protocol Realities

The lab implements Modbus/TCP, DNP3, OPC UA and S7comm with protocol-aware detection on real endpoints. In a production rollout (e.g., Railway/Transportation):


6. Key Findings & Engineering Judgments


7. Getting Started

To spin up the entire simulated environment (OpenPLC, HMI, Historian, and Firewall):

# Clone the repository
git clone https://github.com/LiamCarPer/OT-Security-Lab.git
cd ot-security-lab

# Start the environment (firewall rules and IDS rules apply automatically)
make up

# Validate the environment: simulate attacks and assert detection
make compliance

The gateway container applies the IEC 62443 zone firewall on boot and launches all custom detection rules as persistent services (make up is sufficient; no manual docker cp/docker exec steps are required).

The OpenPLC runtimes are headless: each runs a committed program.zip under plc/programs/, built automatically by plc/build.sh from the ST sources with the STruC++ toolchain (no desktop editor required), then uploaded at boot by the EWS bootstrap service. The controllers run real IEC 61131-3 logic and serve the canonical register map over Modbus/TCP; the physics-aware detection therefore observes the live process. See plc/programs/README.md.

Run in Codespaces (one click)

No local Docker required — the whole lab runs in your browser:

  1. Open the repository → Code → Codespaces → Create codespace on main.
  2. Pick the 4-core / 8GB machine type (the stack consumes ~4.3GB RAM).
  3. Wait for the automatic build and boot (first time ~5-10 min; progress is visible in the terminal). The devcontainer forwards: Grafana :3000 · SCADA HMI :8080 (via the DMZ reverse proxy) · Bastion SSH :2222 · Alertmanager :9093. (The PLC runtime API is internal to the Control zone and reached by the EWS, so it is not host-published.)
  4. Validate the environment:
    make compliance
    

    This replays all attack simulations and asserts detection, then commits the fresh evidence back to detection/logs/alerts.json — which you can watch update live in the editor.


8. Technologies Used

8.1 CI/CD & Supply Chain


9. Known Limitations & Future Work

Current Limitations:

Future Roadmap:


10. Compliance Mapping