SCADA sensor networks are ubiquitous in industry and notoriously difficult to secure effectively. This simulator generates network traffic in a virtual environment and allows students the opportunity to view and work with modbus traffic, the protocol used by SCADA systems. This system fully encompasses a basic SCADA network and allows 1 to N PLC devices attached to HMIs that feed into a central historian. The topology is controled by a single json configuration file, allowing for simple or complex sensor networks.
The SCADA simulator requires at least three different systems: A historian, one or more HMIs, and a PLC. Each component can run on an independent Ubuntu virtual machine.
#
Table of Contents- Check out SCADA code
- Install Dependencies
- Setup Postgres DB
- Initilize SCADA
- Local Deployment
- Historian Deployment
- HMI Deployment
- PLC Box Deployment
- Configuration file format
- Install and Configure Docker
$ git clone https://github.com/cmu-sei/scada-simulator.git
$ cd scada
$ apt-get - $ xargs apt-get-y install < os_deps.txt # Ubuntu
$ yum - $ xargs yum -y install < os_deps.txt # Centos
$ yum group install "Development Tools"
$ pip install -r requirements.txt
$ sudo -i -u postgres
$ createuser -s -W <db-username>
$ createdb --owner <db-username> <database-name>
$ exit
$ systemctl start postgresql && systemctl enable postgresql
(for help with setting up postgres the following link is a great resource https://www.digitalocean.com/community/tags/postgresql?type=tutorials)
Please see the configurations section for proper configurations json file.
$ python ./init.py --help # Help CLI arguments
$ python ./init.py -f path/to/config.json -u <db-username> -d <db-name> -w <db-password> # Local
$ python ./init.py -s -f path/to/config.json -u <db-username> -d <db-name> -w <db-password> # Distrobuted
Troubleshoot 1: Make sure if you have a distributed SCADA network that you can connect to HMIs defined in the configuration file.
Troubleshoot 2: Ensure the postgres service is on and the pg_hba.conf file allows for users to connect remotely to the defined HMIs.
**Data Server - Terminal 1** ```bash $ python ./dataserver.py --help # Help CLI arguments $ python ./dataserver.py -u -d -w ``` Open browser and go to http://localhost:5000Troubleshoot 1: Default port is port 5000 ensure that the firewall allows communication over port 5000.
**HMI Server - Terminal 2** ```bash $ python ./HMI_Server.py --help # Help CLI arguments $ python ./HMI_Server.py -p 5001 -u -d -w ``` Troubleshoot 1: Ensure that the Data Server is started and currently running.Troubleshoot 2: Ensure firewall allows communication over port 5001 local
**PLC Engine - Terminal 3** ```bash $ python ./PLC_manager.py --help # Help CLI arguments $ python ./PLC_manager.py -f path/to/config.json ``` Troubleshoot 1: Ensure that the Data Server is started and currently running.Troubleshoot 2: Ensure firewall allows communication over port 5001 local.
**Data Server - Terminal 1** ```bash $ python ./dataserver.py --help # Help CLI arguments $ python ./dataserver.py -i -p -u -d -w ``` Troubleshoot 1: Ensure that the firewall allows communication over the defined port. If the port number is low then sudo may be required. ## 7. HMI Deployment - Open two terminals and navigate to JASPR home directory. **Data Server - Terminal 1** ```bash $ python ./dataserver.py --help # Help CLI arguments $ python ./dataserver.py -i -p -u -d -w ``` Troubleshoot 1: Ensure that the firewall allows communication over the defined port. If the port number is low then sudo may be required. **7b. HMI Server - Terminal 2** ```bash $ python ./HMI_Server.py --help # Help CLI arguments $ python ./HMI_Server.py -i -p -u -d -w ``` Troubleshoot 1: Ensure that the Data Server is started and currently running.Troubleshoot 2: Ensure that the firewall allows communication over the defined port. If the port number is low then sudo may be required.
This requires docker with an image that supports pymodbus module see PLC Box configurations section, and in this section it is assumed that you have properly configured PLC Box and the docker image contains the arduino.py engine
$ python ./PLC_engine.py --help - For CLI arguments
$ python ./PLC_engine.py -H http://<host-ip>:<host-port>/api/modbus-config
- 9a. This project simulates a SCADA system that has three unique parts: Histoian, HMI, and PLC. The Historian is the central repository for all of the Human-Managment Interfaces. The Historian poles the HMIs to gather a historiacal picture of what the HMIs are seeing. The default poling interval is 30 seconds, if the poling interval should be larger or shorter then the sleep time in HMI_Server.py/historina_handler can be changed up or down. The HMIs are a real time view of the PLC devices readings. This allows users to identify real time issues associated with each individual PLC devices. The HMI unlike the Historian only maintains records of the last 1000 readings pulled from the PLC devices. Finally the PLC devices are modled off of the arduino controller archetecture. Each ardunino has its own unique IP address and allows two way communication. These modules are comprised of actuators and sensors with the actuators having direct relationship with the sesnors, meaning if a heater actuator is turned up the temperture sensor will start rising in value. The next couple of sections will walk you through how to properly configure the json configuration file in order to correctly map your SCADA System.
- 9b. Historian
- 9b.1 The required keys are: name_system, name, location, actuators, and sub_devices. The default IP address is 127.0.0.1 and listening port is 5020
- 9b.2 Sub Devices are HMIs or Controllers(PLC Device) the Historian cannot have any controller devices and must have atleaset one HMI
- 9b.3 The "Status" Actuator is required for all devices this allows users to turn on and off services that the device provides as well as all services dependant on the device ex: if the Historian is disabled then all HMIs will be disabled and all PLC devices relying on the HMI.
- 9b.4 The Historian only has one Actuator and cannot have any additional sensors or actuators.
- 9b.5 Below is an example of the Hisorian Configuration:
- 9c. HMI
- 9c.1 The required keys are: name_system, name, location, actuators, and sub_devices. The default Host and HMI IP address is 127.0.0.1 and listening port for the host is 5020 and HMI is 5021
- 9c.2 The Host IP address is the web page front end for the HMI while the HMI IP address is the interface communicating with the PLC devices
- 9c.3 The HMI only has one Actuator and cannot have any additional sensors or actuators.
- 9c.4 The HMI Identifier is a unique string that identifies the HMI. This is what will be used to bind PLC devices to the HMI and can be any unique string
To install Docker on your PLC Box follow the instructions in the following Link: https://docs.docker.com/engine/installation/, however this guide will be going over how to install on a CentOS 5 or above.
**Download and Install Docker (you must be in the scada home directory)** ```bash $ cp ./docker.repo /etc/yum.repos.d $ sudo yum update && sudo yum install docker-engine $ sudo systemctl enable docker.service $ sudo systemctl start docker.service ``` **Prepare docker image for ardunio engine** ```bash ```