How to Build a Safe OT Cybersecurity Lab: Network Design, Tools and Safety Controls

Most security testing advice assumes that the worst thing you can break is a web application. In operational technology, the worst thing you can break is a process – and processes move pumps, valves, conveyors and turbines.

That difference is why every OT walkthrough on CyberLabs starts in a lab rather than on a live plant network. This article shows you how to build that lab: an isolated, restorable environment where you can capture industrial traffic, validate segmentation, write detection rules and make mistakes without consequence.

You do not need industrial hardware to begin. A laptop with 16 GB of RAM and a hypervisor is enough for a first build. Physical switches, firewalls and controllers can be added later, once the software environment has proven itself.


1. What you will learn

By the end of this build you will have an isolated OT environment capable of supporting:

  • Passive asset discovery
  • Modbus/TCP analysis
  • Firewall and VLAN testing
  • OT network scanning experiments
  • HMI and PLC simulation
  • Windows engineering workstation testing
  • Detection-rule development
  • Packet capture and evidence collection
  • Backup and recovery exercises

Every future CyberLabs OT article will reference this lab, so it is worth building carefully once rather than improvising each time.


2. OT safety classification

Green – Controlled lab activity.

No production industrial systems are involved. All testing takes place inside an isolated virtual environment with no path to a live process, a corporate network or the internet from the OT segments.

CyberLabs classifies every OT article this way so that readers know, before they start, whether an activity is safe to reproduce in a lab, requires a maintenance window, or should never be attempted outside a test environment.


3. Why an OT lab is different

An IT penetration tester works in a world where confidentiality usually ranks first. In OT, the priority order commonly inverts: availability and safety come before confidentiality. That single change has practical consequences.

Availability is the primary control objective. A short outage on a file server is an inconvenience. The same outage on a control network can halt a batch, trip a safety system or force an unplanned shutdown with hours of restart cost behind it.

Ordinary traffic can be disruptive. Embedded controllers often run minimal TCP/IP stacks with small connection tables. Aggressive port scans, broadcast storms and rapid connection cycling have been known to hang devices that would shrug off the same traffic in an IT context. The device does not need a vulnerability to fail – it only needs to run out of resources.

A perfectly valid command can still be dangerous. Modbus/TCP has no authentication. A write to a coil is not an exploit; it is the protocol working exactly as designed. Anything that can reach TCP/502 and speak the protocol can start a pump. This is why “read-only” discipline matters more in OT than the vulnerability count.

Recovery must be planned before testing, not after. In a lab that means snapshots and exported configurations. On a real site it means agreed rollback procedures, known-good backups and someone with authority to stop the test.

Production testing requires explicit, written authorisation. Scope, timing, permitted techniques, escalation contacts and abort criteria should be agreed with operations before anything touches a live network – usually alongside a maintenance window and an operator who can revert to manual control.

The lab exists so that you can learn all of the above without a process engineer standing behind you.


4. Lab components

Everything below is free or has a usable free tier. Use the tools you already know; an unrealistically expensive lab is a lab you will never finish.

RoleSuggested software
HypervisorVMware Workstation Pro, VMware Fusion or VirtualBox
Security workstationKali Linux or Ubuntu with your usual toolset
Engineering workstationWindows 10 or 11 (evaluation image is sufficient)
Firewall / segmentationpfSense or OPNsense as a virtual appliance
PLCOpenPLC Runtime and OpenPLC Editor
HMI / SCADAScadaBR, FUXA or Rapid SCADA
Protocol simulationModbusPal, mbpoll, pymodbus or a Modbus client of your choice
Traffic analysisWireshark
DetectionZeek and/or Suricata
Log aggregation (later)FortiSIEM, Wazuh or Elastic

Resource guidance. Four VMs running simultaneously – firewall, Windows jump host, OpenPLC and HMI – will run comfortably in 16 GB of RAM if you keep the Linux VMs at 1-2 GB each and give Windows 4 GB. The monitoring VM can be started only when you need it.


5. Network segmentation

Create at least three networks. The point is not realism for its own sake – it is that segmentation is the control you will spend most of your OT career testing, so your lab needs to have some.

ZoneExample subnetPurpose
Test / IT192.168.10.0/24Security workstation, analysis tools
OT DMZ192.168.20.0/24Jump host, controlled access
OT Control192.168.30.0/24HMI, PLC and industrial services

Suggested lab architecture

              CyberLabs OT Security Lab

     +----------+-----------+
     |  Security Testing    |
     |  Kali / Ubuntu       |
     |  192.168.10.50       |
     +----------+-----------+
                |
         IT / Test Network
          192.168.10.0/24
                |
     +----------+-----------+
     |  Firewall / Router   |
     |  Segmentation Rules  |
     +----------+-----------+
                |
              OT DMZ
          192.168.20.0/24
                |
     +----------+-----------+
     |  Jump Host /         |
     |  Engineering PC      |
     |  Windows             |
     +----------+-----------+
                |
          OT Control VLAN
          192.168.30.0/24
                |
        +-------+-------+
        |               |
+-------+--------+  +---+------------+
| HMI / SCADA    |  | PLC Simulator  |
| Simulator      |  | Modbus/TCP     |
+----------------+  +----------------+

Mapped onto the Purdue reference model, the test network stands in for Level 4 (enterprise), the OT DMZ for Level 3.5, and the control VLAN for Levels 1-2. You are building a miniature version of the zone-and-conduit structure that IEC 62443 describes.

Hypervisor isolation

This is the step people get wrong, and it is the one that matters most.

  • VMware Workstation: put each OT segment on a LAN Segment, not a NAT or host-only network. LAN segments have no connectivity to the host or the physical network.
  • VirtualBox: use Internal Network adapters (intnet) for the OT DMZ and OT Control segments.
  • Give the firewall VM one adapter per zone, plus one NAT or bridged adapter only if you need internet access for updates on the test network. Turn that adapter off during testing.
  • The OT Control segment should have no default route to the internet at any point in the build.

Do not bridge the OT lab to your home or work network. A misconfigured Modbus write is harmless in an isolated segment and considerably less harmless if the segment happens to reach a real device on the same broadcast domain.

Monitoring interface

Add a second interface to your monitoring VM, attach it to the OT Control segment, and enable promiscuous mode:

  • VMware: set the virtual network to allow promiscuous mode (on Linux hosts this may require permissions on /dev/vmnet*).
  • VirtualBox: set Promiscuous Mode to Allow All on that adapter.

This is your virtual SPAN port. When you later add a physical managed switch, the same role is served by a mirrored port – the analysis workflow does not change.


6. Firewall policy

Begin with a default-deny design on every inter-zone interface. Then add only the flows the process actually needs.

SourceDestinationServiceAction
Test workstationJump hostRDP / SSH (management only)Allow
Jump hostHMIHTTP/HTTPS or approved client portAllow
HMIPLCModbus/TCP 502Allow
Test workstationPLCAnyDeny (initially)
OT ControlInternetAnyDeny
AnyAnyAnyDeny and log

Enable logging on the final deny rule. Those logs are the evidence you will use to prove – or disprove – that segmentation works, and they are the raw material for detection rules later.

Two habits worth forming now:

  1. Write the rule intent down. A firewall rule without a documented business or process justification is a rule nobody will dare remove in three years’ time.
  2. Test the deny rules, not just the allow rules. Most segmentation findings in real assessments come from paths nobody intended to create – a management VLAN with a route it should not have, a dual-homed workstation, a vendor remote-access appliance sitting quietly in the DMZ.

This section sets up a later CyberLabs article: Can the IT Network Reach the PLC? Testing OT Segmentation Safely.


7. Install the PLC simulator

Install OpenPLC Runtime on a Linux VM in the OT Control segment (192.168.30.20 in the examples below). The runtime exposes a Modbus/TCP server on port 502 and a web management interface on port 8080.

Build a small, visible process rather than manipulating anonymous registers. A tank makes a good first example because the register values mean something a reader can picture.

Suggested register map

Modbus objectOpenPLC addressMeaning
Coil 0%QX0.0Pump start/stop command (written by HMI)
Coil 1%QX0.1Pump running status
Coil 2%QX0.2High-level alarm
Holding register 0%QW0Tank level, 0-1000 (0.0-100.0 %)
Holding register 1%QW1Temperature x 10 (e.g. 215 = 21.5 degC)

In OpenPLC’s default mapping, a Modbus master can write coils (%QX) and holding registers (%QW) and read discrete inputs (%IX) and input registers (%IW). Because the HMI writes the start command to coil 0, the PLC program must never assign to %QX0.0 – it only reads it.

Illustrative Structured Text

PROGRAM main
VAR
  PumpCmd   AT %QX0.0 : BOOL;          (* command from HMI  *)
  PumpRun   AT %QX0.1 : BOOL;          (* status to HMI     *)
  HighAlarm AT %QX0.2 : BOOL;
  Level     AT %QW0   : INT := 400;    (* 40.0 %            *)
  Temp      AT %QW1   : INT := 215;    (* 21.5 degC         *)
  Tick      : TON;
END_VAR

Tick(IN := NOT Tick.Q, PT := T#500ms);

IF Tick.Q THEN
  IF PumpCmd THEN
    Level := Level + 10;               (* pump fills the tank   *)
  ELSE
    Level := Level - 5;                (* steady draw-off       *)
  END_IF;
  IF Level > 1000 THEN Level := 1000; END_IF;
  IF Level < 0    THEN Level := 0;    END_IF;
END_IF;

PumpRun   := PumpCmd;
HighAlarm := Level > 850;

END_PROGRAM

Compile it in the OpenPLC Editor, upload it to the runtime and start the PLC. Confirm operation from the command line before involving the HMI:

# Read holding registers 0 and 1 (tank level, temperature)
mbpoll -a 1 -t 4 -r 1 -c 2 192.168.30.20

# Read the three coils
mbpoll -a 1 -t 0 -r 1 -c 3 192.168.30.20

Watch the level climb and fall as you set coil 0. That single command – one write, one process change, no authentication anywhere – is the whole argument for OT segmentation in a single line of terminal output.


8. Configure the HMI

Install ScadaBR or FUXA on a VM in the OT Control segment, add the PLC as a Modbus/TCP data source, and build a small operator screen showing:

  • Tank level (bar or gauge, 0-100 %)
  • Pump state (running / stopped)
  • Alarm state (high level)
  • Start and stop controls
  • Communications status

Set the polling interval to something realistic – 500 ms to 2 seconds. The polling rate matters later: a steady, predictable poll cycle is what makes an OT baseline so much easier to profile than IT traffic, and it is what makes anomalies stand out.

Screenshots of this screen will make every future article more concrete, so it is worth spending twenty minutes making it look like an operator screen rather than a debug page.


9. Establish normal traffic

Before you attack anything, record what “normal” looks like. This is the single most valuable artefact in the lab.

Start a capture on the monitoring interface and let the lab run for at least fifteen minutes of ordinary operation – HMI polling, an operator starting and stopping the pump, an engineer logging into the jump host, a denied connection or two.

Capture on the OT Control segment:

sudo tcpdump -i eth1 -w ot-baseline-$(date +%Y%m%d).pcap

You should be able to identify:

  • ARP, and its regular background pattern
  • DNS, if present at all (in many control segments it is not)
  • Modbus/TCP sessions on port 502, and which function codes appear
  • The HMI polling cycle and its interval
  • Engineering workstation access to the jump host
  • Firewall allows and denies

Useful Wireshark display filters:

mbtcp                               # all Modbus/TCP
modbus.func_code == 3               # read holding registers
modbus.func_code in {5 6 15 16}     # writes - the ones that change the process
tcp.flags.syn == 1 && tcp.flags.ack == 0

If you have Zeek running on the monitoring interface, its Modbus analyser will produce a modbus.log recording each request with its function code – a far more practical baseline format than raw packets when you start writing detections.

Record, in writing:

  • Which devices talk to which, and on what ports
  • Which Modbus function codes are legitimate on this network
  • The expected polling interval
  • Which hosts should never originate a write

Save the clean baseline PCAP somewhere separate from the VM images. Every later article – asset discovery, unauthorised command detection, segmentation testing – compares against this file.


10. Recovery and reset

A lab you cannot restore is a lab you will be reluctant to test in, which defeats the purpose.

Snapshot every VM in a known-good state, after configuration but before any testing. Name them clearly (baseline-2026-07-28, not Snapshot 3).

Export the firewall configuration. In pfSense and OPNsense this is a single XML file. Keep it outside the VM.

Back up the PLC project – the OpenPLC Editor project file and the compiled program.

Back up the HMI project – ScadaBR and FUXA both support project export.

Record IP addresses, VLANs and credentials in one document. Use throwaway credentials in the lab and never reuse anything from a real environment.

Practise the restore. Deliberately break something, revert to the snapshot, and confirm the lab comes back cleanly. The first time you do this should not be after you have accidentally corrupted a controller image.

The same discipline scales to real work: known-good configuration backups, tested restore procedures and a documented rollback plan are what turn a risky assessment into an acceptable one.


11. Validation tests

Work through this checklist before declaring the lab finished.

  • [ ] The test workstation cannot reach the PLC directly on port 502
  • [ ] The jump host can reach only the approved services on the OT DMZ and control segments
  • [ ] The HMI can read the PLC (function codes 1, 3 succeed)
  • [ ] The HMI can issue approved control commands (function code 5 succeeds)
  • [ ] Denied connections appear in the firewall logs with source, destination and port
  • [ ] Wireshark on the monitoring interface captures OT Control traffic that is not addressed to it
  • [ ] Every VM can be restored from its snapshot
  • [ ] No OT segment has a route to the internet
  • [ ] The lab has no unintended connection to a production, home or corporate network

Verify the first item explicitly rather than assuming it:

# From the test workstation - this must fail
nc -vz 192.168.30.20 502

Then check that the attempt appears in the firewall log. A deny you cannot see in the logs is a control you cannot evidence.


12. What comes next

With the lab built, the following walkthroughs all become reproducible:

  • Passive OT asset discovery with Wireshark
  • Understanding Modbus/TCP traffic
  • Safely testing IT-to-OT segmentation
  • Detecting unauthorised Modbus commands
  • Auditing an industrial switch
  • Building an OT traffic baseline

Each will refer back to this article rather than repeating the build.


Downloads

  • OT lab build checklist
  • IP address and zone worksheet
  • Firewall validation matrix
  • Blank network diagram
  • Lab safety checklist

Could an unintended pathway exist in your OT environment?

A lab shows you what segmentation looks like when it is designed deliberately. Real environments accumulate exceptions: a vendor remote-access appliance, a dual-homed workstation, a temporary rule that outlived the project that needed it.

CyberLabs OT security assessments examine network segmentation, remote-access pathways, industrial device exposure and monitoring controls, while accounting for operational availability and recovery requirements.