A lightweight "Infrastructure as Code" (IaC) tool to deploy realistic, virtualized IoT environments on a single Linux host.
It spins up lightweight QEMU/Alpine VMs that mimic real-world devices (Medical, Industrial, Home, Office), generating authentic network traffic (SIP, MQTT, CoAP, HTTPS, etc.) and identifying themselves via specific DHCP fingerprints (OUI, VCI/Option 60).
- Dynamic host architecture detection (x86_64 or ARM).
- Dynamic Device Personas: Define devices in a simple 'iot.json' file.
- Realistic Traffic Generation: Agents generate live traffic for HTTP/S, DNS, SIP, MQTT, CoAP, etc.
- DHCP Fingerprinting: Real Vendor Class Identifiers (VCI) and OUIs, perfect for testing Device Identification features in Palo Alto Firewalls.
- Syslog Integration: Relays DHCP logs to the DHCP Server log ingestor in the Palo Alto Firewall for Device Mapping.
- Lightweight: Uses Alpine Linux + QEMU (256MB RAM and 1 vCPU per device).
- OS: Ubuntu 20.04 or higher.
- Hardware: CPU with Virtualization support.
- Privileges: Root access (via 'sudo').
- Firewall: Palo Alto Firewall with a valid IoT Subscription.
Note: Tested on Ubuntu 22.04 running inside an Azure instance (Standard D8s v3 - x86_64) with 20 Qemu VMs.
- Download:
wget -O iot-lab-gen.tgz https://go.ialfaro.com/UkBtqmss- Extract the files:
tar -xzvf iot-lab-gen.tgz- Make the script executable:
cd iot-lab-gen && chmod +x setup.shRun the setup script with 'sudo'. The script will automatically install dependencies (QEMU, KVM, Bridge-Utils, Kea, Python) on the first run.
sudo ./setup.sh -s <subnet> -n <count> -j <json_file> -f <firewall_ip> [-c <cert_path>]-s : IoT Lab Subnet CIDR (e.g., 192.168.10.0/24) [Required]
-n : Total number of VMs to deploy. [Required]
-j : Path to JSON device definition file. [Required]
-f : PA Firewall Management IP to send Syslogs. [Optional]
-c : Path to Root CA cert (if decryption is enabled). [Optional]Note: If -n is higher than the number of devices in 'iot.json', the script will cycle through the list, reusing Personas but generating random unique MAC addresses for the extras.
The lab is driven by the 'iot.json' file. This file defines the "Persona" of every device.
{
"name": "Nest_Thermostat",
"mac": "18:B4:30:DD:EE:16",
"vci": "Nest/Thermostat/Gen3",
"ttl": 64,
"cadence": 60,
"protocols": ["HTTPS", "DNS"],
"user_agent": "Nest/5.6.3",
"targets": {
"DNS": ["home.nest.com", "time.google.com"],
"HTTPS": ["home.nest.com"]
}
}- mac: The specific MAC address (determines OUI).
- vci: DHCP Option 60 string (Vendor Class Identifier).
- cadence: How often (in seconds) the device generates traffic.
- protocols: List of protocols to simulate.
- targets: Dictionary of destinations (Hostnames or IPs) for each protocol.
- DNS
- NTP
- SIP
- SNMP
- HTTP
- HTTPS
- MQTT
- CoAP
- Zigbee
Deploy 10 devices on 192.168.50.0/24 using the default iot.json:
sudo ./setup.sh -s 192.168.50.0/24 -n 10 -f 192.168.30.1 -j iot.jsonAfter installation, the environment is located at '~/iot-lab-gen/':
~/iot-lab-gen/
|-- certs/ # Stored Root CA certificates
|-- gen/ # Generated handler code
|-- logs/ # Serial logs for debugging VMs
|-- vms/ # VM Disk Images (one per device)Once deployed, a helper script is generated at '/usr/local/bin/iot_lab'. Use this to control the environment.
Usage: sudo iot_lab <command> [option]
Commands:
start Start the lab environment.
stop Stop all VMs and services.
restart Restart the environment.
status Show status of VMs, Network, and DHCP.
connect <ID> Connect to VM Console (e.g., iot_lab connect 01).
log <TARGET> Tail logs. Target: 'syslog' or VM ID (e.g., 01).
clean DESTROY the lab (Delete data and configurations).
help Shows this help message.Before running this script, ensure your host machine is correctly sized. Each simulated IoT device requires 1 vCPU and 256MB of RAM if KVM (Hardware Acceleration) is enabled. If KVM is disabled, QEMU is forced to use Software Emulation (TCG), creating a massive memory overhead.
Creating more devices than your host can handle may lead to system instability, freezing, or OOM (Out of Memory) kills so be careful.
Make sure that the Palo Alto firewall is the default gateway of the Host so the simulated IoT devices can send packets through it and provide traffic signatures to enrich the Device Mappings.
The firewall needs to have a route back to the IoT simulated environment subnet so traffic outside of LAN works.
The firewall will need to have a DHCP Log Ingestion Server configured in the Management interface to get the UDP packets from the Syslog processor in the IoT Host.
If you are using SCM, you will need to configure this locally on the firewall due to SCM config limitation.
After a successful deployment, you will see the devices in the IoT portal:
Note: Make sure that the firewall is running PAN-OS 11.1 or higher so IoT Security sends mappings for IoT devices regardless of their confidence score.
MIT
