Back to blog

MikroTik / RouterOS  ·  Tutorial  ·  August 2026

WireGuard
on MikroTik

RouterOS 7 ships WireGuard in the kernel, and it makes every older VPN on the platform feel like homework. No certificates, no phases, no proposals — an interface, a key pair, and a list of peers. This post builds the two setups that cover almost every real need: your phone and laptop dialing home from anywhere, and two offices joined by a tunnel that survives reboots and ISP changes.

RouterOS 7 WireGuard VPN Road Warrior Site-to-Site Remote Access

Internet UDP 13231 OFFICE (RB5009) wg0 10.99.0.1/24 LAN 192.168.88.0/24 Phone (4G) 10.99.0.10/32 Laptop (café) 10.99.0.11/32 BRANCH (hEX) wg0 10.99.0.2 LAN 192.168.20.0/24 one wg0 interface on OFFICE, three peers — road-warriors get a /32 each, the branch brings its whole LAN

WireGuard's entire configuration model is: an interface with a private key, and peers identified by public keys. No negotiation to debug — if the keys match and UDP arrives, it works; if either is false, it silently doesn't. That silence is the only hard part of WireGuard, and this post gives you the diagnosis path for it.

The concept that actually needs learning is allowed-address. It is two things at once: an inbound filter ("packets from this peer may claim these source IPs") and an outbound routing table ("packets to these IPs go to this peer"). Every confused WireGuard deployment we've untangled — handshake fine, no traffic — was a misunderstanding of that dual role. Get it right and both setups below are twenty minutes each. This is also the modern answer to the problem the Cisco series solves with GRE over IPsec — same overlay idea, a decade less ceremony.

Prerequisites

01

The Server Side — One Interface, Forever

The office router gets a wg0 interface, an address, a listening port, and a firewall rule. This part never changes again, no matter how many peers you add.

OFFICE router — interface + firewall, once
[admin@Office] > /interface/wireguard add name=wg0 listen-port=13231
# The private key generates itself. Grab the PUBLIC key — peers need it:
[admin@Office] > /interface/wireguard print
 0  name="wg0" listen-port=13231
    public-key="offApub4T8yQ0eVX2mKcR9sJ1uYw3zB5nH7dL6gF0iM="

# Address the tunnel — the office is .1 of the VPN subnet
[admin@Office] > /ip/address add address=10.99.0.1/24 interface=wg0

# Firewall (input chain, above the final drop):
#   1. let handshakes in from the internet, 2. treat tunnel traffic as trusted-ish
[admin@Office] > /ip/firewall/filter add chain=input action=accept protocol=udp dst-port=13231 comment="wireguard handshake" place-before=[find comment="drop all else"]
[admin@Office] > /interface/list/member add list=LAN interface=wg0
# Adding wg0 to the LAN list reuses every existing LAN permission —
# VPN users can now do whatever LAN users can. Scope tighter if they shouldn't.
💡 The Port Is Invisible Anyway

WireGuard doesn't respond to unauthenticated packets — a scanner probing UDP 13231 gets the same silence as a closed port. There's no banner, no handshake to fingerprint, nothing for Shodan to index. That's why the accept rule above is safe to leave open to the whole internet, and why WireGuard has no equivalent of the SSH brute-force problem the firewall post defends against: without a valid key, the service effectively isn't there.

02

Road Warriors — Phone and Laptop

Each device is a peer: its public key, its own /32 in the VPN subnet. The client config mirrors it back. Keys never travel — only public halves are exchanged.

OFFICE — one peer per device
# The phone generates its own keys in the WireGuard app; you copy its PUBLIC key
[admin@Office] > /interface/wireguard/peers add interface=wg0 name=phone-sp1r4 public-key="PhOnEpUb..." allowed-address=10.99.0.10/32
[admin@Office] > /interface/wireguard/peers add interface=wg0 name=laptop-sp1r4 public-key="LaPtOpPuB..." allowed-address=10.99.0.11/32

# allowed-address=/32 means: this peer may BE 10.99.0.10, and only that.
# A stolen laptop key can't impersonate the branch or another user.
Phone / laptop — the client side of the same conversation
[Interface]
PrivateKey = <generated on the device, never leaves it>
Address    = 10.99.0.10/32
DNS        = 192.168.88.1

[Peer]
PublicKey  = offApub4T8yQ0eVX2mKcR9sJ1uYw3zB5nH7dL6gF0iM=   ← office pubkey
Endpoint   = office.example.gr:13231
AllowedIPs = 192.168.88.0/24, 10.99.0.0/24   ← split tunnel: only work traffic
# AllowedIPs = 0.0.0.0/0                     ← full tunnel: EVERYTHING via office

Note the symmetry: on the client, AllowedIPs is the same dual-role field — it's what the phone will route into the tunnel. List the office subnets and you get a split tunnel (work traffic through the VPN, YouTube direct); list 0.0.0.0/0 and the device sends everything home — your traffic exits from the office IP, which is also the classic "trusted internet from hostile Wi-Fi" setup. For full-tunnel to actually work, the office router must also masquerade 10.99.0.0/24 out its WAN, exactly like any LAN subnet.

⚠ Gotcha — Handshake OK, Traffic Dead: It's Always allowed-address

The classic failure: last-handshake ticks happily, ping dies. Handshakes only prove keys and reachability; traffic has to pass both directions of the allowed-address check. Diagnosis in one line each: pinging LAN from the phone fails → the phone's AllowedIPs is missing the LAN subnet (it never routes the packet into the tunnel). LAN can't reach the phone → the router's peer entry is missing the phone's /32 (replies arrive but are dropped as "not allowed from this peer"). Every "WireGuard is up but nothing works" ticket is one of these two lines.

03

Site-to-Site — the Branch Office

Same machinery, bigger allowed-address: the branch peer brings its whole LAN. Add one static route each side and the two offices are one network.

Both routers — peers of each other
# BRANCH gets its own wg0 (10.99.0.2/24) as in section 01, then:
[admin@Branch] > /interface/wireguard/peers add interface=wg0 name=office public-key="offApub..." endpoint-address=office.example.gr endpoint-port=13231 allowed-address=10.99.0.0/24,192.168.88.0/24 persistent-keepalive=25s

# OFFICE adds the branch — note it brings a whole /24, no endpoint needed:
[admin@Office] > /interface/wireguard/peers add interface=wg0 name=branch public-key="BrAnChPuB..." allowed-address=10.99.0.2/32,192.168.20.0/24

# Routes: tell each router the other LAN lives across the tunnel
[admin@Office] > /ip/route add dst-address=192.168.20.0/24 gateway=wg0
[admin@Branch] > /ip/route add dst-address=192.168.88.0/24 gateway=wg0

# From a branch PC:
C:\> ping 192.168.88.10
Reply from 192.168.88.10: bytes=32 time=9ms TTL=126   ← two offices, one network
⚠ Gotcha — persistent-keepalive Is Mandatory Behind NAT

Only the branch dials out (it knows the office's endpoint; the office has none configured for the branch — it learns it from incoming packets). If the branch sits behind CGNAT or any home router, the NAT mapping expires after ~30–180 seconds of silence — and then the office can't initiate anything: packets to the branch die at a NAT that's forgotten the mapping. persistent-keepalive=25s keeps the hole open from the inside. Rule of thumb: the NAT'd/dynamic side sets the endpoint and the keepalive; the static side sets neither. Forget it and you get the maddening "works for a minute after the branch pings us, then goes deaf".

04

Verify and Diagnose Safe to Run

WireGuard fails silently by design — so you read counters, not error messages. Three numbers tell the whole story: last-handshake, rx, tx.

RouterOS — the three numbers
[admin@Office] > /interface/wireguard/peers print detail
 0  name="phone-sp1r4" interface=wg0 public-key="PhOnEpUb..."
    allowed-address=10.99.0.10/32
    current-endpoint-address=94.66.58.121 current-endpoint-port=41922
    last-handshake=14s rx=48.1MiB tx=512.3MiB
ReadingMeaning
no last-handshake everKeys mismatched (pubkeys swapped or re-generated), or UDP never arrives — check the endpoint DNS/port and the input rule.
handshake fresh, rx grows, tx ~0Their traffic reaches you; yours never enters the tunnel — your allowed-address/route for their subnets is missing.
handshake fresh, tx grows, rx ~0Mirror image — the far side isn't routing back, or drops your source as not-allowed.
handshake goes stale after minutesNAT mapping expired — set persistent-keepalive on the NAT'd side (section 03).
works, but large transfers stallMTU. wg0 defaults to 1420; on PPPoE or LTE underlays try 1380, and the overlay-MTU lesson from the GRE lab applies verbatim.
💡 Where This Sits Among the Platform's VPNs

For anything new on RouterOS 7, WireGuard should be the default: kernel-fast (it typically outruns IPsec on the same hardware), four commands per peer, and silent to scanners. Reach for IPsec/L2TP only when the far end can't speak WireGuard — a Cisco router (see the IKEv2 post), a corporate VPN concentrator, or built-in OS clients you can't install apps on. And since keys are the whole identity: the router's private key is in every binary backup — treat those files accordingly.

Takeaways

  1. WireGuard is an interface plus peers — no phases, no certificates. If keys match and UDP arrives, it works; the debugging surface is genuinely that small.
  2. allowed-address is a filter AND a routing table. Inbound: which source IPs a peer may use. Outbound: which destinations go to that peer. Almost every "handshake fine, no traffic" is this field.
  3. Road warriors get a /32 each; a site brings its LAN. The narrower the allowed-address, the less a stolen key is worth.
  4. Split vs full tunnel is one line on the client — office subnets for split, 0.0.0.0/0 (plus masquerade of the VPN subnet on the router) for everything-through-home.
  5. The NAT'd side sets endpoint + persistent-keepalive=25s; the static side sets neither. Forgetting the keepalive gives you a tunnel that goes deaf between conversations.
  6. Diagnose with three counters — last-handshake, rx, tx — and the table above; WireGuard never logs an error for you.
  7. Silent by design: no response without a valid key means no fingerprinting and no brute-force surface — safe to expose, unlike everything else on the input chain.

Want your sites and people on one secure network?

NOCTIS deploys WireGuard-based remote access and site-to-site links for businesses across Crete — phones, laptops, branch offices, and the villa NVR, each with least-privilege access and keys that rotate when staff do.

Book a Discovery Call →