Some simple instructions to create a WireGuard Site-to-Site VPN topology based on the below schema. The reason I am writing this, is for keeping it as notes because finding documentation on S2S topologies with wireguard is not the easiest thing.

wireguard-vpn

Private & Public keys

First we need to create the private and public key pair of each host. To do that with an one-liner, use the following command, after setting umask 077 in /etc/wireguard directory.

cd /etc/wireguard/
umask 077
wg genkey | tee private.key | wg pubkey > public.key

Configuring local wg0 interface

Now that we have the key pairs of each host, we can procceed to configure the wg0 interfaces. In /etc/wireguard/ directory, we create a wg0.conf file on each host with the info of the local wireguard interface wg0.

Host-A wg0.conf file:

# Host-A
[Interface]
PrivateKey=<Host-A-Private-key>
Address=192.168.250.1/30
ListenPort=51830

Host-B wg0.conf file:

# Host-B
[Interface]
PrivateKey=<Host-B-Private-key>
Address=192.168.250.2/30
ListenPort=51831

Configuring peer tunnels

Then we have to append on our wg0.conf files the configuration for each peer on both the hosts. So, the full wg0.conf file of Host-A will look like:

# Host-A
[Interface]
PrivateKey=<Host-A-Private-key>
Address=192.168.250.1/30
ListenPort=51830

[Peer]
# Name = Host-B
PublicKey = <Host-B-Public-key>
Endpoint = <Host-B-Public-IP>:51831
AllowedIPs = 192.168.250.0/30, 10.20.0.0/24

and the config file wg0.conf on Host-B will should look like:

# Host-B
[Interface]
PrivateKey=<Host-B-Private-key>
Address=192.168.250.2/30
ListenPort=51831

[Peer]
# Name = Host-A
PublicKey = <Host-A-Public-key>
Endpoint = <Host-A-Public-IP>:51831
AllowedIPs = 192.168.250.0/30, 10.10.0.0/24

Configuring host

If you are using a firewall, you have to open the neccessary ports on each host that WireGuard service is listening. For example in RHEL-based systems on Host-A:

firewall-cmd --add-port-51830/udp --permanent
firewall-cmd --reload

Also, ip-forwarding must be enabled so it can route traffic between subnets.

echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -p

Setting Up the tunnels

There are a lot of ways to brind up a WireGuard tunnel (eg. wg-quick command). I prefer to starting it as a service, and enabling it if I want the tunnel to always be up. So following this the commands to run on each host are:

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

Now if you force the tunnel with a ping request, the tunnel will initiate a handshake and start working. Execute a wg command to see relevant information about the wireguard VPN tunnels.

Note that some static routes, regarding the encryption domain are added to the route table. So traffic generated from Host-A LAN will be masquerated-NATed behind the wg0 IP address of Host-A. If you want you can remove the static route, and add another one with next hop the wg0 IP address of Host-B respectively, or just install FRR and run a dynamic protocol on top of Wireguard! ;)