WireGuard landed in RouterOS 7 as a native kernel interface, and it immediately made every other VPN option on MikroTik feel dated. No phase 1/phase 2 negotiation, no certificate ceremony, no proposal mismatch debugging at 2 AM. A keypair, a peer entry, a firewall rule — done.
But the simplicity is deceptive in one specific place: allowed-address. It is not a firewall setting. It is simultaneously a routing directive and a cryptographic ACL, and misunderstanding it accounts for nearly every “handshake works but no traffic” ticket I’ve seen. Get allowed-address right and WireGuard on RouterOS is boring. Get it wrong and you’ll chase ghosts.
I covered the VyOS side of this in the VyOS Guide — the concepts transfer one-to-one, only the syntax changes. RouterOS actually goes one step further with peer parameters that generate client configs for you.
The Interface
WireGuard lives under /interface/wireguard in RouterOS 7. Creating the interface generates a keypair automatically:
/interface/wireguardadd name=wg-rw listen-port=13231
# The private key stays on the router; grab the public key for clients/interface/wireguard print detailThe public-key field in the print output is what you hand to peers. You never need to see the private key, and you shouldn’t export it anywhere.
Defaults worth knowing: listen-port defaults to 13231 (MikroTik’s convention, not the upstream 51820 — pick either, just be consistent), and MTU defaults to 1420, which is the correct value for WireGuard over standard 1500-byte Ethernet. More on that later.
Give the interface an address like any other:
/ip addressadd address=10.20.30.1/24 interface=wg-rw comment="WireGuard road-warrior subnet"Road-Warrior Setup
One router, many roaming clients. Each client is a peer with a /32 allowed-address:
/interface/wireguard/peersadd interface=wg-rw name=laptop public-key="LAPTOP_PUBLIC_KEY_BASE64=" \ allowed-address=10.20.30.10/32 comment="Berik laptop"
add interface=wg-rw name=phone public-key="PHONE_PUBLIC_KEY_BASE64=" \ allowed-address=10.20.30.11/32 comment="Berik phone"No endpoint on the server side — road warriors connect from unknown addresses, and WireGuard learns the endpoint from the first authenticated handshake. That’s the roaming magic: switch from Wi-Fi to LTE and the tunnel follows without renegotiation.
Let RouterOS Generate the Client Config
This is the part MikroTik did better than most. Peer entries accept client-* parameters that describe the remote side, and WinBox/WebFig will render a ready-to-import config file and QR code:
/interface/wireguard/peersadd interface=wg-rw name=tablet public-key="" private-key=auto \ allowed-address=10.20.30.12/32 \ client-address=10.20.30.12/32 \ client-dns=10.0.10.1 \ client-endpoint=vpn.example.com \ client-listen-port=13231 \ client-keepalive=25sWith private-key=auto, RouterOS generates the client’s keypair, fills in the public key, and produces the full client config — scan the QR from your phone’s WireGuard app and you’re connected. The trade-off: the router briefly knows the client’s private key. For a homelab, fine. For anything with a compliance story, generate keys on the client and paste only the public key.
Firewall
Two things need to pass: the WireGuard UDP port on input, and the tunnel traffic itself.
/ip firewall filter# Allow handshakes from the internetadd chain=input action=accept protocol=udp dst-port=13231 \ comment="WireGuard handshake"
# Allow VPN clients into the LAN (place before your forward drop rule)add chain=forward action=accept in-interface=wg-rw out-interface-list=LAN \ comment="WireGuard clients to LAN"If clients should reach the internet through the tunnel (full tunnel), your existing masquerade rule on the WAN interface covers them as long as it matches out-interface-list=WAN rather than a source subnet. If it matches on source, add 10.20.30.0/24.
Site-to-Site
Two routers, HQ (10.0.10.0/24) and branch (10.0.20.0/24), transfer network 10.255.255.0/30.
HQ:
/interface/wireguardadd name=wg-branch listen-port=13232
/ip addressadd address=10.255.255.1/30 interface=wg-branch
/interface/wireguard/peersadd interface=wg-branch name=branch public-key="BRANCH_PUBLIC_KEY=" \ endpoint-address=branch.example.com endpoint-port=13232 \ allowed-address=10.255.255.2/32,10.0.20.0/24 \ persistent-keepalive=25s
/ip routeadd dst-address=10.0.20.0/24 gateway=wg-branch comment="Branch LAN via WireGuard"Branch mirrors it with swapped keys, addresses, and allowed-address=10.255.255.1/32,10.0.10.0/24. If the branch sits behind CGNAT and can’t accept inbound handshakes, set responder=yes on the HQ peer entry — it tells RouterOS this peer only answers, never initiates, and the branch does all the dialing.
Allowed-Address Discipline
This is the section to internalize. allowed-address does two jobs at once:
- Outbound (routing): a packet routed into the WireGuard interface is encrypted to the peer whose allowed-address matches the destination. It’s a routing table inside the interface.
- Inbound (crypto ACL): a decrypted packet is accepted only if its source address matches the sending peer’s allowed-address. Anything else is silently dropped.
The consequences:
- Handshake up, traffic dead, no log entries — the classic symptom of a source address arriving that isn’t in allowed-address. WireGuard drops it before the firewall ever sees it, so
/logand torch on the wg interface show nothing inbound. - Overlapping allowed-addresses don’t merge — only one peer can own a given prefix per interface. If two peers claim 0.0.0.0/0, the last one wins and the other breaks.
- allowed-address is not the same as the route. On RouterOS you still add the
/ip routefor site-to-site — allowed-address permits the traffic, the route sends it there. VyOS behaves the same way; neither system auto-installs routes from allowed-ips the waywg-quickdoes on Linux.
Rule of thumb: allowed-address = “which source IPs am I willing to believe this peer speaks for.” A road warrior speaks for its own /32. A branch router speaks for its tunnel IP plus everything behind it.
MTU and Keepalives
WireGuard adds 60 bytes of overhead on IPv4 (80 on IPv6). RouterOS defaults the interface to 1420, which is right for a 1500 path. If your WAN is PPPoE (1492) or the path crosses another tunnel, go lower:
/interface/wireguard set wg-branch mtu=1412Symptoms of MTU too high are always the same: ping works, SSH works, HTTPS stalls on large responses. Test the path properly:
/ping 10.0.20.1 size=1420 do-not-fragment# largest size that succeeds = your usable MTU (size includes headers here)persistent-keepalive matters whenever a peer sits behind NAT or a stateful firewall. WireGuard is silent when idle; NAT mappings expire in 30–60 seconds; then the server can no longer reach the client until the client sends something. persistent-keepalive=25s on the NATed side keeps the mapping alive. Skip it only when both ends have static public IPs — it’s wasted battery on mobile clients otherwise… except mobile clients are exactly the ones behind NAT. In practice: road warriors set it client-side, site-to-site sets it on whichever router is behind NAT.
Verification
Handshake state is the first thing to check:
/interface/wireguard/peers print detail# look at last-handshake — anything under 2 minutes means the tunnel is alive# rx / tx counters tell you whether data actually flows both wayslast-handshake of “never” means the handshake itself fails: wrong key, wrong endpoint, or blocked UDP port. A recent handshake with rx increasing but the client seeing nothing means return traffic dies — check allowed-address on the client and NAT/routes on the router.
Watch live traffic:
/tool torch interface=wg-rw/tool sniffer quick interface=ether1 port=13231The sniffer on the WAN interface proves handshake packets arrive at all — if you see nothing on UDP 13231, the problem is upstream (port forward, ISP filtering), not WireGuard.
RouterOS vs VyOS, Briefly
Same kernel implementation, different ergonomics. VyOS models peers as children of the interface in one config tree; RouterOS splits interface and peers into two menus, which feels clumsy until you script it. RouterOS wins on client onboarding — the client-* parameters and QR export have no VyOS equivalent, where you template client configs yourself. VyOS wins on config review: one show interfaces wireguard diff versus assembling state from two RouterOS menus. Both need explicit routes for site-to-site, both default sensibly on MTU. If you run both (I do), keep a naming convention for peers and the mental model transfers cleanly.
Closing Thoughts
WireGuard on RouterOS 7 is the rare feature that’s both simpler and more capable than what it replaces. The checklist that keeps it boring:
- allowed-address is a crypto ACL and a routing directive — every “no traffic” mystery starts here
- MTU 1420 for plain Ethernet paths, lower for PPPoE or nested tunnels
- keepalive 25s on any NATed peer, skip it otherwise
responder=yesfor peers that can’t receive handshakes- verify with
peers print detail— last-handshake and rx/tx tell you which half of the conversation is broken
Next up in the series: IKEv2, for the clients where you can’t install WireGuard and have to meet the OS where it lives.