ShawnM
Hi,

I have been experimenting with OpenPLC and ScadaBR to build an industrial control system testbed for a cybersecurity research project focused on detecting anomalies with ICS protocols. I've really been enjoyed working with these products so far and happy to see there are tools available for researchers to work with ICS/SCADA/OT systems.

My lab includes a RaspberryPi running OpenPLC_v3 that has an ArduinoMEGA slave device.  The ArduinoMEGA is controlling 8 electrical relays that have LED lights attached to them (In future I will be adding voltage sensors, but I am awaiting delivery).

So far, I have got ladder logic in place that changes the on/off switch in the relays based on a timer.  This is to allow me to poll the device and see if statuses are changing, but eventually, I will reprogram it to allow remote control of the relays.  I have successfully programmed ModBus/IP to poll the status of the relays, but I have been having difficulties with DNP3 over IP.  I am wondering if anyone has had success in polling using DNP3 over IP, and what they did to get this to work?

In the OpenPLC log, I do see a connection from the ScadaBR console (192.168.1.117), but nothing else.

OpenPLC Runtime starting...
Interactive Server: Listening on port 43628
Device ArduinoMEGA is disconnected. Attempting to reconnect...
Connected to MB device ArduinoMEGA
Warning: Persistent Storage file not found
Issued start_modbus() command to start on port: 502
Server: Listening on port 502
Server: waiting for new client...
Issued start_dnp3() command to start on port: 20000
DNP3 ID manager: Starting thread (0)
DNP3 ID DNP3_Server: Listening on: 0.0.0.0:20000
Issued start_enip() command to start on port: 44818
Server: Listening on port 44818
Server: waiting for new client...
DNP3 ID DNP3_Server: Accepted connection from: 192.168.1.117
Issued stop_pstorage() command
DNP3 ID DNP3_Server: End of file
DNP3 ID DNP3_Server: Accepted connection from: 192.168.1.117
DNP3 ID DNP3_Server: End of file
DNP3 ID DNP3_Server: Accepted connection from: 192.168.1.117
DNP3 ID DNP3_Server: Accepted connection from: 192.168.1.117

In dnp3.cfg, I have tried the default settings, but have also tried changing the offsets to start at 800, as this is where the ModBus offsets started.  I am using Digital Outputs on the Arduino right now.  I've also tried changing various settings on the points within ScadaBR without much luck.

Any suggestions on how to get this to work would be greatly appreciated.

Thanks,
Quote 0 0
thiagoralves
Hi Shawn, it seems that there are some issues in the way ScadaBR implements DNP3. It is possible that the runtime also has some corners to be rounded. I haven’t tested much of the DNP3 implementation. If you can, try downloading some DNP3 master simulators to see if they can communicate with OpenPLC. If you find issues let me know. I’ll try to revisit the code on the runtime later
Quote 0 0
ShawnM
Thank you - I think I may have this working now but will need to continue to test.  I continued to play around with the dnp3.cfg file and data source settings in ScadaBR and eventually found something that appears to have worked. 

Below is my dnp3.cfg file, I marked the lines in red that seem to have had some impact in getting it to work.  The address lines were obvious, as were the offset lines.  The first digital output point was found at 800 using ModBus/IP and it looks to be the same with DNP3/IP.  The database_size seems to have been the missing setting, although I'm unsure what the appropriate setting would be.  I tried various settings (trial and error) until errors started to disappear in the catalina.out log found on the ScadaBR VM and started to notice the data point values changing from n/a to false or true within the UI.

In the ScadaBR data source, indexes for the 8 points I was trying to poll are 0-7 (there is no need to mention the 800 offset previously mentioned for dnp3.cfg) with data type being "Binary Output", Operation Mode being "Direct Operate", and Control command being "Close/Trip".



 ----------------------------------------------------------------
# Configuration file for DNP3
#-----------------------------------------------------------------

# Use this file to fill out DNP3 settings for your Open PLC
# Uncomment settings as you want them


# Link Settings
#-----------------------------------------------------------------

# local address
local_address = 10

# master address allowed
remote_address = 1

# keep alive timeout
# time (s) or MAX
keep_alive_timeout = 2


# Parameters
#-----------------------------------------------------------------

# enable unsolicited reporting if master allows it
# True or False
enable_unsolicited = True

# how long (seconds) the outstation will allow a operate
# to follow a select
# select_timeout = 10

# max control commands for a single APDU
# max_controls_per_request = 16

# maximum fragment size the outstation will recieve
# default is the max value
# max_rx_frag_size = 2048

# maximum fragment size the outstation will send if
# it needs to fragment. Default is the max falue
# max_tx_frag_size = 2048

# size of the event buffer
event_buffer_size = 10

# number of values the outstation will report at once
# AKA database size
database_size = 1008

# First data point offset for DI - required if slave device used (the address should represent 1st data point of slave device)
offset_di = 800

# First data point offset for DO - required if slave device used (the address should represent 1st data point of slave device)
offset_do = 800

# First data point offset for AI - required if slave device used (the address should represent 1st data point of slave device)
offset_ai = 800

# First data point offset for AO - required if slave device used (the address should represent 1st data point of slave device)
offset_ao = 800

#Timeout for solicited confirms
# in MS
# sol_confirm_timeout = 5000

#Timeout for unsolicited confirms (ms)
# unsol_conrfirm_timeout = 5000

#Timeout for unsolicited retries (ms)
# unsol_retry_timeout = 5000

Quote 0 0
thiagoralves
Good findings. Just a tip note, your analog offsets should be 100 not 800.
Quote 0 0
ShawnM
Thanks - I will update that.

Shawn
Quote 0 0