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.

v73 lines · 146 bytes
/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/24is fine if your LAN is 192.168.x.x.

v72 lines · 109 bytes
/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:

v75 lines · 147 bytes
/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.

v76 lines · 532 bytes
# 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 inyour input chain. The pre-existingconnection-state=established,related accept covers return traffic.

Step 5 — Client config

Generate this on the router side and copy to the client. Theendpoint is your router's public IP (or DDNS hostname, if you set one up per remote access):

client.conf10 lines · 274 bytes
[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

v73 lines · 149 bytes
/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/log for "wireguard:" messages.
  • VPN connects but no LAN access — missing forward-chain rule between wg0 and 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 DNS on 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 — addPersistentKeepalive = 25 if you don't already have it.