Portable OT Labs: How Labshock’s PLF Revolutionizes Industrial Cybersecurity Training – Export, Share, and Replicate Complete SCADA Environments in Minutes + Video

Listen to this Post

Featured Image

Introduction:

Operational Technology (OT) cybersecurity labs are essential for hands-on learning, yet most remain trapped on a single machine—unshareable, non-reproducible, and prone to instability. The Portable Lab Format (PLF), introduced by Zakhar Bernhardt through Labshock, changes this by allowing practitioners to create a complete industrial environment (topology, services, real-world simulations) and export/import it in just a few clicks, shifting focus from infrastructure building to actual attack, detection, and learning.

Learning Objectives:

  • Understand the limitations of traditional OT lab setups and how PLF solves portability and reproducibility.
  • Learn to containerize and virtualize OT components (PLCs, HMIs, Modbus servers) using Docker, Vagrant, and QEMU.
  • Master export/import workflows, including backup of VM states, Docker images, and configuration-as-code for sharing entire industrial control system simulations.
  1. Creating a Portable OT Topology with Docker Compose

A PLF-ready lab starts with defining all OT components in a declarative format. Docker Compose allows you to simulate industrial services (Modbus, MQTT, OPC UA) as lightweight containers that can be exported and re-run anywhere.

Step‑by‑step guide – Build a minimal Modbus PLC simulator:
1. Install Docker Desktop (Windows/Linux) or Docker Engine (Linux).

2. Create a `docker-compose.yml` file:

version: '3.8'
services:
modbus-server:
image: oitc/modbus-server:latest
container_name: plc_sim
ports:
- "502:502"
environment:
- MODBUS_PORT=502
restart: unless-stopped
scada-gui:
image: eclipse-mosquitto:latest  or use scada-br for full HMI
ports:
- "8080:8080"

3. Launch the lab: `docker-compose up -d`

  1. Verify Modbus connectivity using `mbpoll` (Linux) or `Modbus Poll` (Windows):

– Linux: `sudo apt install mbpoll -y && mbpoll -m tcp -p 502 -a 1 -r 0 localhost`
– Windows (PowerShell as admin): `docker run –rm -it alpine/mbpoll -m tcp -p 502 -a 1 -r 0 host.docker.internal`

This environment is portable because the entire configuration is a text file. To export, simply share `docker-compose.yml` and the image list.

  1. Packaging a Full VM-Based OT Lab with Vagrant

Many OT labs require Windows-based HMIs or proprietary ICS software that cannot be containerized. Vagrant virtualizes entire machines and can package them into a single portable box.

Step‑by‑step guide – Export a VirtualBox VM as a reusable lab:
1. Install Vagrant and VirtualBox on your host (Windows/Linux/macOS).
2. Initialize a Vagrantfile for an Ubuntu OT host:

vagrant init ubuntu/focal64

3. Edit `Vagrantfile` to add a simulated PLC using Python’s pymodbus:

Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "private_network", ip: "192.168.50.10"
config.vm.provision "shell", inline: <<-SHELL
apt update && apt install -y python3-pip
pip3 install pymodbus
 run a simple Modbus TCP server on boot
echo '!/bin/bash\npython3 -m pymodbus.server --host 0.0.0.0 --port 502' > /usr/local/bin/modbus_server.sh
chmod +x /usr/local/bin/modbus_server.sh
nohup /usr/local/bin/modbus_server.sh &
SHELL
end

4. Spin up and provision: `vagrant up`

  1. Package the entire lab into a portable `.box` file:
    vagrant package --base my-ot-lab --output ot-lab-export.box
    
  2. Import on another machine: `vagrant box add ot-lab-export.box –name my-ot-lab` and `vagrant init my-ot-lab`

    This method preserves all installed software, network configurations, and device states – exactly what Labshock’s PLF achieves.

  3. Exporting and Sharing Containerized OT Services (Without Losing Data)

Docker volumes and networks are often the pain point when moving labs. Use `docker save` and `docker-compose down -v` carefully to capture persistent data.

Step‑by‑step guide – Export a running OT lab with databases:
1. List all active containers: `docker ps –format “table {{.Names}}\t{{.Image}}”`
2. Save each custom image as a `.tar` file:

docker save oitc/modbus-server:latest -o modbus-server.tar
docker save my-custom-hmi:latest -o custom-hmi.tar

3. Backup volumes (e.g., for InfluxDB time-series data):

docker run --rm -v influxdb_volume:/source -v $(pwd):/backup alpine tar czf /backup/influxdb-backup.tar.gz -C /source .

4. Transfer all `.tar` files and `docker-compose.yml` to the target machine.

5. Import and restore:

docker load -i modbus-server.tar
docker run --rm -v $(pwd):/backup -v influxdb_volume:/target alpine tar xzf /backup/influxdb-backup.tar.gz -C /target
docker-compose up -d

For Windows, replace `$(pwd)` with `%cd%` in PowerShell or use Get-Location.

  1. Simulating Real Attacks and Detection in the Portable Lab

Once your OT lab is portable, you can focus on offensive security and monitoring. The same exported environment can be used for red‑team exercises or blue‑team detections.

Step‑by‑step guide – Attack a Modbus PLC using Metasploit:
1. Ensure the target PLC container or VM is reachable (same Docker network or bridged adapter).
2. In the attacker container (or a separate Kali VM), start Metasploit:

msfconsole
use auxiliary/scanner/scada/modbusclient
set RHOSTS <PLC_IP>
set ACTION READ_HOLDING_REGISTERS
run

3. For a Denial-of-Service test, use `auxiliary/dos/scada/modbus_dos` (requires custom module).
4. Detection setup – Deploy Snort on the OT network:

 Inside the OT host (Ubuntu)
sudo apt install snort -y
sudo snort -A console -q -c /etc/snort/snort.conf -i eth1

5. Write a custom rule for abnormal Modbus function codes:

alert tcp $HOME_NET 502 -> any any (msg:"Modbus Write Single Coil detected"; content:"|05|"; depth:1; sid:1000001;)

6. Re-run the exploit and observe alerts.

Because the lab is portable, this entire attack/detection scenario can be zipped, sent to a colleague, and reproduced exactly.

5. Cloud Hardening for Shared OT Labs (AWS/Azure)

When distributing PLF-based labs to remote teams, you must harden the environment to prevent accidental exposure or abuse. Use Infrastructure as Code (IaC) to enforce security boundaries.

Step‑by‑step guide – Deploy a hardened OT lab on AWS:
1. Export your lab as a Vagrant box and convert it to an AMI using `vagrant-aws` plugin or Packer.
2. Write a Terraform configuration to launch the lab inside an isolated VPC:

resource "aws_security_group" "ot_lab_sg" {
name = "ot_lab_sg"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["YOUR_IP/32"]  restrict SSH
}
ingress {
from_port = 502
to_port = 502
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]  only internal
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}

3. Enable VPC Flow Logs for network visibility and encrypt EBS volumes.
4. Share the AMI and Terraform code with team members; each deploy gets an identical, isolated lab.

For Azure, use similar NSG rules and Azure Policy to enforce encryption and disable public RDP.

6. Automating Reproducibility with Ansible

To truly embrace PLF, store your lab as code. Ansible playbooks can rebuild the entire OT environment from scratch on any Linux host.

Step‑by‑step guide – Write an Ansible playbook for a SCADA lab:

1. Create `inventory.ini`:

[bash]
plc ansible_host=192.168.50.10
hmi ansible_host=192.168.50.11

2. Playbook `ot-lab.yml`:

- hosts: plc
tasks:
- name: Install Modbus simulator
apt:
name: python3-pymodbus
state: present
- name: Start Modbus server on boot
systemd:
name: modbus-server
enabled: yes
state: started
- hosts: hmi
tasks:
- name: Deploy Scada-LTS web interface
docker_container:
name: scada-lts
image: scadalts/scadalts:latest
ports: "8080:8080"

3. Run the playbook: `ansible-playbook -i inventory.ini ot-lab.yml`

  1. Version control the playbook, inventory, and any required files in Git.
  2. Any user can clone the repo and run the same command to get an identical OT lab. This is the ultimate PLF implementation.

7. Troubleshooting Common Portability Issues

Even with PLF, you may encounter network mismatches or permission errors when moving labs between hosts.

Step‑by‑step guide – Fix the top three portability problems:
1. Network interface name changes (from `eth0` to ens192):
– Linux: Edit `/etc/netplan/00-installer-config.yaml` to use `match: {name: en}` instead of a fixed name.
– Windows WSL2: Use `localhost` or `host.docker.internal` for cross‑host communication.

2. Docker permission denied:

  • Ensure user is in the `docker` group: `sudo usermod -aG docker $USER && newgrp docker`
    – On Windows, enable “Expose daemon on tcp://localhost:2375” (only for trusted networks).
  1. Vagrant packaging fails due to large disk size:

– Clean temporary files inside the VM before packaging:

vagrant ssh -c "sudo apt clean && sudo dd if=/dev/zero of=/EMPTY bs=1M || true; sudo rm -f /EMPTY"
vagrant package --base my-ot-lab --output clean-lab.box

What Undercode Say:

  • Portability is not a luxury – it’s a prerequisite for scaling OT cybersecurity training. Without the ability to export and replicate labs, each practitioner wastes 70% of their time rebuilding infrastructure instead of learning attack and defense.
  • Labshock’s PLF philosophy aligns with “everything as code” – Docker, Vagrant, and Ansible can achieve the same result today. The key innovation is standardizing the export/import workflow so that a lab becomes a first‑class artifact, not a forgotten VM snapshot.

Prediction: Within three years, most OT security training providers will adopt a portable lab format (likely based on OCI images and VM manifests) integrated with CI/CD pipelines. This will enable continuous security validation – every time a new exploit is discovered, the portable lab can be automatically updated, redeployed, and tested across hundreds of machines, dramatically accelerating the detection and mitigation of industrial cyber threats.

▶️ Related Video (68% Match):

🎯Let’s Practice For Free:

IT/Security Reporter URL:

Reported By: Ndeye Adama – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow UndercodeTesting & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin | 🦋BlueSky