Change Wireguard src-address

Hi everyone,
I have a specific challenge on a MikroTik CHR (v7). I have two WireGuard interfaces (wg1 and wg2) that are connecting to the exact same remote Endpoint IP address.
I need to force each interface to reach that same IP through different WAN gateways:

  • wg1 must reach the Endpoint via Gateway 172.16.0.1

  • wg2 must reach the Endpoint via Gateway 172.16.1.1

Since the destination IP is identical for both, standard destination-based routing won't work. I need to differentiate the traffic originating from the router itself.
My questions for the community:

  1. Is it possible to bind a specific Local Address or a different Listen Port to each outbound tunnel so I can use Mangle rules to mark and route them separately?

  2. How can I reliably use /ip firewall mangle in the output chain to distinguish between the two WireGuard instances if they are targeting the same remote IP and port?

  3. Would setting different listen-port values on my side allow me to capture that traffic in Mangle and apply different routing-marks?

Current environment: MikroTik RouterOS v7 (CHR).
I am trying to achieve this to balance the load or have redundancy between two ISPs for the same remote server. Any help with the Mangle/Routing Rule logic would be great.
Thanks!

Isn’t “mangle” the old way and for v7 you should simply use policy-based-routing ??
Go to “routing” , then “rules” and then create at least 1 rule to “intercept” traffic from a certain wgX interface and throw it out whatever WAN-port you want ?
Make sure your NAT config is also correct.

I would want to see a network diagram first as its not clear to me what devices are involved and what subnets are involved etc.. In both cases is the CHR acting as server for handshake for both WGs?
Are you attempting to different tunnels to CHR from same MT router??? If so how many WANS does this router have etc etc

IN addition to network diagram, a complete config of all connected MT devices required for analysis
/export file=anynameyouwish (minus router serial number, any public WANIP information, keys, dhcp lease lists and any ipv6 config if not used )

If I understand the situation correctly, the proper solution for you is to simply assign different listen ports to the two interfaces, and point one of the wg tunnels to your appropriate vrf.

The vrf feature for underlay traffic is a relatively new feature. If you don't have a vrf, create one. Vrfs have their own routing tables.

As far as I have understood, “Mangle” is the more advanced/complex way of doing PBR. Routing-Rules are the easy, fast way to do things - but with a lot less options.

But I think it is by design difficult to PBR WireGuard.

Is it not possible to say WG0 hat the IP 172.16.0.1, WG1 has 172.16.1.1 (all done via IP>Addresses).

If this doesnt work, the double-NAT-Workaround maybe helps?

2026-04-19 17:41:40 by RouterOS 7.19.4

system id = QEn38+9e4EM

/interface ethernet set [ find default-name=ether1 ] disable-running-check=no
/interface l2tp-client add connect-to=92.38.132.67 disabled=no name=Admin user=aa
/interface wireguard add listen-port=56860 mtu=1420 name=wg1
/interface wireguard add listen-port=14037 mtu=1420 name=wg2
/routing table add disabled=no fib name=wg1
/routing table add disabled=no fib name=wg2
/routing table add disabled=no fib name=wg0
/ip neighbor discovery-settings set discover-interface-list=none
/interface wireguard peers add allowed-address=0.0.0.0/0 endpoint-address=146.70.187.130 endpoint-port=51820 interface=wg1 name=wg1_peer persistent-keepalive=10s public-key="TpPDIhObMTeoMVx0MvSstQaIH1EfRYqW2vzGTB+ETVk="
/interface wireguard peers add allowed-address=0.0.0.0/0 endpoint-address=146.70.187.130 endpoint-port=51820 interface=wg2 name=wg2_peer persistent-keepalive=10s public-key="TpPDIhObMTeoMVx0MvSstQaIH1EfRYqW2vzGTB+ETVk="
/ip address add address=192.168.16.249/24 interface=ether1 network=192.168.16.0
/ip address add address=10.70.36.36 interface=wg1 network=10.70.36.36
/ip address add address=10.69.199.252 interface=wg2 network=10.69.199.252
/ip address add address=192.168.16.248/24 interface=ether1 network=192.168.16.0
/ip address add address=192.168.16.247/24 interface=ether1 network=192.168.16.0
/ip firewall nat add action=src-nat chain=srcnat dst-address=146.70.187.130 protocol=udp src-port=80 to-addresses=192.168.16.248 to-ports=80
/ip firewall nat add action=masquerade chain=srcnat out-interface=wg1
/ip firewall nat add action=masquerade chain=srcnat out-interface=wg2
/ip route add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=192.168.16.254 routing-table=main scope=30 suppress-hw-offload=no target-scope=10
/ip route add disabled=no distance=1 dst-address=146.70.187.130/32 gateway=192.168.16.253 pref-src=192.168.16.248 routing-table=wg1 scope=30 suppress-hw-offload=no target-scope=10
/ip route add disabled=no distance=1 dst-address=146.70.187.130/32 gateway=192.168.16.251 routing-table=wg2 scope=30 suppress-hw-offload=no target-scope=10
/ip route add disabled=no dst-address=0.0.0.0/0 gateway=wg1 routing-table=wg1 suppress-hw-offload=no
/ip route add disabled=no distance=1 dst-address=0.0.0.0/0 gateway=wg2 routing-table=wg2 scope=30 suppress-hw-offload=no target-scope=10
/ip service set www disabled=yes

This is the config of my CHR, i want the wg1 with the gateway 192.168.16.253 and wg2 with gateway 192.168.16.251, but i try many config and dont work

I think this would be the easiest solution for your needs. Your two wg1 and wg2 interfaces are probably already listening on two different ports. Two mangle mark-routing rules on chain=output with src-port as condition should do the job.

Also, if your two gateways expect two different source IP addresses then you'll also need SRCNAT rules to correct the source addresses of the outgoing UDP packets.


Alternative solutions with VRFs might be too disruptive and do not suit all situations. More and more of RouterOS became VRF-aware and if your WANs are in different VRFs then those services might lose the ability to benefit from failover/load-balancing!

Routing rules are unfortunately not applicable in this case, I think. Neither interface, src-address nor dst-address can be used as differentiators. wg1 and wg2 are not what we can use as parameter for interface in your intended rules (you can use them if you want to policy-route the traffic inside the tunnels).

DO NOT have these two routes in your wg1 and wg2 routing table. Remove them!

i try this but no work on mangle dont show anything

Maybe something like:

/ip firewall mangle
add chain=output action=mark-routing protocol=udp src-port=56860 \
    dst-address=146.70.187.130 dst-port=51820 new-routing-mark=wg1 passthrough=no
add chain=output action=mark-routing protocol=udp src-port=14037 \
    dst-address=146.70.187.130 dst-port=51820 new-routing-mark=wg2 passthrough=no

/ip firewall nat
add chain=srcnat action=src-nat out-interface=ether1 protocol=udp src-port=56860 \
    dst-address=146.70.187.130 dst-port=51820 to-addresses=192.168.16.248 place-before=0
add chain=srcnat action=src-nat out-interface=ether1 protocol=udp src-port=14037 \
    dst-address=146.70.187.130 dst-port=51820 to-addresses=192.168.16.247 place-before=0

Thanks that work 100%