WireGuard Peer not functioning after a router restart

I can fully agree that it’s not up to the PROTOCOL to make sure DNS resolution is functional.
This should already have been handled upfront before the protocol was initiated to start.
Just like NTP service does not test it either, neither will it make sure DNS will work. It has to work before.
(but NTP will retry later on …that’s the difference)

So … to put it indeed in a positive way it’s effectively a “feature” of Wireguard which needs to be dealt with by the operating system it runs under.
And currently ROS does NOT retry anything. You can wait till your beard grows onto the ground.
Someone manually needs to retrigger the start of that WG interface to re-initiate that resolution of the endpoint. Or have a script deal with it (ROS, Linux, whatever, …). Or … the operating system needs to deal with it. Last option is ideally the best.

Just for fun, I pulled to cable on my Windows-laptop and made sure no Wifi is connecting. So no network at all.
When trying to initiate WG, it gives me an error “no such host is known or present”. And THAT’s how it should be. The error should be caught and the “caller” needs to be notified about it.
But this has NOTHING to do with flaky setup of the interface as indicated several posts above. It’s because of a condition prior to starting said interface.

On Windows, the client has something coded that takes care of this.
https://git.zx2c4.com/wireguard-windows/tree/conf/dnsresolver_windows.go

It’s an opportunity for RouterOS to do it better. It’s friendly OS where things are nicely integrated together, so it makes sense to handle this automatically. This one, if it’s as startup error, is pretty obvious. There’s hostname for peer, it’s not available, trying again later is the one right choice and should happen automatically.

It’s slightly more complicated if you’d want to handle changes for already established connections. E.g. server goes away for a while and comes back with different address. But client doesn’t know that and will be sending packets to old address. Server won’t be able to notify client about the change. Client would need to resolve server’s hostname (which now points to new address) again, but it probably doesn’t do it either. This should probably not happen automatically. But an option to try it after user-defined time, when there’s no contact with peer, could be nice.

I avoid this by creating static DNS entries in the router creating so a pool of IP addresses that apply to that specific VPN connection.

When you are depending on external server to return the dynamic IP address of the peer then you could store that in static DNS entry every so many minutes. Use the static entry then as endpoint address.

When the internet connection is restored and in the meantime the IP address on the other side has changed, then after updating the static DNS entry that you can script a restart of the WG peer…swatting so two flies in one hit.

Yes, it’s doable. But think about average users, they shouldn’t need to do this, it should work automatically. If I set endpoint for peer, that’s clear indication that I want system use it to initiate new connection. If it’s hostname and system tries to resolve it once and immediatelly gives up when it fails, it’s not good.

On first start, a resolve is made but no IP is returned then try again later. If an other reply, as nxdomain, servfail or refused then no retry, as it is now.
Add DNS blockers like Pi-hole: 0.0.0.0 or ::0 is also no retry

@gdanov, question for you back at post #30. A bit of noise occurred in between. :wink:

I’m not scripting expert. Originally tried with netwatch, nothing happened then reading the forum I saw other people do it with schedule because “netwatch has not enough rights”.
I’ll experiment with that checkbox.

Just to be clear, 10.1.1.51 being pinged from the remote client router is
you trying to ping a subnet address on the Server router through the tunnel ???

yes, but your wording is bit confusing, so let me repeat: the local peer (one running the script) pings the remote peer’s tunnel IP. 10.x.x.x is my wireguard sub-net.

So the complete script would be

:global myFunc [:parse [/system script get watch-WG-pp source]]
$myFunc wgcheckip=10.1.1.51 endpointip=xxxyyy.sn.mynetname.net

#:log info "wg check-ip $wgcheckip "

:if ([/ping $wgcheckip interval=1 count=5] =0) do={
:log info “WG down $wgcheckip”
/interface/wireguard/peers/disable [find endpoint-address=$endpointip];
:delay 60
/interface/wireguard/peers/enable [find endpoint-address=$endpointip];
:log info “WG up again $wgcheckip”
}

>

I don't think that would work if you use it as one script. If you want one script (instead of script entry + second script that invokes it as function) it needs to look something like this:

```text
:local wgcheckip 10.1.1.51
:local endpointip xxxyyy.sn.mynetname.net

#:log info "wg check-ip $wgcheckip "

:if ([/ping $wgcheckip interval=1 count=5] =0) do={
  :log info "WG down $wgcheckip"
  /interface/wireguard/peers/disable [find endpoint-address=$endpointip];
  :delay 60
  /interface/wireguard/peers/enable [find endpoint-address=$endpointip];
  :log info "WG up again $wgcheckip"

regarding the “noise” — WireGuard is not a finished service, it’s a low-level tool, unfortunately. The complaints are valid, but people miss the fact that WG is intentionally limited in functionality by it’s creators because they wanted small and auditable code base. That’s fair, problem is we don’t have high quality add-ons for it. For example linux wg-quick is of questionable value. Unfortunately the mobile clients also aren’t very smart too and lack proper connection health sensing + retry.

With WG you are on your own and need to build scripts to monitor and re-establish the connections. That’s my experience running several WG meshes on Ubuntu, OSX, Android and Windows. It’s not MT problem.

Sorry for the confusion but right back at ya! I didnt understand the below…

so let me repeat: the local peer (one running the script) pings the remote peer’s tunnel IP.
10.xc.x.x is my wireguard sub-net.

Can I assume you mean the script on the client device that originates the initial connection (your MT router) , pings an IP address within the subnet you have assigned to the tunnel at the remote site - and thus the linux device has assigned an IP address of something like 10.1.1.1/24 network 10.1.1.0 to the tunnel??

Close?

What if on the Wireguard Setup at the linux end, has NO IP address was assigned to WG Interface ( I rarely do!).
Wouldnt it be good enough to simply ping any local address at the remote site, THRU the tunnel (assuming of course that all requiste wireguard settings and firewall rules allowed the traffic)

finally it all makes sense :slight_smile: I always give IPs to my WG peers. Had abs. never thought about going without an IP (well, duh, yes, obvious now).
Yes, you could ping anything on the remote end that would go via the tunnel.

Thank you everyone for posting about this issue and also for multiple ways around it. I just thoroughly tested this issue and would like to emphasize that three conditions must be in place for the issue to happen:

  • DNS is used as the endpoint peer.


  • Client router reboots.


  • WAN link is disconnected when the router is up, and later it gets reconnected.

All three have been mentioned in the discussion above. In my many tests simply rebooting the router did not cause this issue. I do have keepalive configured, so shortly after the reboot I could see the DNS name appearing in the DNS cache window, and the packets on the WireGuard interface started to flow without any intervention on my part.

This might explain why some people have been using WireGuard for a long time and didn’t observe this issue.

Dynamic IP changes without involving reboots would still cause the same issue, so the workaround is still needed.

Just wanted to share another finding. The Netwatch script actually works perfectly without any permission tweaking. However, Netwatch is only triggered when status changes from up to down or down to up. This is actually a very nice feature, especially for some email alerts as you wouldn’t want to get emails every minute when your target is down for a prolonged period of time.

So the Netwatch script fired once, but if there is still a connection issue (in my tests I disabled the remote interface), it will not try again because the status is still down as with the last check. Use a scheduler script instead that will keep trying forever based on the schedule you define.