Many modbus devices support only one or very few clients

Overview

Modbus TCP proxy

Many modbus devices support only one or very few clients. This proxy acts as a bridge between the client and the modbus device. It can be seen as a layer 7 reverse proxy. This allows multiple clients to communicate with the same modbus device.

When multiple clients are connected, cross messages are avoided by serializing communication on a first come first served REQ/REP basis.

This project is the Rust version of the Python based modbus-proxy project.

I did it because it fitted my personal goal of exercising with the Rust programming language and it's async based tokio library.

The goal was to produce a robust, highly concurrent server with a low memory footprint.

Installation

$ cargo install modbus-proxy-rs

Running the server

First, you will need write a configuration file where you specify for each modbus device you which to control:

  • modbus connection (the modbus device url)
  • listen interface (to which url your clients should connect)

Configuration files can be written in YAML (.yml or .yaml) or TOML (.toml).

Suppose you have a PLC modbus device listening on plc1.acme.org:502 and you want your clients to connect to your machine on port 9000. A YAML configuration would look like this:

devices:
- modbus:
    url: plc1.acme.org:502     # device url (mandatory)
  listen:
    bind: 0:9000               # listening address (mandatory)

Assuming you saved this file as modbus-config.yml, start the server with:

$ modbus-proxy-rs -c ./modbus-config.yml

Now, instead of connecting your client(s) to plc1.acme.org:502 you just need to tell them to connect to *machine*:9000 (where machine is the host where modbus-proxy is running).

Note that the server is capable of handling multiple modbus devices. Here is a configuration example for 2 devices:

devices:
- modbus:
    url: plc1.acme.org:502
  listen:
    bind: 0:9000
- modbus:
    url: plc2.acme.org:502
  listen:
    bind: 0:9001

Logging

Log levels can be adjusted by setting the RUST_LOG environment variable (default is warn):

$ RUST_LOG=debug modbus-proxy-rs -c ./modbus-config.yml

Docker

This project ships with a Dockerfile which you can use as a base to launch modbus-proxy inside a docker container.

First, build the docker image with:

$ docker build -t modbus-proxy .

Assuming you have prepared a config.yml in the current directory:

devices:
- modbus:
    url: plc1.acme.org:502
  listen:
    bind: 0:502

The supplied docker image by default runs the command /modbus-proxy-rs -c /etc/modbus-proxy.yml. Therefore, running launching a container is as simple as:

docker run --init --rm -p 5020:502 -v $PWD/config.yml:/etc/modbus-proxy.yml modbus-proxy

You can supply a different configuration path (ex: /config.yml):

docker run --init --rm -p 5020:502 -v $PWD/config.yml:/config.yml modbus-proxy -c /config.yml

Now you should be able to access your modbus device through the modbus-proxy by connecting your client(s) to :5020 .

Note that for each modbus device you add in the configuration file you need to publish the corresponding bind port on the host (-p : argument).

Credits

Development Lead

Contributors

None yet. Why not be the first?

You might also like...
A high performence Socks5 proxy server with bind/reverse support implementation by Rust.

rsocx A high performence Socks5 proxy server with bind/reverse support implementation by Rust Features Async-std No unsafe code Single executable Linu

Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.
Interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust.

Cliws Lightweight interactive bind/reverse PTY shell with Windows&Linux support implementation by Rust. Features WebSocket Full pty support: VIM, SSH,

A Rust compiler plugin and support library to annotate overflow behavior

overflower This project contains a compiler plugin and supporting library to allow the programmer to annotate their code to declare how integer overfl

Lightweight p2p library. Support build robust stable connection on p2p/distributed network.

Chamomile Build a robust stable connection on p2p network features Support build a robust stable connection between two peers on the p2p network. Supp

UDP proxy with Proxy Protocol and mmproxy support
UDP proxy with Proxy Protocol and mmproxy support

udppp UDP proxy with Proxy Protocol and mmproxy support. Features Async Support Proxy Protocol V2 SOCKET preserve client IP addresses in L7 proxies(mm

Asynchronous Linux SocketCAN - Broadcast Manager support (BCM) with tokio

tokio-socketcan-bcm The Broadcast Manager protocol provides a command based configuration interface to filter and send (e.g. cyclic) CAN messages in k

A rust implementation of websock/socket proxy. Support noVNC

websockify-rs: WebSockets support for any application/server This is a rust implement of the websockify-js, which is part of the noVNC project. At the

๐Ÿš€Memory safe, blazing fast, configurable, minimal hello world written in rust(๐Ÿš€) in a few lines of code with few(1092๐Ÿš€) dependencies๐Ÿš€
๐Ÿš€Memory safe, blazing fast, configurable, minimal hello world written in rust(๐Ÿš€) in a few lines of code with few(1092๐Ÿš€) dependencies๐Ÿš€

๐Ÿš€ hello-world.rs ๐Ÿš€ ๐Ÿš€ Memory safe, blazing fast, minimal and configurable hello world project written in the rust( ๐Ÿš€ ) programming language ๐Ÿš€ ๐Ÿš€ W

Const equivalents of many [`bytemuck`] functions, and a few additional const functions.

Const equivalents of many bytemuck functions, and a few additional const functions. constmuck uses bytemuck's traits, so any type that implements thos

A super simple /sbin/init for Linux which allows running one and only one program

Summary High-performance /sbin/init program for Linux This is designed to do literally nothing but accept binaries over the network and run them as a

A minimal file exchange server designed for clients with browsers only.

XIAO-Files Xiao-Files is a minimal file exchange server designed for clients with browsers only. Example Let's say we have a host with IP 10.8.20.1, a

A framework that allows anyone to create an Urbit Chatbot with only a few lines of code.

Urbit Chatbot Framework A framework that allows anyone to create an Urbit Chatbot with only a few lines of code. The Urbit Chatbot Framework takes car

A tokio-based modbus library

tokio-modbus A tokio-based modbus library. Features pure Rust library async (non-blocking) sync (blocking) Modbus TCP Modbus RTU Client & Server Open

The Modbus IIoT Library

The Modbus IIoT Library A pure Rust library for working with Modbus in IoT/IIoT projects. It is based on the Modbus protocol specification with the fo

A very-very simple url shortener for Rust

urlshortener-rs A very simple urlshortener for Rust. This library aims to implement as much URL shortener services as possible and to provide an inter

This crate does only one thing: format a Unix timestamp.

time-format This crate does only one thing: format a Unix timestamp. Splitting a timestamp into its components The components_utc() function returns t

This library implements a type macro for a zero-sized type that is Serde deserializable only from one specific value.

Monostate This library implements a type macro for a zero-sized type that is Serde deserializable only from one specific value. [dependencies] monosta

SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.
SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.

SixtyFPS is a toolkit to efficiently develop fluid graphical user interfaces for any display: embedded devices and desktop applications. We support multiple programming languages, such as Rust, C++ or JavaScript.

Rust Library for controlling divoom devices that support REST APIs, such as pixoo-64.
Rust Library for controlling divoom devices that support REST APIs, such as pixoo-64.

Divoom Rust Library for controlling divoom devices that support REST APIs, such as pixoo-64 (and from how divoom's api/doc organizes, maybe more in th

Comments
  • License not yet defined

    License not yet defined

    First of all, congratulations on this great project. Flawlessly solves a very common problem with Modbus/TCP connections. Thanks a lot for this.

    One thing is missing: Could you please specify a license for your project?

    Not completely altruistic I would wish for a very free one ร  la MIT ;) of course it is up to you

    opened by fox2k06 0
Owner
Tiago Coutinho
Software engineer python, rust, lua, elixir&erlang
Tiago Coutinho
Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo workspace

ra-multiplex โ€ƒ Multiplex server for rust-analyzer, allows multiple LSP clients (editor windows) to share a single rust-analyzer instance per cargo wor

max 95 Dec 29, 2022
Fake rest is a fake API generator using a config file to help you develop clients.

About Fake-Rest is a fake API generator using a config file to help you develop clients. It's EASY AS HELL. Usage It's very simple to use. just create

Benyamin Eskandari 9 Feb 1, 2023
Hotwire allows you to study network traffic of a few popular protocols in a simple way

Hotwire Hotwire is a gtk GUI application that leverages the wireshark and tshark infrastructure to capture traffic and explore the contents of tcpdump

null 194 Dec 30, 2022
Tiny CLI application in rust to scan ports from a given IP and find how many are open. You can also pass the amount of threads for that scan

Port Scanner A simple multi-threaded port scanner written in Rust. Usage Run the port scanner by providing the target IP address and optional flags. $

nicolas lopes 4 Aug 29, 2023
SpringQL: Open-source stream processor for IoT devices and in-vehicle computers

What is SpringQL? SpringQL is an open-source stream processor specialized in memory efficiency. It is supposed to run on embedded systems like IoT dev

SpringQL 25 Dec 26, 2022
A copy of ziad87 "very stupid thing" (rip). Now in v2: Electric Boogaloo

IPv6-Place-v2 A re-implementation of ziad87's awesome "Place: IPv6" site. Written in Rust with Axum using Server-Sent-Events for the fun instead of WS

Server Scanning Inc. 4 Jun 6, 2023
Imagine your SSH server only listens on an IPv6 address, and where the last 6 digits are changing every 30 seconds as a TOTP code...

tosh Imagine your SSH server only listens on an IPv6 address, and where the last 6 digits are changing every 30 seconds as a TOTP code... Inspired fro

Mark Vainomaa 409 Oct 23, 2022
๐Ÿค– brwrs is a new protocol running over TCP/IP that is intended to be a suitable candidate for terminal-only servers

brwrs is a new protocol running over TCP/IP that is intended to be a suitable candidate for terminal-only servers (plain text data). That is, although it can be accessed from a browser, brwrs will not correctly interpret the browser's GET request.

daCoUSB 3 Jul 30, 2021
Listen to bluetooth headphone keys (Linux only)

What Take action when you use your bluetooth headphone to indicate pause, play, next or previous. For Linux only. Why You can bind global keys to XF86

ไพไบ‘ 8 Dec 30, 2022
wireguard tool to manage / generate configuration. Maintain one yaml configuration file to quickly build wireguard network.

wgx wireguard tool to manage / generate configuration. Maintain one yaml configuration file to quickly build wireguard network. Usage wgx --h USAGE:

yinheli 6 Nov 3, 2022