Forward WAN port to another subnet/router LAN

Please bear with my network diagramming skills :slight_smile:
Home Net.drawio.png
I have MikroTik router with “default” LAN 192.168.88.0/24 and WireGuard-dedicated LAN 192.168.80.0.
There is a WireGuard to remote router (OpenWRT, but it shouldn’t matter much, I guess).

I need to forward some port, say 7777 on my WAN interface (pppoe-out1) to a PC on remote router LAN, its IP is 192.168.10.200.
Everything else seems to be working fine:

  • I have a similar port forwarding rule to a PC “inside” MikroTik LAN which is working
  • Routing between sub-nets on different routers are fine: I can see my PC 192.168.10.200 from 192.168.88.0/24 subnet and vice versa

Initially I though that adding this rule would suffice, but apparently I was wrong. Incoming packet shows (out: unknown) in log files.

/ip firewall nat add action=dst-nat chain=dstnat dst-port=7777 protocol=tcp to-addresses=192.168.10.200 to-ports=7777)

What am I missing?

Connecting via WG to remote?
Too much missing info.
Post full configs on both routers
/export file=anynameyouwish ( minus router serial number, public WANIP information, keys etc.)

Here’s excerpt from my MK config (I removed just a few completely irrelevant pieces that just works)

/interface bridge add admin-mac=B8:69:F4:03:26:AE arp=proxy-arp auto-mac=no comment=defconf name=bridge port-cost-mode=short
/interface wireless set [ find default-name=wlan1 ] antenna-gain=0 band=2ghz-b/g/n channel-width=20/40mhz-XX country=belarus disabled=no distance=indoors frequency=auto frequency-mode=manual-txpower installation=indoor mode=ap-bridge ssid=WhyFi2 station-roaming=enabled wireless-protocol=802.11 wmm-support=enabled wps-mode=disabled
/interface wireless set [ find default-name=wlan2 ] antenna-gain=0 band=5ghz-a/n/ac channel-width=20/40/80mhz-XXXX country=belarus disabled=no distance=indoors frequency=auto frequency-mode=manual-txpower installation=indoor mode=ap-bridge ssid=WhyFi2 station-roaming=enabled wireless-protocol=802.11 wmm-support=enabled wps-mode=disabled
/interface pppoe-client add add-default-route=yes disabled=no interface=ether1 name=pppoe-out1 password=<...> user=<...>
/interface wireguard add comment="WireGuard server" listen-port=13231 mtu=1420 name=wg1 private-key="xxx"
/interface list add comment=defconf name=WAN
/interface list add comment=defconf name=LAN
/ip pool add name=dhcp ranges=192.168.88.100-192.168.88.254
/ip dhcp-server add address-pool=dhcp interface=bridge lease-time=1h name=defconf
/routing table add disabled=no fib name=wg-vpn
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=ether2 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=ether3 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=ether4 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=ether5 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=wlan1 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge comment=defconf ingress-filtering=no interface=wlan2 internal-path-cost=10 path-cost=10
/interface bridge port add bridge=bridge disabled=yes ingress-filtering=no interface=*D internal-path-cost=10 path-cost=10
/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
/interface list member add comment=defconf interface=ether1 list=WAN
/interface list member add disabled=yes interface=*A list=WAN
/interface list member add interface=pppoe-out1 list=WAN
/interface pptp-server server
# PPTP connections are considered unsafe, it is suggested to use a more modern VPN protocol instead
set enabled=yes
# My external router. Port forward destination is there
/interface wireguard peers add allowed-address=192.168.80.7/32,192.168.10.0/24,192.168.1.0/24 comment="Sokol Router" interface=wg1 public-key="<...>"
/ip address add address=192.168.88.1/24 comment=defconf interface=ether2 network=192.168.88.0
/ip address add address=10.0.88.0/24 disabled=yes interface=bridge network=10.0.88.0
/ip address add address=192.168.80.1/24 comment="WireGuard server" interface=wg1 network=192.168.80.0
/ip dhcp-server network add address=192.168.88.0/24 boot-file-name=undionly.kpxe comment=defconf dns-server=192.168.88.60 gateway=192.168.88.1 next-server=192.168.88.60
/ip firewall filter add action=accept chain=input disabled=yes dst-port=443 protocol=tcp
/ip firewall filter add action=accept chain=input comment="defconf: accept established,related,untracked" connection-state=established,related,untracked
/ip firewall filter add action=accept chain=input comment="Allow establish Remote Access" in-interface-list=WAN log=yes log-prefix=remote_sys port=500,4500 protocol=udp
/ip firewall filter add action=accept chain=input comment="Allow establish Remote Access" in-interface-list=WAN log=yes log-prefix=remote_sys protocol=ipsec-esp
/ip firewall filter add action=accept chain=input comment=WireGuard dst-port=13231 protocol=udp
/ip firewall filter add action=accept chain=input comment="IKE2: Allow ALL incoming traffic from 10.0.88.0/24 to this RouterOS" ipsec-policy=in,ipsec log-prefix=vpn src-address=10.0.88.0/24
/ip firewall filter add action=accept chain=input comment="Allow access to WinBox via WireGuard" dst-port=8291 in-interface=wg1 protocol=tcp
/ip firewall filter add action=drop chain=input comment="defconf: drop invalid" connection-state=invalid
/ip firewall filter add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
/ip firewall filter add action=accept chain=input comment="defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
/ip firewall filter add action=drop chain=input comment="defconf: drop all not coming from LAN" in-interface-list=!LAN log-prefix=bad
/ip firewall filter add action=accept chain=forward comment="IKE2: Allow ALL forward traffic from 10.0.88.0/24 to OFFICE network" dst-address=192.168.88.0/24 ipsec-policy=in,ipsec log-prefix=vpn src-address=10.0.88.0/24
/ip firewall filter add action=accept chain=forward comment="IKE2: Allow ALL forward traffic from 10.0.90.0/24 to WAN only" out-interface-list=WAN src-address=10.0.90.0/24
/ip firewall filter add action=accept chain=forward comment="defconf: accept in ipsec policy" disabled=yes ipsec-policy=in,ipsec
/ip firewall filter add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec log-prefix=vpn
/ip firewall filter add action=accept chain=forward comment="defconf: accept established,related, untracked" connection-state=established,related,untracked
/ip firewall filter add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related hw-offload=yes
/ip firewall filter add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid log-prefix=drop
/ip firewall filter 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 mangle add action=passthrough chain=forward comment="Traffic from Vacuum" src-address=192.168.88.57
/ip firewall mangle add action=passthrough chain=forward comment="Traffic to vacuum" dst-address=192.168.88.57
/ip firewall mangle add action=change-mss chain=forward new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn
/ip firewall mangle add action=accept chain=forward comment="Forward Gritsevtsa -> Sokol" dst-address=192.168.1.0/24 src-address=192.168.10.0/24
/ip firewall mangle add action=accept chain=forward dst-address=192.168.1.0/24 src-address=192.168.80.0/24
/ip firewall mangle add action=accept chain=prerouting dst-address=192.168.1.0/24 src-address=192.168.88.0/24
/ip firewall mangle add action=accept chain=forward disabled=yes dst-address=192.168.1.0/24 in-interface-list=WAN
/ip firewall mangle add action=accept chain=forward comment="Forward Home -> Gritsevtsa" dst-address=192.168.10.0/24 src-address=192.168.88.0/24
/ip firewall mangle add action=log chain=prerouting disabled=yes protocol=icmp src-address=10.0.88.2
/ip firewall mangle add action=mark-connection chain=prerouting connection-state=new dst-address-list=split-vpn new-connection-mark=wg-vpn passthrough=yes
/ip firewall mangle add action=mark-routing chain=prerouting connection-mark=wg-vpn dst-address-list=split-vpn new-routing-mark=wg-vpn passthrough=no
/ip firewall nat add action=masquerade chain=srcnat ipsec-policy=out,none log-prefix=vpn src-address=10.0.88.0/24
/ip firewall nat add action=masquerade chain=srcnat connection-mark=wg-vpn
/ip firewall nat add action=masquerade chain=srcnat disabled=yes ipsec-policy=out,none src-address=10.0.90.0/24
/ip firewall nat add action=masquerade chain=srcnat comment="defconf: masquerade" ipsec-policy=out,none out-interface-list=WAN
/ip firewall nat add action=dst-nat chain=dstnat dst-port=8123 protocol=tcp to-addresses=192.168.88.60 to-ports=8123
# HERE HERE HERE: I assume this rule will do the job but apparently it doesn't
/ip firewall nat add action=dst-nat chain=dstnat disabled=yes dst-port=8124 protocol=tcp to-addresses=192.168.1.200 to-ports=8123
/ip firewall nat add action=dst-nat chain=dstnat comment="Port forward to HTPC" dst-address-type=local dst-port=443 protocol=tcp to-addresses=192.168.88.60 to-ports=443
/ip firewall nat add action=dst-nat chain=dstnat comment="Port forward to qBittorent on NAS" dst-port=6882 in-interface-list=WAN protocol=tcp to-addresses=192.168.88.63 to-ports=6882
/ip firewall nat add action=masquerade chain=srcnat disabled=yes out-interface=wg2
/ip firewall nat add action=masquerade chain=srcnat comment="Hairpin NAT for Home Assistant" dst-address=192.168.88.60 dst-port=443,8123 log-prefix=hair-pin protocol=tcp src-address=192.168.88.0/24
/ip firewall nat add action=masquerade chain=srcnat disabled=yes dst-address=192.168.1.0/24 log=yes protocol=tcp src-address=86.57.152.197
/ip firewall nat add action=dst-nat chain=dstnat comment="Forward to MeatPC:RDP" disabled=yes dst-port=3389 protocol=tcp to-addresses=192.168.88.13 to-ports=3389
/ip route add disabled=no distance=1 dst-address=192.168.1.0/24 gateway=wg1 pref-src="" routing-table=main scope=30 suppress-hw-offload=no target-scope=10
/ip route add disabled=no dst-address=192.168.10.0/24 gateway=wg1 routing-table=main suppress-hw-offload=no

My “external” router, referred to as Sokol Router above based on OpenWRT 23. Its Firewall config is like this:
Scr-2024-01-15 at 19.29.31.png
Let me state that everything else is working just fine: I am able to access my instance 192.168.1.200 from my MK local subnet.

UPDATE: As a second thought, I decided to add forwarding-allow rule like this:

chain=forward action=accept protocol=tcp out-interface=wg1 in-interface-list=WAN dst-port=8123 log=yes log-prefix=""

When I try to establish connection, there’s log message like this:

forward: in:pppoe-out1 out:wg1, connection-state:new,dnat proto TCP (SYN), <my-current-ip>:45329->192.168.1.200:8123, NAT <my-current-ip>:45329->(<mikrotik-public-ip>:8124->192.168.1.200:8123), len 64

Okay so remote router is not MT its something else.
You wish for your external users to use your DYNDNS URL/IP address of the mikrotik router to reach the server at 192.168.10.200
In other words, enter the MT router then be port forwarded through the tunnel to the other router…

I will look at the config… keep important lines and modify others.

/interface bridge add admin-mac=B8:69:F4:03:26:AE arp=proxy-arp auto-mac=no comment=defconf name=bridge port-cost-mode=short
/interface wireguard add comment=“WireGuard server” listen-port=13231 mtu=1420 name=wg1 private-key=“xxx”
/interface list add comment=defconf name=WAN
/interface list add comment=defconf name=LAN
/ip pool add name=dhcp ranges=192.168.88.100-192.168.88.254
/ip dhcp-server add address-pool=dhcp interface=bridge lease-time=1h name=defconf
/routing table add disabled=no fib name=wg-vpn
/interface list member add comment=defconf interface=bridge list=LAN
/interface list member add comment=defconf interface=ether1 list=WAN
/interface list member add interface=pppoe-out1 list=WAN

/interface wireguard peers add allowed-address=192.168.80**.7**/32,192.168.10.0/24,192.168.1.0/24 comment=“Sokol Router” interface=wg1 public-key=“<…>”

OKAY
so we can infer that your local subnet 192.168.88.1 needs access to 192.168.10.0/24 and 192.168.1.0/24 subnets at the other router!
OR
we can infer that remote subnets 192.168.10.0/24 and 192.168.1.0/24 require access to the MT LAN or WAN.
WRONG
The IP address for the remote router is wrong should be
/interface wireguard peers add allowed-address=192.168.80**.8**/32,192.168.10.0/24,192.168.1.0/24 comment=“Sokol Router” interface=wg1 public-
WHY
you dont seem to have any other peers, would have thought at least one for the admin to remotely connect to be able to config the router when away.

/ip address add address=192.168.88.1/24 comment=defconf interface=ether2 network=192.168.88.0
/ip address add address=10.0.88.0/24 disabled=yes interface=bridge network=10.0.88.0

This makes no sense to me ETHER2 is on the bridge so why does it have some strange address DELETE/REMOVE IT.
Not only that but the SYNTAX is wrong anyway should be 10.0.88.1

The address for the bridge should have the BRIDGE as interface.
/ip address add address=192.168.88.1/24 comment=defconf interface=bridge network=192.168.88.0


FIREWALL RULES ORDER AND ORGANIZATION MODIFIED

Q1: how does 10.0.88.0/24 subnet even come into this config?
Q2. how does 10.0.90.0/24 subnet even come into this config?

{ Forward Chain }
(default rules to keep)
/ip firewall filter add action=accept chain=input comment=“defconf: accept established,related,untracked” connection-state=established,related,untracked
/ip firewall filter add action=drop chain=input comment=“defconf: drop invalid” connection-state=invalid
/ip firewall filter add action=accept chain=input comment=“defconf: accept ICMP” protocol=icmp
/ip firewall filter add action=accept chain=input comment=“defconf: accept to local loopback (for CAPsMAN)” dst-address=127.0.0.1

(admin rules)
/ip firewall filter add action=accept chain=input comment=“Allow establish Remote Access” in-interface-list=WAN log=yes log-prefix=remote_sys port=500,4500 protocol=udp
/ip firewall filter add action=accept chain=input comment=“Allow establish Remote Access” in-interface-list=WAN log=yes log-prefix=remote_sys protocol=ipsec-esp
/ip firewall filter add action=accept chain=input comment=WireGuard handshake" dst-port=13231 protocol=udp
/ip firewall filter add action=accept chain=input comment=“Allow access to WinBox via WireGuard” dst-port=8291 in-interface=wg1 protocol=tcp
/ip firewall filter add action=drop chain=input comment=“defconf: drop all not coming from LAN” in-interface-list=!LAN log-prefix=bad

{ Forward Chain }
(default rules to keep fastrack rule is BEFORE established,related)
/ip firewall filter add action=accept chain=forward comment=“defconf: accept in ipsec policy” disabled=yes ipsec-policy=in,ipsec
/ip firewall filter add action=accept chain=forward comment=“defconf: accept out ipsec policy” ipsec-policy=out,ipsec log-prefix=vpn
/ip firewall filter add action=fasttrack-connection chain=forward comment=“defconf: fasttrack” connection-state=established,related hw-offload=yes
/ip firewall filter add action=accept chain=forward comment=“defconf: accept established,related, untracked” connection-state=established,related,untracked
/ip firewall filter add action=drop chain=forward comment=“defconf: drop invalid” connection-state=invalid log-prefix=drop

(admin rules)
/ip firewall filter add action=accept chain=forward comment=“internet traffic” in-interface-list=LAN out-interface-list=WAN
/ip firewall filter add action=accept chain=forward comment=“port forwarding” connection-nat-state=dstnat
/ip firewall filter add action=drop chain=forward comment=“Drop all else”

There are too many things going on to comment further on firewall rules or mangles.
If the complete config is not presented, then its not possible to see the forest from the trees…
-Two subnets make no sense without the rest of the config.
-Your destination nat rules are not complete or consistent in format
-You suddenly have a second wireguard interface without reason…

  • Mangles cannot be digested without more information… why which speaks to requirements, etc etc…
    ++++++++++++++++++++++++++++++++++++++

In any case, I will remove myself from this thread and state.
To get port forwarding to work through the tunnel, you need to accept the incoming external traffic at the MT router, as per normal port forwarding. You then have to guide that traffic into the wireguard tunnel. This is accomplished with a properly formatted dstnat rule and and IP route.

  1. see my forward chain ruleset (allows port forwarding)
  2. Dst-nat rule for traffic to remote server, use to-address of actual server on remote router.
  3. Create IP route on MT
    add dst-address=IPServer gateway=wg1 routing-table=main

( NOTE: since other router allowed-IPs for MT peer will be =0.0.0.0/0 different source address arriving at other router not a problem and OPs usually want to see the actual source IPs anyway. )

  1. NO need to sourcenat out WG1 and dont recommend it in this case see note above…

  2. Add the WG interface to the LAN interface list.

  3. What you do after it leaves the MT and arrives at the other router is not our concern.

  4. Return traffic will come from the server and thus will be accounted for on the allowed IPs on the MT peer settings for the other router.

  5. the LAN to WAN Rule will ensure the server return traffic exiting the WG tunnel at the MT will go back out the WAN interface ( see point 5. )

Good luck!!

anav, thanks for your time!
You must have spent a lot of time analyzing my config and writing down such an elaborated analysis.
But I find a situation a bit weird. I didn’t want to put the whole config for clarity. Well, I failed to remove a few irrelevant things, such as remnants for another WG subnet and another IPSec tunnel. I think that contributed to a confusion a bit.

Let me ask the question a differently: what should someone do if they want to forward some port on WAN interface (static publicly routed IP, not sh*t like DynDNS at all) to a server on remote WG subnet:

  • WAN IP is snow-white, static, never changes
  • WireGuard between routers works fine: being in MikroTik LAN it is possible to access above mentioned server

Here’s what I have right now:

Port forwarding:

/ip firewall nat add chain=dstnat action=dst-nat to-addresses=192.168.1.200 to-ports=8123 protocol=tcp dst-port=8124

Route to remote WG subnet:

/ip route add distance=1 dst-address=192.168.1.0/24 gateway=wg1 pref-src="" routing-table=main scope=30 suppress-hw-offload=no target-scope=10

If you read the above notes, its pretty much covered.

I only mentioned dyndns because most server admins give an URL for people to use, a lot handier than a long assed IP address.
Something like Johns.homeserver.net

As stated yes.

  1. Forward chain rule as per my forward chain above ( get rid of DEFAULT dstnat rule and replace with three rules )
    add action=forward action=accept comming='internet traffic" in-interface-list=LAN out-interface-list=WAN
    add chain=forward action=accept comment=“port fowarding” connection-nat-state=dstnat
    add chain=forward action=drop comment=“Drop All Else”

  2. Ensure you add wireguard interface to LAN list

  3. Ensure you remove wireguard from sourcenat

  4. Your IP route is good, I would put the IP address of the server unless there are other servers in the mix as well.

  5. Dstnat rule is missing a component.
    /ip firewall nat add chain=dstnat action=dst-nat dst-address=StaticWANIP to-addresses=192.168.1.200 to-ports=8123 protocol=tcp dst-port=8124


    ( to confirm you are asking your users to come in on port 8124 to the router and the router will change it to port 8123 before it actually hits the server )

Unfortunately, I’m still fighting with a problem.
To make sure packets incoming to :8124 are actually get routed and leave the MK router, I’ve added the following rule:

chain=postrouting action=passthrough protocol=tcp out-interface=wg1 dst-port=8123 log=yes log-prefix="+"

and yes, I see log entries for that rule. However, I’m not completely sure if this correct way to make sure packet leave the router :frowning:

And another thought: looks like forwarded packages have my WAN IP as source IP address but this is unexpected for LAN-to-LAN wireguard tunnel.
Am I going to the right direction?

Thanks.

Wireguard has serious limitations. Wireguard only works well in ads. Most softphone programs VOIP don’t work in Wireguard. SIP isn’t working properly. Waste of time Wireguard is not suitable for SIP. Please remember that Wireguard only works on layer 3 and needs routing everywhere. I did many tests and gave up.

its been awhile since ive looked at your config.
Post the complete config again and state clearly what you are attempting to do.

For those who stumbled on the same issue, here’s my solution.
This is one of the posts that helped me in my chain of thoughts: http://forum.mikrotik.com/t/dst-nat-and-src-nat-on-same-connection/152089/1

Main problem was to understand that remote instance 192.168.10.200 does not have WG interface as default gateway. Thus, dst-nat port forwarding on inbound router works fine, replies did not get back to the tunnel.

Idea of the solution is simple: dst-nat PLUS src-nat.
dst-nat is for WAN port forwarding, src-nat is to keep two-way traffic flow inside WG tunnel.

YMMV, therefore I’m not going to write exact rules here.

Now, ladies and gens, the case is officially marked as [SOLVED] :slight_smile:

You have discovered a truly marvelous proof of this, which this margin is too narrow to contain? :wink: :laughing:
Seriously, if you can, do post the configuration that actually solved the problem, even if mileage of other members may vary, at least they will have a base reference.