Community discussions

MikroTik App
 
juwalter
just joined
Topic Author
Posts: 11
Joined: Mon Mar 24, 2025 5:11 pm

Quick Guide: Bidirectional 1:1 NAT (SNAT, DNAT) Setup w/ working example

Fri Apr 04, 2025 3:36 am

Intro
Setting up bidirectional 1:1 NAT in RouterOS allows you to create static mappings between external and internal IP addresses. This configuration is useful when you need multiple internal (LAN) devices to be accessible via specific external (WAN) IPs. There is a special twist though, since in this particular setup all internal devices are using the same IP address (this was a mandatory requirements since we were not able to change the IP addresses on any of those devices).
This quick guide covers the essential RouterOS commands needed to properly configure dst-nat and src-nat rules for complete bidirectional communication. With these settings, traffic to your designated external IPs will be properly forwarded to the corresponding internal devices, and those internal devices will appear to use their mapped external IPs when connecting outbound.

Note: All credit goes to helpful and friendly forum user lurker888 located at: memberlist.php?mode=viewprofile&u=213255 - thank you again fren for taking the time and patience the explain everything to me!!
If anyone wants to follow along on how this setup has been created step-by-step you can find the original forum post here: viewtopic.php?t=215744

We are currently using this setup for communicating with 12x PLC (all with somewhat hard-coded, identical IP addresses) for IIoT / data acquisition.
Here is an overview image:

2025-04-04-NAT-Router.png
While IP addresses 192.168.2.20 were a given, we have chosen 192.168.2.180 and 172.29.10.0/24 addresses arbitrarily.

Requirements

The starting point for all this was really only the fact that each PLC has somewhat "hard-coded" IP address 192.168.2.20; with that, we could not use a switch but had to implement 1:1 NAT. Added benefit that PLC networks are separated from each other and we can also implement a firewall between external/internal traffic. For consistency reasons we also decided to use the same "gateway" address 192.168.2.180 on each etherN (N>1, since ether1 = WAN/external) which at first made things a bit more complicated (each PLC wanted to ping 192.168.2.180, but solved).

Configuration step-by-step

Interface Organization
We start with organising the interfaces. While WAN is not really used later in the configuration, I think it is still useful and consistent to have.

# Create interface lists for better management
/interface list
add name=PLC-PORTS
add name=WAN

# Add interfaces to lists
/interface list member
add interface=ether1 list=WAN
add interface=ether2 list=PLC-PORTS
add interface=ether3 list=PLC-PORTS
add interface=ether4 list=PLC-PORTS

IP Configuration
We will configure the IP addresses for the WAN interface and the PLC interfaces. The WAN interface will have a primary IP address, and each PLC will have a virtual IP address on the same subnet. The PLC interfaces will be configured with the same internal IP address.

Notes:
- Initially I had the idea of using /32 subnet mask for the PLCs because we are only dealing and need to connect to this one IP address, but lurker88 recommended against that, so we are using /24 instead.
- Having same IP address 192.168.2.180 on each ether1/ether2/... interface is not a problem, since they are not routed in the main routing table but instead in their specific routing table. This is accomplished by policy-routing (see next section).

# WAN interface (Edge device connection)
/ip address
add address=172.29.10.1/24 interface=ether1 comment="Edge Network Primary IP"
# Add virtual IPs for each PLC on the WAN interface
add address=172.29.10.102/24 interface=ether1 comment="PLC1 External IP"
add address=172.29.10.103/24 interface=ether1 comment="PLC2 External IP"
add address=172.29.10.104/24 interface=ether1 comment="PLC3 External IP"
# Configure IP addresses for each PLC interface - directly using Ethernet ports
add address=192.168.2.180/24 interface=ether2 comment="PLC1 Network"
add address=192.168.2.180/24 interface=ether3 comment="PLC2 Network"
add address=192.168.2.180/24 interface=ether4 comment="PLC3 Network"

Routing Tables

A separate routing table for each PLC is needed; this allows us to route traffic to the correct PLC based on the destination IP address.

/routing table
add disabled=no fib name=to-plc1
add disabled=no fib name=to-plc2
add disabled=no fib name=to-plc3

/routing rule
add action=lookup-only-in-table routing-mark=to-plc1 table=to-plc1
add action=lookup-only-in-table routing-mark=to-plc2 table=to-plc2
add action=lookup-only-in-table routing-mark=to-plc3 table=to-plc3

Connection Marking for Policy Routing

Here are two versions, first one works, but will not allow ping back from the PLCs to the router. The second one is a bit more complicated, but allows ping back from the PLCs to the router.

first one is missing connection and routing marks on traffic coming from the PLCs to the router. This is not a problem for most applications, but if you need to ping the router from the PLCs, you will need to add connection and routing marks.

/ip firewall mangle
# Mark inbound traffic from WAN to PLCs with routing marks directly
add chain=prerouting in-interface=ether1 dst-address=172.29.10.102 action=mark-routing new-routing-mark=to-plc1 comment="Mark route to PLC1"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.103 action=mark-routing new-routing-mark=to-plc2 comment="Mark route to PLC3"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.104 action=mark-routing new-routing-mark=to-plc3 comment="Mark route to PLC2"

second one has connection and routing marks on traffic coming from the PLCs to the router.

/ip firewall mangle
# Mark inbound traffic from WAN to PLCs with routing marks directly
add chain=prerouting in-interface=ether1 dst-address=172.29.10.102 action=mark-routing new-routing-mark=to-plc1 comment="Route to PLC1"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.103 action=mark-routing new-routing-mark=to-plc2 comment="Route to PLC2"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.104 action=mark-routing new-routing-mark=to-plc3 comment="Route to PLC3"

# Mark connections based on initiator
add chain=prerouting connection-mark=no-mark in-interface=ether1 action=mark-connection new-connection-mark=from-mgmt comment="Mark connection from MGMT side"
add chain=prerouting connection-mark=no-mark in-interface=ether2 action=mark-connection new-connection-mark=from-plc1 comment="Mark connection from PLC1"
add chain=prerouting connection-mark=no-mark in-interface=ether3 action=mark-connection new-connection-mark=from-plc2 comment="Mark connection from PLC2"
add chain=prerouting connection-mark=no-mark in-interface=ether4 action=mark-connection new-connection-mark=from-plc3 comment="Mark connection from PLC3"

# Route return traffic from router to PLCs (where connection-mark=from-plc)
add chain=output connection-mark=from-plc1 action=mark-routing new-routing-mark=to-plc1 comment="Route to PLC1"
add chain=output connection-mark=from-plc2 action=mark-routing new-routing-mark=to-plc2 comment="Route to PLC2"
add chain=output connection-mark=from-plc3 action=mark-routing new-routing-mark=to-plc3 comment="Route to PLC3"

Policy-Based Routing Rules

The routing rules are used to direct traffic based on the connection marks set in the previous step. Each PLC will have its own routing table, and the rules will ensure that traffic is routed correctly.

Note: Policy routes for the entire PLC subnet (/24), not just the PLC (/32)

/ip route
add dst-address=192.168.2.0/24 gateway=ether2 routing-table=to-plc1 comment="Route to PLC1"
add dst-address=192.168.2.0/24 gateway=ether3 routing-table=to-plc2 comment="Route to PLC2"
add dst-address=192.168.2.0/24 gateway=ether4 routing-table=to-plc3 comment="Route to PLC3"

NAT Configuration

Finally, this is where the magic happens. The NAT rules are used to translate the IP addresses between the external and internal networks. The destination NAT rules will forward traffic from the external IPs to the internal PLCs, and the source NAT rule (applies to all interfaces in list PLC-PORTS) will ensure that replies from the PLCs appear to come from the external IPs.

# Destination NAT
/ip firewall nat
add chain=dstnat in-interface=ether1 dst-address=172.29.10.102 action=dst-nat to-addresses=192.168.2.20 comment="PLC1 Inbound"
add chain=dstnat in-interface=ether1 dst-address=172.29.10.103 action=dst-nat to-addresses=192.168.2.20 comment="PLC2 Inbound"
add chain=dstnat in-interface=ether1 dst-address=172.29.10.104 action=dst-nat to-addresses=192.168.2.20 comment="PLC3 Inbound"

# Source NAT for replies (makes router appear as 192.168.2.180 to PLCs)
add chain=srcnat out-interface-list=PLC-PORTS action=src-nat to-addresses=192.168.2.180 comment="Source NAT to PLCs"

# might be default but just in case
/ip firewall connection tracking set enabled=yes

Final configuration

Here is the final configuration:

## /export
## /export verbose
## /system reboot
## /system reset-configuration

# Identity for better management
/system identity set name="PLC-Gateway"

#######################################
# Interface Organization
#######################################

# Create interface lists for better management
/interface list
add name=PLC-PORTS
add name=WAN

# Add interfaces to lists
/interface list member
add interface=ether1 list=WAN
add interface=ether2 list=PLC-PORTS
add interface=ether3 list=PLC-PORTS
add interface=ether4 list=PLC-PORTS

#######################################
# IP Configuration
#######################################

# WAN interface (Edge device connection)
/ip address
add address=172.29.10.1/24 interface=ether1 comment="Edge Network Primary IP"
# Add virtual IPs for each PLC on the WAN interface
add address=172.29.10.102/24 interface=ether1 comment="PLC1 External IP"
add address=172.29.10.103/24 interface=ether1 comment="PLC2 External IP"
add address=172.29.10.104/24 interface=ether1 comment="PLC3 External IP"
# Configure IP addresses for each PLC interface - directly using Ethernet ports
add address=192.168.2.180/24 interface=ether2 comment="PLC1 Network"
add address=192.168.2.180/24 interface=ether3 comment="PLC2 Network"
add address=192.168.2.180/24 interface=ether4 comment="PLC3 Network"

#######################################
# Create Routing Tables
#######################################

/routing table
add disabled=no fib name=to-plc1
add disabled=no fib name=to-plc2
add disabled=no fib name=to-plc3

#######################################
# Create Routing Rules
#######################################

/routing rule
add action=lookup-only-in-table routing-mark=to-plc1 table=to-plc1
add action=lookup-only-in-table routing-mark=to-plc2 table=to-plc2
add action=lookup-only-in-table routing-mark=to-plc3 table=to-plc3

#######################################
# Connection Marking for Policy Routing
#######################################

/ip firewall mangle
# Mark inbound traffic from WAN to PLCs with routing marks directly
add chain=prerouting in-interface=ether1 dst-address=172.29.10.102 action=mark-routing new-routing-mark=to-plc1 comment="Route to PLC1"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.103 action=mark-routing new-routing-mark=to-plc2 comment="Route to PLC2"
add chain=prerouting in-interface=ether1 dst-address=172.29.10.104 action=mark-routing new-routing-mark=to-plc3 comment="Route to PLC3"

# Mark connections based on initiator
add chain=prerouting connection-mark=no-mark in-interface=ether1 action=mark-connection new-connection-mark=from-mgmt comment="Mark connection from MGMT side"
add chain=prerouting connection-mark=no-mark in-interface=ether2 action=mark-connection new-connection-mark=from-plc1 comment="Mark connection from PLC1"
add chain=prerouting connection-mark=no-mark in-interface=ether3 action=mark-connection new-connection-mark=from-plc2 comment="Mark connection from PLC2"
add chain=prerouting connection-mark=no-mark in-interface=ether4 action=mark-connection new-connection-mark=from-plc3 comment="Mark connection from PLC3"

# Route return traffic from router to PLCs (where connection-mark=from-plc)
add chain=output connection-mark=from-plc1 action=mark-routing new-routing-mark=to-plc1 comment="Route to PLC1"
add chain=output connection-mark=from-plc2 action=mark-routing new-routing-mark=to-plc2 comment="Route to PLC2"
add chain=output connection-mark=from-plc3 action=mark-routing new-routing-mark=to-plc3 comment="Route to PLC3"

#######################################
# Policy-Based Routing Rules
#######################################

# Policy routes for the entire PLC subnet (/24), not just the PLC (/32)
/ip route
add dst-address=192.168.2.0/24 gateway=ether2 routing-table=to-plc1 comment="Route to PLC1"
add dst-address=192.168.2.0/24 gateway=ether3 routing-table=to-plc2 comment="Route to PLC2"
add dst-address=192.168.2.0/24 gateway=ether4 routing-table=to-plc3 comment="Route to PLC3"

#######################################
# NAT Configuration - Inbound & Reply Traffic
#######################################

# Destination NAT
/ip firewall nat
add chain=dstnat in-interface=ether1 dst-address=172.29.10.102 action=dst-nat to-addresses=192.168.2.20 comment="PLC1 Inbound"
add chain=dstnat in-interface=ether1 dst-address=172.29.10.103 action=dst-nat to-addresses=192.168.2.20 comment="PLC2 Inbound"
add chain=dstnat in-interface=ether1 dst-address=172.29.10.104 action=dst-nat to-addresses=192.168.2.20 comment="PLC3 Inbound"

# Source NAT for replies (makes router appear as 192.168.2.180 to PLCs)
add chain=srcnat out-interface-list=PLC-PORTS action=src-nat to-addresses=192.168.2.180 comment="Source NAT to PLCs"

# might be default but just in case
/ip firewall connection tracking set enabled=yes

Fin.
You do not have the required permissions to view the files attached to this post.