I’m having a strange wireguard issue at one customer:
Customer has site A, with two IP addresses, ending with .28 and .29 (same subnet, same interface).
Site B has two ISP’s (not relevant for this issue, I think), this site is configured to establish a wireguard tunnel with site A on IP .29.
But over time I see that the wireguard tunnel will establish over .28, even though .29 is hard configured as the end-point address, see below screenshot. I even have a firewall rule on site A to block wireguard traffic on .28, which results in a dead tunnel. I’ve configured client-endpoint now for .29 on site A, restarted the wg interface and wg peer on this site. Wireguard on B will still show it’s connected to .28. Only restarting the peer on site B will will it re-establish the tunnel back on .29. Why is this happening?
After a current endpoint is established it doesn’t care about what you wrote in the endpoint field, it only looks that up if there’s no current endpoint.
I assume both .28 and .29 are public IP addresses. What you are seeing just means that at some point the router at site A sent a packet with .28 as the source. As soon as the peer at site B gets a packet with the new source, it will switch over and start sending to that IP. This is how WireGuard works, it’s called built-in roaming. This paragraph explains it well: https://www.wireguard.com/#built-in-roaming
As to why router A decides to use .28 as the source is not really up to WireGuard, it’s how your router is configured. You can either look into routing configuration or like @spippan said, use SNAT on router A to ensure this particular connection always uses the IP you want.
Thank you for the clear answer, I’ve tried configuring a SRC-NAT rule on router A to SRC NAT all UDP traffic from the UDP port(s) used by wireguard to NAT to .29. No packets are triggered by this NAT rule. The rule is first in the list, so I think packets outputted by the router itself aren’t NAT’ed?
Output packets are most certainly src-natted. If you don’t see your NAT rule working correctly these are the probable causes:
If the connection already has a conntrack entry, the src-nat rules are not consulted (again) for the ongoing connection. You have to delete the conntrack entry with some version of /ip/firewall/connection/remove [ find … ]
If your connection (in terms of conntrack) is initiated by the other side. If the “current endpoint address” has already transitioned to the address that you don’t want to use, it will still keep sending packets to that address. Disabling/enabling the peer resets this.
(… or 3. Your NAT rule simply has a typo in it.)
I did quite a bit of testing around Wireguard and NAT. (There is a whole saga around this topic on the forum. I can guarantee a headache if you try to process it all.) For testing I usually follow this procedure:
Disable wg peers on both sides.
Delete conntrack entries. Depending on the testing on one side only or on both sides.
I let the rule run overnight, and now it has 55 packets hit, however the peer (site B) is still showing that the current endpoint is .28. I think this is a conntrac issue then, and we’ll need to find a maintenance window to down the WG interfaces and remove the active connections for this.
Here’s the config:
/ip/firewall/nat/export where action=src-nat
# 2025-05-09 09:28:14 by RouterOS 7.16.2
# software id =
#
/ip firewall nat
add action=src-nat chain=srcnat comment="Force Wireguard over .29" out-interface=ether1 protocol=udp src-address=x.x.x.28 src-port=\
20001-20010 to-addresses=x.x.x.29
add action=src-nat chain=srcnat comment="External SRCNAT" out-interface=ether1 to-addresses=x.x.x.28
The complete config is required as requested for me to reply, unlike anserk I dont like playing whackamole
Its already clear that you are trying some non-standard setups to deal with a yet to be fully determined wan setup and unknown set of user requirements.
I don’t think you need a downtime, you can just find the connection in WinBox Firewall - Connections and delete it from there. It doesn’t kill the actual connection but simply removes it from conntrack, forcing packets to go through the full firewall rule list as it would for new or expired connections. As soon as router A starts sending packets sourced with .29, router B will switch over automatically. But playing it safe in production environment is always a good idea.
Or maybe xx.xx.xx.28/31 on recent versions of routeros.
Reasoning:
The connection out from wireguard back to the caller is a new connection (not the same connection as the incoming data)
The packets seen at the output chain from wireguard have already been routed and natted, so really too late to do anything at this time.
Wireguard will attempt to use the same source address as the incoming packet, but it is on a different new connection, so will
likely get natted if it is not the IP address ether1 is masquerading too.
I am a bit surprised the return packets actually got back into the source router.
(Unless you have allowed incoming packets on the wireguard port)