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.

v7 3 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/24 is fine if your LAN is 192.168.x.x.

v7 2 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:

v7 5 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.

v7 6 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 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):

client.conf 10 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

v7 3 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 — add PersistentKeepalive = 25 if you don't already have it.