WireGuard
WireGuard is a simple, fast, and modern VPN that uses state-of-the-art cryptography. It aims to be faster, simpler, and leaner than IPsec, and considerably more performant than OpenVPN. WireGuard is a general-purpose VPN designed for embedded interfaces and supercomputers alike, fit for many different circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable.
vrf parameter in WireGuard context
The vrf parameter does not apply to the WireGuard interface itself (e.g., wg0, wg1), but rather to the UDP socket used for transporting encrypted packets.
There are two distinct layers in WireGuard operation:
- WireGuard interface — this is the virtual network device through which plain (unencrypted) packets flow. These packets are encrypted and sent out through the UDP socket, or decrypted when they come in from it.
- UDP sockets — these handle the encrypted traffic: receiving encrypted packets from the network and sending encrypted packets out.
The vrf parameter is relevant to the UDP socket layer (case 2). It specifies which routing table (VRF) the socket should use to determine how encrypted packets are sent or received.
This ensures that encrypted traffic follows the correct routing path and uses the proper source IP, preventing issues where packets might otherwise go out through the wrong interface or route.
Example
Suppose interface
eth1belongs to VRFfoo.
If you want WireGuard to send and receive encrypted packets througheth1, configure WireGuard withvrf=foo.
It is normal for the WireGuard interface (wg0) itself to be in a different VRF than the one specified by thevrfparameter used by the internal UDP socket.
Importing and Exporting WireGuard
Configuration can be done in various ways. Here is a simple WireGuard import file example: export
Minimum parameters must be specified for importing on the client device by QR code or file. If the client address field is left empty, the default IP address 192.168.177.2/24 is added when the QR code is generated.
Example:
interface: wireguard1
public-key: v/oIzPyFm1FPHrqhytZgsKjU7mUToQHLrW+Tb5e601M=
private-key: KMwxqe/iXAU8Jn9dd1o5pPdHep2blGxNWm9I944/I24=
allowed-address: 192.168.88.3/24
client-address: 192.168.88.3/32
client-endpoint: example.com:13231
When importing with /interface/wireguard/wg-import file=, you may get a Could not parse error if the WireGuard import file starts with #.
Use a clean format as in the following example:
[Interface]
Address =192.168.88.3/24
ListenPort = 13533
PrivateKey = UBLqJEFZZf9wszZSUF2BPWa9dsMX99RbEcxlNfxWffk=
It is possible to import configuration with config-string parameter:
/interface/wireguard/wg-import config-string="
[Interface]
Address =192.168.88.3/24
ListenPort = 13533
PrivateKey = UBLqJEFZZf9wszZSUF2BPWa9dsMX99RbEcxlNfxWffk=
[Peer]
PublicKey = EoF7HlFu3fbOnuYbyGqLMJkPZgQk9n3WwONZuJZ6qWc=
Endpoint = 199.168.100.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25"
When you encounter issues with reply traffic having the wrong source address, translating packet source addresses to your loopback interface with NAT is a common workaround. This approach helps ensure the source address is consistent and correct when packets are routed back through the network.
The "AllowedIPs" configuration provided to the client through the WireGuard peer export (configuration file or QR code) cannot be changed and is set to "0.0.0.0/0, ::/0". If you need to modify these values on the remote end, this must be done through the remote peer software used for the WireGuard connection. Support has been added from version 7.21.
Application examples
Site to Site WireGuard tunnel
Consider the setup illustrated below. Two remote office routers are connected to the internet and office workstations are behind NAT. Each office has its own local subnet, 10.1.202.0/24 for Office1 and 10.1.101.0/24 for Office2. Both remote offices need secure tunnels to local networks behind routers.

WireGuard interface configuration
First, configure WireGuard interfaces on both sites to allow automatic private and public key generation. The command is the same for both routers:
/interface/wireguard
add listen-port=13231 name=wireguard1
Now when printing the interface details, both private and public keys should be visible to allow an exchange.
Warning A private key is never needed on the remote side device — hence the name private.
Office1
/interface/wireguard/print
Flags: X - disabled; R - running
0 R name="wireguard1" mtu=1420 listen-port=13231 private-key="yKt9NJ4e5qlaSgh48WnPCDCEkDmq+VsBTt/DDEBWfEo="
public-key="u7gYAg5tkioJDcm3hyS7pm79eADKPs/ZUGON6/fF3iI="
Office2
/interface/wireguard/print
Flags: X - disabled; R - running
0 R name="wireguard1" mtu=1420 listen-port=13231 private-key="KMwxqe/iXAU8Jn9dd1o5pPdHep2blGxNWm9I944/I24="
public-key="v/oIzPyFm1FPHrqhytZgsKjU7mUToQHLrW+Tb5e601M="
Peer configuration
Peer configuration defines who can use the WireGuard interface and what kind of traffic can be sent over it. To identify the remote peer, its public key must be specified together with the created WireGuard interface.
Office1
/interface/wireguard/peers
add allowed-address=10.1.101.0/24,10.255.255.2/32 endpoint-address=192.168.80.1 endpoint-port=13231 interface=wireguard1 \
public-key="v/oIzPyFm1FPHrqhytZgsKjU7mUToQHLrW+Tb5e601M="
Office2
/interface/wireguard/peers
add allowed-address=10.1.202.0/24,10.255.255.1/32 endpoint-address=192.168.90.1 endpoint-port=13231 interface=wireguard1 \
public-key="u7gYAg5tkioJDcm3hyS7pm79eADKPs/ZUGON6/fF3iI="
IP and routing configuration
Lastly, IP and routing information must be configured to allow traffic to be sent over the tunnel.
Office1
/ip/address
add address=10.255.255.1/30 interface=wireguard1
/ip/route
add dst-address=10.1.101.0/24 gateway=wireguard1
Office2
/ip/address
add address=10.255.255.2/30 interface=wireguard1
/ip/route
add dst-address=10.1.202.0/24 gateway=wireguard1
Firewall considerations
The default RouterOS firewall blocks the tunnel from establishing properly. The traffic must be accepted in the "input" chain before any drop rules on both sites.
Office1
/ip/firewall/filter
add action=accept chain=input dst-port=13231 protocol=udp src-address=192.168.80.1
Office2
/ip/firewall/filter
add action=accept chain=input dst-port=13231 protocol=udp src-address=192.168.90.1
The "forward" chain can also restrict communication between the subnets, so such traffic should also be accepted before any drop rules.
Office1
/ip/firewall/filter
add action=accept chain=forward dst-address=10.1.202.0/24 src-address=10.1.101.0/24
add action=accept chain=forward dst-address=10.1.101.0/24 src-address=10.1.202.0/24
Office2
/ip/firewall/filter
add action=accept chain=forward dst-address=10.1.101.0/24 src-address=10.1.202.0/24
add action=accept chain=forward dst-address=10.1.202.0/24 src-address=10.1.101.0/24
RoadWarrior WireGuard tunnel
RouterOS configuration
Add a new WireGuard interface and assign an IP address to it.
/interface/wireguard
add listen-port=13231 name=wireguard1
/ip/address
add address=192.168.100.1/24 interface=wireguard1
Adding a new WireGuard interface automatically generates a pair of private and public keys. Configure the public key on your remote devices. To obtain the public key value, print the interface details.
[admin@home] > /interface/wireguard/print
Flags: X - disabled; R - running
0 R name="wireguard1" mtu=1420 listen-port=13231 private-key="cBPD6JNvbEQr73gJ7NmwepSrSPK3np381AWGvBk/QkU="
public-key="VmGMh+cwPdb8//NOhuf1i1VIThypkMQrKAO9Y55ghG8="
For the next steps, obtain the public key of the remote device. Once you have it, add a new peer by specifying the public key of the remote device and allowed addresses that will be allowed over the WireGuard tunnel.
/interface/wireguard/peers
add allowed-address=192.168.100.2/32 interface=wireguard1 public-key="<paste public key from remote device here>"
Firewall considerations
If you have a default or strict firewall configured, you need to allow a remote device to establish the WireGuard connection to your device.
/ip/firewall/filter
add action=accept chain=input comment="allow WireGuard" dst-port=13231 protocol=udp place-before=1
To allow remote devices to connect to the RouterOS services (e.g. request DNS), allow the WireGuard subnet in the input chain.
/ip/firewall/filter
add action=accept chain=input comment="allow WireGuard traffic" src-address=192.168.100.0/24 place-before=1
Or simply add the WireGuard interface to the "LAN" interface list.
/interface/list/member
add interface=wireguard1 list=LAN
iOS configuration
Download the WireGuard application from the App Store. Open it up and create a new configuration from scratch.

First, give your connection a "Name" and choose to generate a keypair. The generated public key is necessary for the peer configuration on the RouterOS side.

Specify an IP address in the "Addresses" field that is in the same subnet as configured on the server side. This address is used for communication. For this example, the RouterOS side uses 192.168.100.1/24. You can use 192.168.100.2 here.
If necessary, configure the DNS servers. If allow-remote-requests is set to yes under the IP/DNS section on the RouterOS side, you can specify the remote WireGuard IP address here.

Select "Add peer" to reveal more parameters.
The "Public key" value is the public key value that is generated on the WireGuard interface on the RouterOS side.
"Endpoint" is the IP or DNS with a port number of the RouterOS device that the iOS device can communicate with over the Internet.
"Allowed IPs" are set to 0.0.0.0/0 to allow all traffic to be sent over the WireGuard tunnel.

Depending on your configuration, you may need to add a NAT rule
chain=dstnat action=dst-nat to-ports=port protocol=udp in-interface=interface dst-port=port
Windows 10 configuration
Download the WireGuard installer from WireGuard and run it as Administrator.

Press <kbd>Control</kbd>+<kbd>N</kbd> to add a new empty tunnel. Add a name for the interface — the public key should be auto-generated. Copy it to the RouterOS peer configuration.
Add it to the server configuration. The full configuration should look like this (keep your auto-generated PrivateKey in the [Interface] section):
[Interface]
PrivateKey = your_autogenerated_private_key=
Address = 192.168.100.2/24
DNS = 192.168.100.1
[Peer]
PublicKey = your_MikroTik_public_KEY=
AllowedIPs = 0.0.0.0/0
Endpoint = example.com:13231
Save and Activate
Multi-WAN setup
For WireGuard there is no server-client relationship. Both ends can serve as an endpoint and both ends stream UDP handshake messages to each other if they have endpoints defined in their configurations. You can enable the "responder" option in the peer settings to emulate server-client behavior, where the "server" peer only replies to handshake messages from "client" peers and does not stream handshake messages by itself.
Because of this tunnel establishment behavior, handshake messages from different endpoints of the WireGuard tunnel are treated as two separate connections.
You need to account for this in setups with multiple paths to the "client" peer, as this can cause the "server" to reply to the "client" through a different route instead of the incoming route.
Below is a configuration example that addresses this behavior and ensures the "server" uses the incoming route to reply to the "client".
Configuration example
This example does not include WireGuard interface configuration as it is applicable to both RoadWarrior and Site to Site setups with two WAN connections such as PCC setup.
For these rules to work as intended, you need to enable the "responder" option in WireGuard peer settings, as the "server" could send handshakes via the incorrect interface because routing was not marked.
/ip/firewall/mangle
add action=add-src-to-address-list chain=prerouting address-list=WAN2_WireGuard_clients address-list-timeout=1m dst-port=13231 in-interface=ether2 protocol=udp comment="add source IP address of WAN2 incoming WireGuard traffic to address list"
add action=mark-connection chain=output dst-address-list=WAN2_WireGuard_clients dst-port=13231 new-connection-mark=wan2 protocol=udp comment="mark WireGuard connection to the client peer by checking destination address from the address list"
add action=mark-routing chain=output connection-mark=wan2 dst-port=13231 new-routing-mark=wan2 protocol=udp comment="ensure that WireGuard traffic uses routing table associated with the WAN2 incoming interface"
add action=add-src-to-address-list chain=prerouting address-list=WAN3_WireGuard_clients address-list-timeout=1m dst-port=13231 in-interface=ether3 protocol=udp comment="add source IP address of WAN3 incoming WireGuard traffic to address list"
add action=mark-connection chain=output dst-address-list=WAN3_WireGuard_clients dst-port=13231 new-connection-mark=wan3 protocol=udp comment="mark WireGuard connection to the client peer by checking destination address from the address list"
add action=mark-routing chain=output connection-mark=wan3 dst-port=13231 new-routing-mark=wan3 protocol=udp comment="ensure that WireGuard traffic uses routing table associated with the WAN3 incoming interface"
/ip/firewall/nat
add action=masquerade chain=srcnat log=yes out-interface=ether2 comment="ensure that packet has source IP of WAN2 interface"
add action=masquerade chain=srcnat log=yes out-interface=ether3 comment="ensure that packet has source IP of WAN3 interface"
The first mangle rule catches the source IP address by matching the destination port of the incoming WireGuard handshake and adds it to the list, which is later used to mark the outgoing WireGuard handshake. The timeout ensures that the same source IP address can later establish a WireGuard tunnel through a different WAN interface.
The second mangle rule marks connections that are used for routing marks and ensures the mark stays on the connection after the IP address is gone from the address list and the tunnel is established.
The third mangle rule forces the packet to use the correct routing table for the second WAN interface.
The last NAT rule ensures the packet is sent out with the correct source IP, as it is not adjusted by the mangle rules. Without this rule, the packet could have a different source IP depending on the setup.
The rules are duplicated for WAN3 to ensure the WAN3 interface is also usable with WireGuard.
This rule set ensures the WireGuard tunnel is established on the interface that received the incoming handshake.
2FA setup
HotSpot services can be bound to WireGuard interfaces in RouterOS v7. This allows administrators to combine WireGuard's high-performance encryption with the HotSpot's captive portal features, supporting additional user-level authentication through a local database, User Manager, or RADIUS. The OTP feature strengthens security further.
Configuration example
Make sure the WireGuard interface is configured on your device:
/interface/wireguard> print
Flags: X - DISABLED; R - RUNNING
0 R name="wg1" mtu=1420 listen-port=49422
public-key="MikroTikMikroTikMikroTik="
Set up HotSpot on the WireGuard interface:
/ip/hotspot> setup
Select interface to run HotSpot on
hotspot interface: wg1
or
/ip/hotspot/add interface=wg1
*Supported from 7.22
After HotSpot setup, once a WireGuard peer is connected, an additional login to the portal is required to proceed. Regular HotSpot username/password authorization can be used. For better security, use /ip/hotspot/user otp-password or /user-manager/user totp-password field. Add a user with totp-secret:
/ip/hotspot/user/add name=peer1 totp-secret=HVR4CFHAFOWFGGFAGSA5JVTIMMPG6GMT
You can find multiple open-source totp generator tools that can provide you with an appropriate key and necessary options to import it into your "authenticator" app.
After setup is complete, launch WireGuard on your device. After successful authorization by the WireGuard/HotSpot server, the HotSpot login page appears and you must enter the HotSpot username and a TOTP 6-symbol password (which changes every 30 seconds) from the authenticator app.
You should use an HTTPS login page for HotSpot and make sure the WireGuard peer can verify the login page certificate.