Jump toUpdate content

Setting up a private mesh VPN with WireGuard®
- mesh-VPN
- WireGuard
- multi-site
WireGuard - Overview
WireGuard is a modern VPN (Virtual Private Network) software. It is designed to be run almost anywhere, and to be cross-platform. Compared to other similar software, it is faster, more secure and simpler.
In this tutorial, we show how to use Wireguard to spin up a private mesh network to create a secure private connection between your different servers and Instances. A mesh network allows your devices to communicate between each other using a Virtual Private Network without the need for a central server:
We use two Instances, one located in the PAR-1
region, the other located in the AMS-1
region, and create a virtual network between them.
- You have an account and are logged into the Scaleway console
- You have configured your SSH Key
- You have two Instances running a Linux kernel ≥ 3.10.
Downloading and installing WireGuard
Log into each of your Instances using SSH:
ssh root@my.compute.instance.ip
Update and upgrade your system, install the kernel headers for your version and install WireGuard using
apt
:apt update && apt upgrade -y
apt install linux-headers-$(uname --kernel-release) # installs the right kernel headers for your version
apt install wireguardCheck that Wireguard is successfuly installed by running:
wg
. If you get no output, this indicates correct installation. In order to check that the WireGuard kernel module has loaded you can runmodprobe wireguard
. Depending on your system configuration, a reboot might be required to activate thewireguard
module.Generate the public and private keys for WireGuard:
cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
Configuring Wireguard manually
Smaller VPNs can be configured using the wg0.conf
configuration file of Wireguard. The following parameters are set in the configuration file:
192.168.1.1
is a randomly chosen private IP address for the VPN interface of the virtual Instances located inPAR-1
.192.168.1.2
is a randomly chosen private IP address for the VPN interface of the virtual Instances located inAMS-1
.- The
Endpoint
is the public IP address of every other instance. 52345
is a randomly chosen UDP port number used for the communication of the VPN.
On the first Instance
In this example we assume the Instance is located in the PAR-1
region.
Create the file /etc/wireguard/wg0.conf
with the following content. Replace the values in pointy brackets as necessary:
[Interface]
PrivateKey = <PAR-1-instance-private-key>
Address = 192.168.1.1
ListenPort = 52345
[Peer]
PublicKey = <AMS-1-instance-public-key>
AllowedIPs = 192.168.1.2
Endpoint = <AMS-1-instance-public-IP>:52345
On the second Instance:
In this example we assume the Instance is located in the AMS-1
region.
Create the file /etc/wireguard/wg0.conf
with the following content. Replace the values in pointy brackets as necessary:
[Interface]
PrivateKey = <AMS-1-instance-private-key>
Address = 192.168.1.2
ListenPort = 52345
[Peer]
PublicKey = <PAR-1-instance-public-key>
AllowedIPs = 192.168.1.1
Endpoint = <PAR-1-instance-public-IP>:52345
Enabling the Wireguard VPN
Enable and start Wireguard on both Instances using
systemctl
:systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0Test the VPN connection on each Instance using the
ping
command:root@PAR-1:~# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=2.87 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.992 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=1.37 ms
64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=1.21 ms
64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=1.57 ms
©64 bytes from 192.168.1.2: icmp_seq=6 ttl=64 time=1.43 ms
--- 192.168.1.2 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5008ms
rtt min/avg/max/mdev = 0.992/1.577/2.873/0.607 msroot@AMS-1:~# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.72 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.45 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=1.35 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=1.35 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=1.25 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=1.44 ms
--- 192.168.1.1 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5008ms
rtt min/avg/max/mdev = 1.257/1.429/1.724/0.148 msAs you can see, each Instance responds to the
ping
command of the other peer, indicating that the VPN connection is active.Tip:If you have problems with the ping, check the content of your
wg0.conf
files and then use the commandsystemctl restart wg-quick@wg0
You can now transfer data between your Instances over a secure private network connection.
Automatizing configuration generation
When managing a large number of machines in a WireGuard mesh network, configuring them manually can be time-consuming. Several projects facilitate the automatized generation of WireGuard configurations to manage your mesh networks with ease. We will use a python script called WireGuard Mesh Configurator to generate the configurations for our Instances.
You can carry out the following steps on your local machine, or any Instance:
Make sure
git
,python3-pip
, andpython3
are installed on your machine:apt install git python3-pip python3 libncurses-dev -y
Clone the GitHub repository of the configurator script:
git clone https://github.com/k4yt3x/wg-meshconf
Enter the script’s directory and install the requirements for it:
cd wg-meshconf
pip3 install -r requirements.txtLaunch the interactive WCG shell:
python3 wireguard_mesh_configurator.py int
Every profile created in the WireGuard Mesh Configurator (WCG) contains a complete network topology. Start by creating a new profile for the mesh network. Once a new profile is created, you will be prompted automatically to enroll new peers.
Type
new
in the WCG shell to launch the creation of a new profile:[WGC]> new
WireGuard Mesh Configurator 1.2.0
(C) 2018-2019 K4YT3X
Licensed under GNU GPL v3
[WGC]> new
[!] WARNING: This will flush the currently loaded profile!Type
add
to add a new peer and enter the details of the new peer:[WGC]> add
[?] USER: Address (leave empty if client only) [IP/CIDR]: 10.1.0.1/16
[?] USER: Public address (leave empty if client only) [IP|FQDN]: 1.1.1.1
[?] USER: Listen port (leave empty for client) [1-65535]: 7000
[?] USER: Private key (leave empty for auto generation):
[?] USER: Keep alive? [y/N]:
[?] USER: Alias (optional):
[?] USER: Description (optional):
[+] INFO: 10.1.0.1/16 information summary:
Address: 10.1.0.1/16
Public Address: 1.1.1.1
Listen Port: 7000
Private Key: 2JgqbhrtAiN1yZ5C3tjvlRwFWOrXflb3pKKhW/DJ3EI=Repeat these step for all peers in the mesh network.
Export everything into Wireguard configuration files, using the following command to generate the configuration files and dump them in the
/tmp/wg-conf
directory:[WGC]> gen /tmp/wg-conf
[WGC]> gen /tmp/wg-conf
[+] INFO: Generating configuration files
[?] USER: Output directory doesn't exist. Create output directory? [Y/n]:
2020-07-27 14:51:29.787508 [+] INFO: Generating configuration file for 10.1.0.1/16
gNNBi1eYUj5Wa6Qh21VvpEQhB9CFt4y6breHLhk49lo=
mFWz1E/ZLdavy8dz9pKPx58x7UBTwHpd61ZLxDjjFFU=
AEJ42t6rT/FxBq5MF1klzTZZrexh5qXvDUnnAU1njnY=
2020-07-27 14:51:29.802540 [+] INFO: Generating configuration file for 10.2.0.1/16
2JgqbhrtAiN1yZ5C3tjvlRwFWOrXflb3pKKhW/DJ3EI=
mFWz1E/ZLdavy8dz9pKPx58x7UBTwHpd61ZLxDjjFFU=
AEJ42t6rT/FxBq5MF1klzTZZrexh5qXvDUnnAU1njnY=
2020-07-27 14:51:29.817690 [+] INFO: Generating configuration file for 10.3.0.1/16
2JgqbhrtAiN1yZ5C3tjvlRwFWOrXflb3pKKhW/DJ3EI=
gNNBi1eYUj5Wa6Qh21VvpEQhB9CFt4y6breHLhk49lo=
AEJ42t6rT/FxBq5MF1klzTZZrexh5qXvDUnnAU1njnY=
2020-07-27 14:51:29.832823 [+] INFO: Generating configuration file for 10.4.0.1/16
2JgqbhrtAiN1yZ5C3tjvlRwFWOrXflb3pKKhW/DJ3EI=
gNNBi1eYUj5Wa6Qh21VvpEQhB9CFt4y6breHLhk49lo=
mFWz1E/ZLdavy8dz9pKPx58x7UBTwHpd61ZLxDjjFFU=Then exit WGC:
[WGC]> exit
[!] WARNING: ExitingCopy the created Wireguard configuration files to each Instance using any method you like (SFTP, FTPS, plain copy & paste, etc.). Make sure to store the configuration at
/etc/wireguard/wg0.conf
to be able to use thewg-quick
command for express configuration.SSH into each of the Instance peers and configure WireGuard. We use the
wg-quick
command to create an interface using our generated configuration and make it a service, so the interface will be configured aSticksutomatically duing system boot. Repeat these step on any of the peers.wg-quick up wg0
systemctl enable wg-quick@wg0
You have now successfully configured a mesh network using WireGuard which allows your Instances to communicate between themselves via a private and encrypted connection. As there is no central server, the network will continue to work if one of the peers fails.
For more information about WireGuard, refer to the official documentation.
“WireGuard” is a registered trademark of Jason A. Donenfeld.