Arch Linux: WireGuard Peer for Connecting to MikroTik
0 (0)

By | 05/08/2026
Click to rate this post!
[Total: 0 Average: 0]

In the post MikroTik: setting up WireGuard and connecting Linux peers I described how to set up MikroTik as a VPN Hub and connect a peer running on Debian Linux.

Setup on Arch Linux is mostly the same as on Debian – but every time I end up digging through this blog and my other hosts to put together the right configs, so I’ll write it up separately to have everything in one place, plus there are a few nuances with DNS and NteworkManager.

What we need to do is install WireGuard, generate keys and a config file, and add a new Peer on MikroTik.

Installing WireGuard

Install the wireguard-tools package – it ships all the utilities plus a systemd unit to start WireGuard:

$ sudo pacman -S wireguard-tools

Generating keys

Create the /etc/wireguard/ directory and generate the private and public keys in it:

# mkdir /etc/wireguard/
# cd /etc/wireguard/
# wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey
0ClB2Lf5uQmWK8Nz0XRofuVkvbQbSfrf3ioHbYOm9F4=

Restrict read access on the private key to root only:

# chmod 600 /etc/wireguard/privatekey

Creating the WireGuard config

In /etc/wireguard/, create the file wg0.conf:

[Interface]
PrivateKey = qIU***W4=
Address = 10.100.0.10/32
DNS = 192.168.0.1, 10.100.0.1

[Peer]
PublicKey = hxz***0o=
Endpoint = 178.***.***.184:51820

AllowedIPs = 10.100.0.0/24,192.168.0.0/24,192.168.100.0/24
PersistentKeepalive = 25

Here:

  • [Interface]
    • PrivateKey: the private key on Arch Linux
    • Address: this Peer’s IP address, used for the local wg0 interface
  • [Peer]
    • PublicKey: the public key from MikroTik
    • Endpoint: the external address where MikroTik is reachable, and the port WireGuard listens on
    • AllowedIPs: which networks this peer can reach, and which routes will be created locally

On Arch Linux, grab the public key:

# cat /etc/wireguard/publickey 
0ClB2Lf5uQmWK8Nz0XRofuVkvbQbSfrf3ioHbYOm9F4=

Add the new Peer on MikroTik:

/interface wireguard peers add interface=wg0 public-key="0Cl***9F4=" allowed-address=10.100.0.10/32,192.168.0.0/24,192.168.100.0/24 comment=setevoy-office

Verify:

/interface wireguard peers print where comment="setevoy-office-new" 
Columns: INTERFACE, PUBLIC-KEY, ENDPOINT-PORT, ALLOWED-ADDRESS
# INTERFACE  PUBLIC-KEY                                    ENDPOINT-PORT  ALLOWED-ADDRESS 
;;; setevoy-office-new
5 wg0        0ClB2Lf5uQmWK8Nz0XRofuVkvbQbSfrf3ioHbYOm9F4=              0  10.100.0.10/32  
                                                                          192.168.0.0/24  
                                                                          192.168.100.0/24

We can connect now – but there might be a problem with resolvconf and /etc/resolv.conf.

WireGuard and the “resolvconf: signature mismatch: /etc/resolv.conf” error

On Arch Linux, bring up the connection:

# systemctl start wg-quick@wg0
Job for [email protected] failed because the control process exited with error code.
See "systemctl status [email protected]" and "journalctl -xeu [email protected]" for details.

Check the status:

# systemctl status [email protected]
× [email protected] - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/usr/lib/systemd/system/[email protected]; disabled; preset: disabled)
     Active: failed (Result: exit-code) since Fri 2026-05-08 08:57:47 EEST; 20s ago
...
May 08 08:57:47 setevoy-work wg-quick[1192596]: [#] wg addconf wg0 /dev/fd/63
May 08 08:57:47 setevoy-work wg-quick[1192596]: [#] ip -4 address add 10.100.0.10/32 dev wg0
May 08 08:57:47 setevoy-work wg-quick[1192596]: [#] ip link set mtu 1420 up dev wg0
May 08 08:57:47 setevoy-work wg-quick[1192644]: [#] resolvconf -a wg0 -m 0 -x
May 08 08:57:47 setevoy-work wg-quick[1192674]: resolvconf: signature mismatch: /etc/resolv.conf
May 08 08:57:47 setevoy-work wg-quick[1192674]: resolvconf: run `resolvconf -u` to update
May 08 08:57:47 setevoy-work wg-quick[1192596]: [#] ip link delete dev wg0
May 08 08:57:47 setevoy-work systemd[1]: [email protected]: Main process exited, code=exited, status=1/FAILURE

The problem is that the system has both openresolv and NetworkManager with the default dns=default – meaning NetworkManager writes /etc/resolv.conf directly, bypassing resolvconf.

Meanwhile, openresolv keeps its own checksum for /etc/resolv.conf in the file, and when NetworkManager rewrites it the checksum no longer matches, which is why resolvconf -a (called by wg-quick) fails with “signature mismatch“.

Option 1: PreUp and resolvconf -u (the “dirty hack”)

There’s a “dirty hack” – add a PreUp option to /etc/wireguard/wg0.conf that runs resolvconf -u:

[Interface]
PrivateKey = qIU***rW4=
Address = 10.100.0.10/32
DNS = 192.168.0.1, 10.100.0.1
PreUp = resolvconf -u

...

This works too, but if NetworkManager rewrites /etc/resolv.conf after the tunnel is already up (for example, on a Wi-Fi reconnect) – the DNS settings from the tunnel will be lost.

So a better approach is to switch NetworkManager to use systemd-resolved, so it doesn’t write /etc/resolv.conf directly at all.

Option 2: NetworkManager and systemd-resolved (the proper way)

Edit /etc/NetworkManager/NetworkManager.conf and add a [main] block with the dns option – see DNS management:

[main]
dns=systemd-resolved

Start systemd-resolved and restart NetworkManager:

# systemctl enable --now systemd-resolved && systemctl restart NetworkManager

Check the systemd-resolved status:

# resolvectl status
Global
           Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
    resolv.conf mode: foreign
  Current DNS Server: 10.100.0.1
         DNS Servers: 192.168.0.1 10.100.0.1
...

Check what’s in /etc/resolv.conf now:

# cat /etc/resolv.conf
# Generated by NetworkManager
nameserver 127.0.0.53
options edns0 trust-ad

127.0.0.53 is our local systemd-resolved:

# netstat -anp | grep 127.0.0.53
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      1221589/systemd-res 
udp        0      0 127.0.0.53:53           0.0.0.0:*                           1221589/systemd-res

Or with ss -lntup | grep 127.0.0.53 – but I’m used to netstat.

Option 3: pure openresolv (just in case)

An alternative is to set dns=none in NetworkManager: then NM doesn’t touch /etc/resolv.conf at all, and openresolv becomes the sole manager of the file – it merges entries from wg-quick and from NetworkManager connections directly into /etc/resolv.conf with the list of real DNS servers (192.168.0.1, 10.100.0.1, …).

With this setup systemd-resolved isn’t needed at all – DNS resolution goes directly through glibc: simpler config and fewer services – but we lose the goodies systemd-resolved brings: caching, split-DNS, DNSSEC.

Anyway, that’s it – start WireGuard:

# systemctl start wg-quick@wg0
# systemctl enable wg-quick@wg0

Check the status:

# wg show
interface: wg0
  public key: 0Cl***9F4=
  private key: (hidden)
  listening port: 47047

peer: hxz***50o=
  endpoint: 178.***.***.184:51820
  allowed ips: 10.100.0.0/24, 192.168.0.0/24, 192.168.100.0/24
  latest handshake: 20 seconds ago
  transfer: 12.06 KiB received, 8.13 KiB sent
  persistent keepalive: every 25 seconds

Check the connection to MikroTik through the VPN tunnel:

root@setevoy-work:/etc/wireguard # ssh [email protected]
...
[admin@mikrotik-rb4011-gw] > 

Done.

Loading