3 minutes
WireGuard Site to Site VPN
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.
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! ;)