This page is a tutorial on how to install wireguard on archlinux and add a connection between two clients. Also i made a systemd timer which reconfigures the interface in case the other side is no longer pingable. This is very useful in case you have a DNS but the IP changes regularly (this is because if you start the interface it resolved the DNS name to the IP, so it loses connection if the IP changes).

Installation

  • Install wireguard-tools and have linux version >= 5.6
    • In arch linux sudo pacman -S wireguard-tools
  • Client A is reachable via the internet

  • Client A run: (umask 0077; wg genkey | tee client_A.key | wg pubkey > client_A.pub)

    • Will generate a keypair
  • Client B run: (umask 0077; wg genkey | tee client_B.key | wg pubkey > client_B.pub)

  • Client A (Server) at /etc/wireguard/wg0.conf:

[Interface]
# ADDRESS_IN_CIDRS is f.ex: 10.10.0.1/32
Address = ADDRESS_IN_CIDR
PrivateKey = [content of client_A.key]
ListenPort = 51820

[Peer]
PublicKey = [content of client_B.pub]
# ADDRESS_IN_CIDR is the subnet which will be forwarded to client_B
# f.ex 10.10.0.2/32 (only the client will be addressable for clients in this network)
AllowedIPs = ADDRESS_IN_CIDR [, IPv6-ADDR]
PersistentKeepalive = 25
  • Client B at /etc/wireguard/wg0.conf:
[Interface]
# ADDRESS_IN_CIDR is Client_B's address. f.ex: 10.10.0.2/32
Address = ADDRESS_IN_CIDR
PrivateKey = [content of client_B.key]

[Peer]
PublicKey = [content of client_A.pub]
# line below is for all traffic over wireguard
# AllowedIPs = 0.0.0.0/0

# ADDRESS_IN_CIDRS is the subnet which will be forwarded to Client_A
# f.ex 10.10.0.0/24 for all other clients in this network 
AllowedIPs = ADDRESS_IN_CIDR [, IPv6-ADDR]
PersistentKeepalive = 25
Endpoint = IP_CLIENT_A:51820
  • Reminder Client_A needs the ListenPort to be open (enable in ufw: sudo ufw allow 51820)
  • Now it's possible to join the VPN with wg-quick up wg0 and leave with wg-quick down wg0 (run this command on both clients)
  • You can enable - to start this VPN automatically on boot - with systemctl enable wg-quick@wg0
    • to start it now: systemctl start wg-quick@wg0
  • Here's more information and configurations: https://wiki.archlinux.org/title/WireGuard

Ensure connection via periodic connectivity checks

In case your DNS name changes the connection will fail. To mitigate this it's possible to install a systemd timer which periodically tests connectivity (through pings) and restarts if the connection failed.

  • script at /etc/systemd/system/ensure_wg0.sh:
    • adjust IP_OF_SERVER to match another client that should always be online
#!/bin/sh

ping -4 -c 1 -q IP_OF_SERVER

ecode=$?

# if the error code is not 0 we simply tear down the interface and restart
if [ $ecode != 0 ]; then
    wg-quick down wg0
    wg-quick up wg0
fi

The service runs the script:

  • service at /etc/systemd/system/ensure_wg0.service:
[Unit]
Description=Checks if still connected to wg0

[Service]
Type=oneshot
ExecStart=bash /etc/systemd/system/ensure_wg0.sh

[Install]
WantedBy=basic.target
  • timer at /etc/systemd/system/ensure_wg0.timer:
    • Here you can tweak OnBootSec (seconds after booting) and OnUnitActiveSec
    • This example checks every 5 minutes the connectivity
[Unit]
Description=Checks if still connected to wg0

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target
  • Finally you can enable the timer with systemctl enable ensure_wg0.timer (only after next reboot)
  • And start it for this session with systemctl start ensure_wg0.timer