I’m trying to route an entire WireGuard client network (10.20.0.0/24) through another Mikrotik router (R2) by sending this traffic from my CHR “hub” router through a second WireGuard tunnel.
Both WireGuard tunnels work perfectly on their own, and all routing between R1 ↔ R2 works.
The only issue appears when CHR tries to forward 10.20.0.0/24 over the R2 tunnel.
Goal
Send the whole network:
10.20.0.0/24 → WG tunnel → CHR → WG exit tunnel → R2 → Internet
while keeping all other CHR traffic routing normally.
Problem
As soon as I enable PBR on CHR to route 10.20.0.0/24 into the R2 WG tunnel:
-
devices in 10.20.0.0/24 lose Internet access,
-
mangle marks work (packets are tagged correctly),
-
the custom routing table selects the correct route,
-
the return route on R2 is correct (10.20.0.0/24 → 10.9.0.1),
-
both WireGuard tunnels remain up and stable,
-
but CHR does NOT send any packets toward R2.
Additional findings:
-
Sniffer on CHR shows traffic from 10.20.0.x, correctly marked for PBR —
but nothing leaves via wg-exit-r2.
-
Sniffer on R2 shows zero packets arriving from CHR for 10.20.x.x.
-
NAT counters on R2 stay at zero.
-
Disabling PBR immediately restores full connectivity.
It looks like RouterOS 7 refuses to forward traffic from one WG interface to another, even though all routes and firewall rules seem correct.
**
Question**
Does RouterOS 7 have any limitations or special requirements for:
-
routing traffic between two WireGuard interfaces?
-
using PBR / mangle with WireGuard traffic?
-
needing routing rules instead of plain mangle?
-
or is this topology simply unsupported without a different design?
Any guidance or known working examples would be greatly appreciated.
Configuration:
Configuration:
vpn hub (R1)
Wireguard
name="wg-es-root" mtu=1420 listen-port=<port> private-key="" public-key=""
name="wg-exit-r2" mtu=1420 listen-port=<port> private-key="" public-key=""
name="wg-es-client" mtu=1420 listen-port=<port> private-key="" public-key="“
Peers
interface=wg-es-root name="peer90" public-key="“ private-key="" endpoint-address="" endpoint-port=0 current-endpoint-address=<port> current-endpoint-port=<port> allowed-address=10.3.57.2/32 preshared-key="" persistent-keepalive=10s client-endpoint="" rx=140.4MiB tx=87.0MiB last-handshake=1m2s
interface=wg-exit-r2 name="peer-exit-r2" public-key="" endpoint-address="" endpoint-port=0 current-endpoint-address=<ip> current-endpoint-port=<port> allowed-address=10.9.0.2/32 preshared-key="" persistent-keepalive=10s client-endpoint="" rx=8.7MiB tx=8.8MiB last-handshake=51s
interface=wg-es-client name="peer98" public-key="" private-key="" endpoint-address="" endpoint-port=0 current-endpoint-address=<ip> current-endpoint-port=<port> allowed-address=10.20.0.2/32 preshared-key="" client-endpoint="" rx=17.5MiB tx=193.8MiB last-handshake=9m6s
Firewall
NAT
chain=srcnat action=masquerade out-interface=ether1 log=no log-prefix=""
Filters
chain=input action=accept connection-state=established,related log=no log-prefix=""
chain=forward action=accept connection-state=established,related
chain=input action=drop src-address-list=TCP port scanner in-interface=ether1 log=no log-prefix=""
chain=input action=add-src-to-address-list protocol=tcp psd=21,3s,3,1 address-list=TCP port scanner address-list-timeout=1w3d
in-interface=ether1 log=no log-prefix=""
chain=input action=add-src-to-address-list protocol=udp psd=21,3s,3,1 address-list=TCP port scanner address-list-timeout=1w3d
in-interface=ether1 log=no log-prefix=""
chain=input action=accept protocol=udp dst-port=<port> log=no log-prefix="" chain=input action=accept protocol=udp dst-port=<port> log=no log-prefix="" chain=input action=accept protocol=udp dst-port=<port> log=no log-prefix="" chain=input action=drop connection-state=invalid log=no log-prefix=""chain=forward action=drop connection-state=invalid chain=forward action=drop connection-state=new connection-nat-state=!dstnat in-interface=ether1
Managle
chain=prerouting action=mark-routing new-routing-mark=rtab-exit-es passthrough=no src-address-list=exit-es log=no log-prefix=""
Routing
Tables
name="main" fib
name="rtab-exit-es" fib
IP Route
dst-address=0.0.0.0/0 routing-table=rtab-exit-es gateway=10.9.0.2 immediate-gw=10.9.0.2%wg-exit-r2 distance=1 scope=30
target-scope=10 suppress-hw-offload=no
Finish Router (R2)
Wireguard
name="Client-to-CHR" mtu=1420 listen-port=<port> private-key="" public-key=""
name="wg-exit-r1" mtu=1420 listen-port=<port> private-key="" public-key=""
Peers
interface=Client-to-CHR name="peer1"
public-key="" private-key=""
endpoint-address=<static IP hub> endpoint-port=<port wireguard hub>
current-endpoint-address=<ip> current-endpoint-port=<port>
allowed-address=10.3.57.1/32,<root network> preshared-key=""
persistent-keepalive=10s client-endpoint="" rx=29.3MiB tx=103.2MiB
last-handshake=1m57s
interface=wg-exit-r1 name="wg-exit-to-CHR"
public-key="" private-key=""
endpoint-address=<static IP hub> endpoint-port=<port wireguard hub>
current-endpoint-address=<ip> current-endpoint-port=<port>
allowed-address=10.9.0.1/32,10.20.0.0/24 preshared-key=""
persistent-keepalive=10s client-endpoint="" rx=8.8MiB tx=8.7MiB
last-handshake=1m26s
Firewall
NAT
chain=srcnat action=masquerade out-interface-list=WAN log=no log-prefix=""
Filters
chain=forward action=passthrough
chain=input action=accept protocol=udp dst-port=<port>
chain=input action=accept protocol=udp dst-port=<port>
chain=input action=accept connection-state=established,related
chain=forward action=accept connection-state=established,related
Ip route
dst-address=10.20.0.0/24 routing-table=main gateway=10.9.0.1 immediate-gw=10.9.0.1%wg-exit-r1 distance=1 scope=30 target-scope=10 suppress-hw-offload=no
