i want to be sure that a ModBus client can only read holding registers from a ModBus Server.
I saw that a modbus read only firewall exists as seperate hardware and as software on a Linux Host.
Is it possible to limit the modbus protocol to read only with the mikrotik firewall? Some Layer7 filtering maybe.
I don’t think so. And until recently, it was only possible to read – so you’d been good already . But since Modbus is accessed via the CLI, and is NOT IP traffic … so it doesn’t touch the firewall.
So if someone has login access to Mikrotik, they’d be able to both read and write modbus. While the user policy does have a “read” and “write”, those apply to the configuration, not the /iot command operations. Now it’s arguable that the modbus write register could require the logged in user to have the generic “write” permission — but that ain’t how it works today.
I forgot the Mikrotik supports acting a modbus TCP gateway. If that’s the case a layer 7 rule might work if you wanted to just limit drop by a “function code” (say 6). In Mikrotik’s regex, it should be “^…\x06” since 8th byte is the function code. I can’t test this but perhaps:
Yeah, it only work on the first packet of the connection in fact . If the Modbus TCP client maintains a persistent connection, the layer-7 approach breaks. If it connects, does its business, and drops the TCP connection after it, some L7 might work. But agree it be hard to be truly effective.
The OP may want to file a feature request at help.mikrotik.com… Don’t use modbus myself, but I can see wanting to “drop”/block the common “write” functions from the TCP side of the modbus … And, since it’s Mikrotik doing the listening/sending on port 502, no need for firewall since it’s like /ip/service… it could be an option in /iot/modbus on what the Modbus TCP server accepts.
Thanks for the answers.
My Client isn´t the MikroTik Router, it is a external device.
Server and Client are in different Networks, so the MikroTik has to route the Traffic.
Here is a example. It seems to be a old Kernel Module for a Linux Host.
On the Site are example iptables commands like:
iptables -A INPUT -p tcp -m modbus --funccode 16 –allowtcp 0 -j DROP
(Drops whenever the functioni code of the received packet is 16}
And it seems like Honeywell make Modbus Read-only Firewall´s here is a datasheet.
Something like this would be awesome if it´s doable with the MikroTik.
Yeah, how well Layer7 works depend on if the remote client connects/disconnects per request. If your remote client maintains a persistent connection, L7 won’t work since it only scans the first few packets to make a decision.
Based on the “-m modbus” in:
… guess the Honeywell thing is using a kernel extension to do that, which Mikrotik does not have. It’s trivial amount of code it seems, so perhaps wouldn’t be too hard for Mikrotik to add: https://modbusfw.sourceforge.net.
Given modbus often connects to physical things that if controlled wrongly/hacked could actually be bad/dangerous it be worth considering on their part. e.g. while DoS attack are bad, commanding a downstream modbus power/water systems/etc seems worse.
ACL to allow specific Modbus device IDs and function codes (and possibly writable register ranges) would be an useful new feature of the MT Modbus TCP-to-RTU gateway. Since the Modbus over TCP protocol itself doesn’t provide any security by default, and can control devices which can do some physically dangerous things if controlled in a wrong way, it must be very carefully protected - not exposed to the Internet. There is a newer version of the protocol secured by TLS (over TCP port 802), but that’s not implemented by MT yet - https://modbus.org/docs/MB-TCP-Security-v36_2021-07-30.pdf
Yeah the threat profile is pretty radically different between serial lines and TCP… Even if it’s blocked from internet, an extra layer of protection on Modbus-TCP makes perfect sense. e.g. stuxnet did not come directly from internet.
I’d recommend you file this as a feature request at help.mikrotik.com – Mikrotik doesn’t always read all the posts.
Looks like it’s in v7.12beta, under “Security rules” in /iot/modbus/security-rules.
Didn’t test it, but seems to allow controlling the allowed function codes from an IP prefix.