/config/wireguard/persistentkeepalive
WireGuard PersistentKeepalive = 25: keep a tunnel open behind NAT
- tool
- WireGuard
- file
- /etc/wireguard/wg0.conf
- key
- [Peer] PersistentKeepalive
- type
- integer seconds (1-65535) or off
- default
- off (0): no keepalive packets
PersistentKeepalive = 25 in a [Peer] section makes WireGuard send an empty authenticated packet to that peer every 25 seconds, so a NAT router or stateful firewall between them keeps the connection mapping alive. WireGuard is otherwise silent when no data flows, and NAT mappings usually expire after 30 seconds to a few minutes; after that, the peer outside the NAT can no longer reach the peer inside it. Set it on the side that is behind NAT (typically the client), for the peer that must be able to reach it. 25 is the value the WireGuard documentation suggests.
Configuration
# Client behind NAT: /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <client private key>
Address = 10.0.0.2/24
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25Apply it to a running interface without restarting:
sudo wg set wg0 peer '<server public key>' persistent-keepalive 25
sudo wg show wg0 | grep -E 'peer|keepalive|handshake'wg show lists persistent keepalive: every 25 seconds for the peer and the time of the latest handshake.
When to set it
| Situation | PersistentKeepalive |
|---|---|
| Client behind home or mobile NAT, server must push traffic or reach the client | 25 on the client |
| Client only initiates connections (browsing through the VPN) | Often not needed: outgoing packets refresh the mapping |
| Server with a public IP and no NAT | Not needed on the server |
| Site-to-site where both ends are behind NAT | Set on both; at least one side needs a reachable Endpoint |
| Battery-sensitive mobile device that rarely needs incoming traffic | Leave off to save power |
Symptoms it fixes
- The tunnel works for a while, then the server cannot ping the client until the client sends something.
latest handshakeinwg showis minutes old on a connection that should be up.- Services hosted on the client (SSH, a home server) are unreachable through the VPN after idle periods.
Keepalives do not fix a wrong Endpoint, blocked UDP port or mismatched keys: if there is never a handshake, check those first.