GUIDE / VPN / WIREGUARD
WireGuard.
RouterOS v7 only. WireGuard is a kernel-mode VPN that runs on a single UDP socket per interface and has a tiny config surface. This page sets up a road-warrior server on your router and one client peer; the same shape extends to N peers.
Step 1 — Server keypair + interface
Create the WireGuard interface; RouterOS auto-generates a keypair.
/interface/wireguard add name=wg0 listen-port=51820 mtu=1420
/interface/wireguard print detail
# note the "public-key" field — clients need this The MTU 1420 leaves headroom for the WireGuard header (60 bytes) over a typical 1500-byte path. Lower it (1380) if you're going over an IPv6 tunnel that already loses 40 bytes to encapsulation.
Step 2 — Assign a VPN subnet
Pick a subnet that doesn't overlap with your LAN. 10.10.10.0/24
is fine if your LAN is 192.168.x.x.
/ip/address add address=10.10.10.1/24 interface=wg0
/ip/pool add name=wg-pool ranges=10.10.10.10-10.10.10.254 The pool is optional — WireGuard peers carry their own IP assignment. Useful only if you want DHCP-style handout (rare for WG).
Step 3 — Add a peer
On the client device, generate a keypair (Linux: wg genkey | tee
privatekey | wg pubkey > publickey; mobile clients generate
one when you create the tunnel in the app). Copy the client's PUBLIC
key — paste it into the peer entry on the router:
/interface/wireguard/peers add \
interface=wg0 \
public-key="<client-public-key>" \
allowed-address=10.10.10.10/32 \
comment="alice-laptop" allowed-address is the WireGuard equivalent of a static
route — packets to that address get encrypted for this peer; packets
from this peer with a source outside the range get dropped. One peer
= one /32 (for road-warrior) or one /24 (for site-to-site).
Step 4 — Firewall
Two rules: accept inbound WireGuard UDP on the listen-port, and accept traffic from the WG interface as if it were LAN.
# Accept WireGuard handshake/data on the WAN
/ip/firewall/filter add chain=input action=accept protocol=udp dst-port=51820 in-interface-list=WAN comment="WG inbound"
# Treat WG-side traffic like LAN — both for input (management) and forward (LAN access)
/ip/firewall/filter add chain=input action=accept in-interface=wg0 comment="WG → router mgmt"
/ip/firewall/filter add chain=forward action=accept in-interface=wg0 comment="WG → LAN"
/ip/firewall/filter add chain=forward action=accept out-interface=wg0 comment="LAN → WG"
Place these BEFORE the default-drop rules in
your input chain. The pre-existing
connection-state=established,related accept covers
return traffic.
Step 5 — Client config
Generate this on the router side and copy to the client. The
endpoint is your router's public IP (or DDNS hostname,
if you set one up per remote access):
[Interface]
PrivateKey = <client-private-key>
Address = 10.10.10.10/24
DNS = 10.10.10.1
[Peer]
PublicKey = <server-public-key-from-step-1>
Endpoint = your-router.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25 AllowedIPs = 0.0.0.0/0 routes ALL the client's traffic
through the VPN. Restrict to just your LAN's CIDR if you want
split-tunnelling (AllowedIPs = 192.168.88.0/24, 10.10.10.0/24).
PersistentKeepalive = 25 keeps NAT punches alive on the
client side — important for mobile clients behind CGN.
Verify
/interface/wireguard/peers print detail
# Look for "last-handshake" — should be recent once the client connects
/log print where topics~"wireguard" Common failure modes
- Client says "Handshake did not complete" — usually a
firewall rule blocking inbound 51820 on the router, or the client is
behind a NAT that's stripping the UDP packet. Check
/logfor "wireguard:" messages. - VPN connects but no LAN access — missing forward-chain
rule between
wg0and the LAN bridge, or the LAN has no route back to the VPN subnet (the router does, but a downstream device might not). - DNS doesn't resolve — set
DNSon the client to the router's WG-side address (10.10.10.1 in this example) and make sure/ip/dns set allow-remote-requests=yes. - Mobile client drops every few minutes — add
PersistentKeepalive = 25if you don't already have it.