WireGuard keeps retrying handshakes after client disconnect and power off (7.18.2)

Possible WireGuard Handshake Retry Issue in RouterOS 7.18.2

Device Information

  • Device: MikroTik RB750Gr3 (hEX)

  • RouterOS Version: 7.18.2 (stable)

  • Architecture: mmips

Network Topology

Internet

ISP Router (LAN 192.168.1.1)

DMZ

MikroTik hEX

Internal LAN

The ISP router forwards traffic through DMZ to the MikroTik WAN interface.

WireGuard Configuration

The MikroTik is configured as a WireGuard server.

Three peers are configured:

  • Android phone

  • Home notebook

  • Second notebook

Configuration characteristics:

  • No endpoint-address configured on any peer.

  • No endpoint-port configured.

  • Only allowed-address and public-key configured.

  • Initially persistent-keepalive=25s was configured.

  • For testing purposes, persistent-keepalive was later removed completely from all peers.

  • The behaviour remains exactly the same after removing persistent-keepalive.

Reproducible Procedure

The following procedure reproduces the behaviour consistently:

  1. Enable the WireGuard tunnel on the Android phone.

  2. Use the VPN normally for approximately one minute.

  3. Disable the VPN from the Android client.

  4. Observe the RouterOS logs.

After disconnecting, RouterOS starts generating messages similar to:

Handshake for peer did not complete after 5 seconds, retrying (try 2)

followed later by:

Handshake for peer did not complete after 20 attempts, giving up

Tests Performed

The following tests were performed in order to eliminate configuration errors:

  • Verified that endpoint-address is empty.

  • Verified that endpoint-port is not configured.

  • Removed persistent-keepalive from MikroTik peers.

  • Rebooted the complete network infrastructure.

  • Verified CPU usage remains very low.

  • Verified memory usage remains normal.

  • Verified there are no active VPN clients.

  • Completely powered off the Android phone.

  • Verified notebooks are powered off.

Despite all of the above, repeated handshake retry messages continue to appear.

Very Important Observation

This appears to be fully reproducible.

If the affected WireGuard peer is:

  • manually disabled,

  • left disabled for approximately 10 seconds,

  • and then enabled again,

the repeated handshake retry messages stop immediately.

The RouterOS log becomes completely clean again.

After that, no further handshake retry messages are generated.

However, if the Android client is connected again, used normally, and then disconnected, the same behaviour appears again and can be reproduced repeatedly.

This specific observation may help identify whether some internal peer state is not being cleared correctly after client disconnection.

Resource Usage

CPU usage remains approximately 4%.

Memory usage remains normal.

There is no apparent performance issue, but the repeated handshake attempts appear unexpected.

Request

Could you please clarify whether this is expected WireGuard behaviour in RouterOS 7.18.2?

If it is expected, could you please explain why RouterOS continues attempting handshakes after:

  • the client has disconnected,

  • the client has been completely powered off,

  • no endpoint-address is configured,

  • and no active VPN client exists?

If this is not expected behaviour, could this indicate an issue in peer state handling or handshake retry logic?

I intentionally did not include a supout.rif because it contains sensitive infrastructure information.

However, the behaviour appears to be reproducible using the procedure described above, and I hope this information is sufficient to reproduce the issue in a laboratory environment.

Retest with later versions. There have been some improvements on that behavior as far as I can recall.

That's normal WG behavior. WireGuard by design have peers, not client-server. If you want to simulate a client-server setup, enable the Responder checkbox and turn off persistent keepalive in the peers' properties in WinBox and you'll stop seeing those log messages.

On the devices (phones, laptops) enable persistent keepalive.

Thank you Very much. It s work!

Sorry, it was late last night, so I did not write a longer response. Let me add some more clarification :slight_smile:

These two points are not important. As you can see, once a successful handshake has been performed, WG on RouterOS will remember the remote address and port of the remote peer in current-endpoint-address and current-endpoint-port. These are the values that will be used when WG sends out UDP packets. This is how WG can easily support roaming. A mobile peer can roam between LTE/5G and multiple WiFi networks for example, while still maintaining an active WG connection. The other side just needs to remember the latest address and port of the handshake, and they don't need to match the initial values you specified in endpoint-address and endpoint-port.

This roaming applies to both sides. WireGuard have equal peers on both sides, not a client and server concept. By default, when one side has something to send, that side can always initiate a connection (start a handshake if there was no recent enough handshake, usually more than a couple of minutes), as long as it has the address and port information of the other side (what in current-endpoint-address and current-endpoint-port, or if those don't have value yet, then what in endpoint-address and endpoint-port).

So when you turn off the WG tunnel on the phones or laptops, at that moment, there might still be on going connections that was going through the tunnel. When there are still packets of those connections on the MikroTik router side, WireGuard on RouterOS will try to send them to your phones or laptops. When the handshake timeout (a couple of minutes) has not elapsed, it will send the UDP wrapper packets, which will not arrive. Then it will try to establish a new handshake, by using the latest known data from current-endpoint-address and current-endpoint-port. That will get no response, and the handshake will fail, and is the reason for the log messages you saw. After a few handshake attempts, WG on RouterOS will give up.

Again, this is how WireGuard was designed. There is no side that only listens for "incoming connections" and acts as server, both peers are similar.

MikroTik to work-around the issue with the log message, has introduced the "Responder" setting to the peers in 7.15:

with some more fixes in 7.17:

When you now turn on the option, even when there are still packets in the queue that need to be send to the other side of the tunnel, RouterOS will not try to initiate a new handshake anymore. It will only listen to handshakes initiated by the other side, similar to a "server". But this is not a standard WG behavior, only a special workaround from MikroTik.

Thanks you very much.