DST-NAT for multiple wan addresses

@chaosinc; And since there is no internet connection where you would normally use the term ‘WAN’, I suggest using ‘PLC LAN’ and ‘Management LAN’ to describe the different subnets.

As @lurker888 pointed out, create a simple but complete network topology that includes IP addresses for all subnets and all endpoints. This should include the laptop, both interfaces on the MikroTik and TP-Link, as well as the PLC.

Thank you all, I will prepare a complete topology. The laptop at the moment is just a “replacement PLC” because I know it is a device that accepts RDP connections and i have 100% control over it. But this likely introduced more confusion, so the complete topology is definitely the way to go.

I apologize if text-based topology is common on this forum, I can edit the post if so.
We can ignore the openvpn stuff for programming use, because that simply works perfectly. If I want to program a PLC/HMI, I openvpn to Mikrotik, then I am in machine subnet and everything works great.
We can ignore any TPlinks I mentioned previously, those were just “instead-of-PLC” placeholders, so I can test this on bench before going to production.

What I ultimately want to achieve is to have NodeRED running on the Desktop in MGMT LAN. This will contact 10.0.80.201 which is at Mikrotik hex, which should translate it to 192.168.250.1 in PLC LAN, so NodeRED talks to the PLC.

Since I wanted to be absolutely sure I am not having PLC/HMI issues, I have used another laptop, called RDP test laptop on topology. Gave it static 192.168.250.99/24.
If RDP test laptop has gateway set to Mikrotik at 192.168.250.51, RDP from Desktop to 10.0.80.203 does work.
If RDP test laptop has no gateway set up, RDP from Desktop to 10.0.80.203 does not work.

This is my current configuration. 1 DSTNAT and 2 SRCNAT, just to try to make the RDP test laptop connection work. I have fully opened firewall until I am sure things work as I want.

/interface bridge
add admin-mac=____________ arp=proxy-arp auto-mac=no comment=defconf name=bridge port-cost-mode=short
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface lte apn
set [ find default=yes ] ip-type=ipv4 use-network-apn=no
/ip pool
add name=ovpn-pool ranges=192.168.250.200-192.168.250.220
/ip smb users
set [ find default=yes ] disabled=yes
/ppp profile
add local-address=192.168.250.199 name=ovpn remote-address=ovpn-pool
add bridge=bridge dns-server=192.168.250.51 local-address=192.168.250.51 name=VPN-Profile remote-address=ovpn-pool use-encryption=yes
/routing bgp template
set default disabled=no output.network=bgp-networks
/routing ospf instance
add disabled=no name=default-v2
/routing ospf area
add disabled=yes instance=default-v2 name=backbone-v2
/interface bridge port
add bridge=bridge comment=defconf ingress-filtering=no interface=ether2 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether3 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether4 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether5 internal-path-cost=10 path-cost=10
/ip firewall connection tracking
set enabled=yes udp-timeout=10s
/ip neighbor discovery-settings
set discover-interface-list=LAN
/ipv6 settings
set disable-ipv6=yes max-neighbor-entries=8192
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
/interface ovpn-server server
add auth=sha1 certificate=server-cert cipher=aes256-cbc default-profile=VPN-Profile disabled=no mac-address=_______________ name=ovpn-server1 require-client-certificate=yes
/ip address
add address=192.168.250.51/24 comment=defconf interface=bridge network=192.168.250.0
add address=10.0.80.200/24 comment="wan primary ip" interface=ether1 network=10.0.80.0
add address=10.0.80.201/24 interface=ether1 network=10.0.80.0
add address=10.0.80.202/24 interface=ether1 network=10.0.80.0
add address=10.0.80.203/24 interface=ether1 network=10.0.80.0
/ip dhcp-server
add address-pool=ovpn-pool interface=bridge lease-time=10m name=defconf
/ip dhcp-server network
add address=192.168.88.0/24 comment=defconf gateway=192.168.88.1
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=192.168.250.51 comment=defconf name=router.lan type=A
/ip firewall filter
add action=accept chain=input
add action=accept chain=forward
add action=accept chain=input dst-port=1194 protocol=udp
add action=accept chain=input dst-port=1194 log=yes protocol=tcp
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" log-prefix=icmp protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" disabled=yes in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related hw-offload=yes
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new in-interface-list=WAN
/ip firewall nat
add action=dst-nat chain=dstnat dst-address=10.0.80.203 log=yes to-addresses=192.168.250.99
add action=src-nat chain=srcnat log=yes out-interface=ether1 src-address=192.168.250.99 to-addresses=10.0.80.203
add action=src-nat chain=srcnat out-interface=bridge src-address=10.0.80.0/24 to-addresses=192.168.250.51
/ip ipsec profile
set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5
/ip route
add disabled=no dst-address=0.0.0.0/0 gateway=10.0.80.1
/ip smb shares
set [ find default=yes ] directory=/flash/pub
/ppp secret
add name=client1 profile=ovpn
add name=maintenance profile=VPN-Profile service=ovpn
/routing bfd configuration
add disabled=no interfaces=all min-rx=200ms min-tx=200ms multiplier=5
/system clock
set time-zone-name=Europe/Belgrade
/system identity
set name=RouterOS
/system note
set show-at-login=no
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

@chaosinc; Much better! Just a few quick follow-up questions and suggestions to make the diagram easier to follow:

Which VLANs are the different subnets actually connected to?

To make the diagram clearer, I’d suggest labeling each subnet with its corresponding VLAN ID right where it applies. For example, put “VLAN10 – 10.0.10.0/24” near the MGMT LAN and “VLAN80 – 10.0.80.0/24” near the PLC LAN or the MikroTik interfaces, depending on where they belong. (and so on)

A few other small things that could make the diagram even easier to follow:

  • Show which VLANs are trunked through the Cisco switch, and which ports are access or trunk.
  • Add labels like “VPN Server” and “VPN Client” next to the devices playing those roles.
  • Keep the IP formatting consistent (try not to mix notations like slashes and full address ranges unless it adds clarity).
  • You could also add arrows or simple notes showing NAT translations, for example between 10.0.80.203 and 192.168.250.99, to help visualize the flow.

Which still seems to me like another subset of the same, in any case the solution there was the same dst-nat (or netmap) + mangle rules to mark packets depending on ports connected, in the case of one “island” with different IP’s there is no need of the mangle.
Multiple islands, each with different IP connected machines won’t need 'em either, since once the LAN is translated to WAN (hopefully not to a conflicting address) there won’t be any duplication.

In that thread masquerade is used instead of src-nat, but that should be irrelevant.

I believe this might illustrate situation better.
I dropped the VLAN indications and actually for all testing I have desktop directly in 10.0.80.X, so everything happens in 10.0.80.0/24 subnet of Main Cisco router.
Added desired NAT translations near Mikrotik.
All subnets in all devices are always 255.255.255.0, so I have also dropped the inconsistent /24

Your diagram is still incomplete/incorrect.

My notes:

  • You say that you want addresses 10.0.80.200-203 (4 addresses) on the ether1 side. I will assume:
  • You want to use one for managing the your Mikrotik router. Let’s assume that’s 10.0.80.200. This we will have as a /24 address.
  • You want to use 10.0.80.201-203 to access 192.168.250.1,100,99 respectively. These addresses will be /32 addresses. (It’s just better this way, trust me)
  • I’m a bit stumped that the PLC would have the 192.168.250.1 address by default. Usually the gateway has either the .1 or .254 address (usually English speaking countries use .1 and German speaking ones user .254, just for fun :slight_smile: ), but no one usually assumes that the PLC will be the GW. This is of no consequence really, and .51 is as good as any other. But this makes me question whether this is really a default configuration or someone just has some idea…

There is nothing special in this and is easily accomplished with the following:

### Addresses
/ip/address
# Management address
add interface=ether1 address=10.0.80.200/24

# Addresses that we will dst-nat
add interface=ether1 address=10.0.80.201/32
add interface=ether1 address=10.0.80.202/32
add interface=ether1 address=10.0.80.203/32

# Address on the device network side
add interface=ether2 address=192.168.250.51/24

### NAT
/ip/firewall/nat
# dst-nat for forwarding
add chain=dstnat dst-address=10.0.80.201 action=dst-nat to-addresses=192.168.250.1
add chain=dstnat dst-address=10.0.80.202 action=dst-nat to-addresses=192.168.250.100
add chain=dstnat dst-address=10.0.80.203 action=dst-nat to-addresses=192.168.250.99

# src-nat for devices not being aware of the gateway
add chain=srcnat out-interface=ether2 action=src-nat to-addresses=192.168.250.51

That’s all there is to it.

Many (all?) Omron plcs actually use 192.168.250.1 as default IP, example:
https://www.myomron.com/index.php?article=1212&action=kb

Which prompts the question about which gateway Is commonly used in Japan?

No, that’s just for the CS-series (EIP2 and EIP21S). Most Omron PLCs with built-in TCP/IP support use DHCP nowadays. Gateways, Modbus adapters, and Sysmac controllers require manual configuration using Sysmac Studio or CX-Programmer via USB.

Again, the culture around PLCs, networks and their users is really messed up somehow. An especially common one is that they assume that masquerading on every interface of a router is normal, e.g. even when no nat is done but two subnets are involved and the PLC is being accessed from a different one, they refuse to set up a default gateway, because for some old tp-link router it worked, and probably the new router is faulty.

EDIT: and yep, the ones I’ve seen default to DHCP.

Yeah, it’s unfortunately more common than you might think, especially at small and mid-sized facilities designed by “old-school PLC guys” who lack basic networking knowledge.

Not disagreeing with you. However what really surprised me is that I used to work with a bunch of young and very talented guys, who actually did have basic networking knowledge, and I’ve seen them set up basic networking totally correctly. Even when they had questions, they made sense. But as soon as the PLCs came out, it was as if they had suddenly forgotten about what they were doing a mere hour ago, and set up the PLCs according to some 20 year old “set up your PLC in 12 easy steps” guide written by someone who had no networking knowledge whatsoever. That’s what I couldn’t understand and to this I actually don’t.

Thank you all very much for your time, problem is solved by application of DST and SRC nat rules as suggested by lurker888’s last post with modification from ether2 to bridge, plus enabling proxy-arp on bridge (ether2-5).

NodeRED running on desktop can access the PLC in Mikrotik Machine LAN, via 10.0.80.201 (NAT to 192.168.250.1).
NodeRED OMRON FINS settings need to be according to Machine LAN. Important part being DA1 = last octet of IP address of PLC (in this case .1, not .201) and SA1 = last octet of who is asking (here .51, since as far as PLC is concerned, packets come from Mikrotik directly)

{
  "host": "10.0.80.201",
  "port": 9600,
  "protocol": "udp",
  "DNA": 0,
  "DA1": 1,
  "DA2": 0,
  "SNA": 0,
  "SA1": 51,
  "SA2": 0
}

After this, Read request from A642, length 2 (= read two analogue inputs of the PLC) works perfectly, as seen in bottom right of this image.

For OMRON PLC CP1L-E it is NOT possible to set a gateway. Now I do not need it anymore, but in case someone is searching for this, the OMRON suggested workaround is to use “IP router table” in Ethernet settings and add 0.0.0.0 → IP_OF_ROUTER/GATEWAY there.
I am happy here, since internal PLC settings stay at 192.168.250.1, but I am able to set CX-Programmer to talk to PLC at 10.0.80.201, so basic of networking are working at least. Not so lucky with some Chinese PLCs and HMIs which I sadly have in production too. But that is OK, since I can always use OVPN for programming needs.

My full router config attached:

[admin@RouterOS] > export 
# 2025-04-19 17:23:37 by RouterOS 7.18.2
# software id = 1E6V-AUYV
#
# model = RB750Gr3
# serial number = ************
/interface bridge
add arp=proxy-arp name=bridge port-cost-mode=short
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/interface lte apn
set [ find default=yes ] ip-type=ipv4 use-network-apn=no
/ip pool
add name=ovpn-pool ranges=192.168.250.200-192.168.250.220
/ip smb users
set [ find default=yes ] disabled=yes
/ppp profile
add bridge=bridge dns-server=192.168.250.51 local-address=192.168.250.51 name=VPN-Profile remote-address=ovpn-pool use-encryption=yes
/routing bgp template
set default disabled=no output.network=bgp-networks
/routing ospf instance
add disabled=no name=default-v2
/routing ospf area
add disabled=yes instance=default-v2 name=backbone-v2
/interface bridge port
add bridge=bridge comment=defconf ingress-filtering=no interface=ether2 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether3 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether4 internal-path-cost=10 path-cost=10
add bridge=bridge comment=defconf ingress-filtering=no interface=ether5 internal-path-cost=10 path-cost=10
/ip firewall connection tracking
set enabled=yes udp-timeout=10s
/ip neighbor discovery-settings
set discover-interface-list=LAN
/ipv6 settings
set disable-ipv6=yes max-neighbor-entries=8192
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
/interface ovpn-server server
add auth=sha1 certificate=server-cert cipher=aes256-cbc default-profile=VPN-Profile disabled=no mac-address=************ name=ovpn-server1 require-client-certificate=yes
/ip address
add address=192.168.250.51/24 interface=ether2 network=192.168.250.0
add address=10.0.80.200/24 interface=ether1 network=10.0.80.0
add address=10.0.80.201 interface=ether1 network=10.0.80.201
add address=10.0.80.202 interface=ether1 network=10.0.80.202
add address=10.0.80.203 interface=ether1 network=10.0.80.203
/ip dhcp-server
add address-pool=ovpn-pool interface=bridge lease-time=10m name=defconf
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=192.168.250.51 comment=defconf name=router.lan type=A
/ip firewall filter
add action=accept chain=input disabled=yes
add action=accept chain=forward disabled=yes
add action=accept chain=input dst-port=1194 protocol=udp
add action=accept chain=input dst-port=1194 log=yes protocol=tcp
add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="defconf: accept ICMP" log-prefix=icmp protocol=icmp
add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" disabled=yes in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related hw-offload=yes
add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new in-interface-list=WAN
/ip firewall nat
add action=dst-nat chain=dstnat dst-address=10.0.80.201 to-addresses=192.168.250.1
add action=dst-nat chain=dstnat dst-address=10.0.80.202 to-addresses=192.168.250.100
add action=dst-nat chain=dstnat dst-address=10.0.80.203 to-addresses=192.168.250.99
add action=src-nat chain=srcnat out-interface=bridge to-addresses=192.168.250.51
/ip ipsec profile
set [ find default=yes ] dpd-interval=2m dpd-maximum-failures=5
/ip route
add disabled=no dst-address=0.0.0.0/0 gateway=10.0.80.1
/ip smb shares
set [ find default=yes ] directory=/flash/pub
/ppp secret
add name=maintenance profile=VPN-Profile service=ovpn
/routing bfd configuration
add disabled=no interfaces=all min-rx=200ms min-tx=200ms multiplier=5
/system clock
set time-zone-name=Europe/Belgrade
/system identity
set name=RouterOS
/system note
set show-at-login=no
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

Glad it works.

You shouldn’t use proxy-arp btw. You only need it because the address is on ether2 instead of the bridge. When an interface is part of a bridge, all IP related configuration should be done on the bridge.

So you could just add this rule without spending time for preparing network diagram :smiley:

Maybe it was a bit confusing with mentioning the “etherX” and potentially interface lists :slight_smile:

Have in back of your head that in the future use the Mikrotiks (192.168.250.51) as a NTP server for PLC’s and HMI’s or for sending e-mail notifications about network state of PLC’s and HMI’s - of course if such needs arise. And you should be good :smiley: