Set Up WireGuard VPN on Ubuntu
Updated by Linode Contributed by Sunit Nandi
WireGuard is a simple, fast, and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster and leaner than other VPN protocols such as OpenVPN and IPSec, and has a much smaller source code footprint. WireGuard is still under development, but even in its unoptimized state it is faster than the popular OpenVPN protocol and delivers lower ping times in comparison.
The WireGuard configuration is as simple to configure as SSH. A connection is established by an exchange of public keys between server and client, and only a client with its public key present in its server configuration file is considered authorized. WireGuard sets up standard network interfaces (such as
wg1), which behave much like the commonly found
eth0 interface. This makes it possible to configure and manage WireGuard interfaces using standard tools such as
Currently, WireGuard is only available on Linux. This guide will configure a simple peer connection between a server, which will be a Linode running Ubuntu 16.04, and a client. The client can be either your local computer or another Linode.
CautionDo not use WireGuard for critical applications. The project is still undergoing security testing and is likely to receive frequent critical updates in the future.
Wireguard requires using Ubuntu’s kernel rather than the Linode kernel. Follow these steps after creating your Linode:
In the Linode Manager, open the configuration profile for your Linode and find the Boot Settings section. Select GRUB 2 as your kernel.
Boot your Linode, then connect to it with SSH and complete the standard setup procedure in our Getting Started guide.
Update your system:
sudo apt update && sudo apt upgrade
Update the kernel:
sudo apt install linux-image-virtual grub2
Reboot your system from the Linode Manager.
Install kernel headers:
sudo apt install linux-headers-$(uname -r)
sudo apt install software-properties-common
Add the Wireguard repository to your sources list:
sudo add-apt-repository ppa:wireguard/wireguard
Install Wireguard and its dependencies:
sudo apt update sudo apt install wireguard-dkms wireguard-tools
If the steps in the previous section were completed successfully, after the installation you will see the following console output:
wireguard: Running module version sanity check. - Original module - No original module exists within this kernel - Installation - Installing to /lib/modules/4.4.0-98-generic/updates/dkms/ depmod.... DKMS: install completed. Setting up wireguard-tools (0.0.20171111-wg1~xenial) ... Processing triggers for libc-bin (2.23-0ubuntu9) ...
NoteIf the installation completes but this output does not appear, your kernel is most likely not configured correctly (to double check, the output of
lsmod | grep wireguardshould not be blank). Refer to the previous section to troubleshoot.
Configure WireGuard Server
Generate a private and public key pair for the WireGuard server:
umask 077 wg genkey | tee privatekey | wg pubkey > publickey
This will save both the private and public keys to your home directory; they can be viewed with
/etc/wireguard/wg0.confin a text editor and add the following content, replacing
<Private Key>with the generated private key:
1 2 3 4 5 6 7
[Interface] PrivateKey = <Private Key> Address = 192.168.2.1/24, fd86:ea04:1115::1/64 ListenPort = 51820 PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE SaveConfig = true
Address defines the private IPv4 and IPv6 addresses for the WireGuard server. Each peer in the VPN network should have a unique value for this field. This guide will use the 192.168.2.0/24 address block for IPv4 and the
fd86:ea04:1115::0/64block for IPv6.
ListenPort specifies the port that WireGuard will use for incoming connections.
PostUp and PostDown set steps to be run after the interface is turned on or off, respectively. In this case,
iptablesis used to set Linux IP Masquerade rules to allow all the clients to share the server’s Internet IPv4 and IPv6 address, and clear the rules once the tunnel is down.
SaveConfig tells the config file to automatically update whenever a new peer is added while the service is running.
Set Up Firewall Rules
Allow SSH connections and WireGuard’s VPN port:
ufw allow 51820/udp ufw allow 22/tcp ufw enable
Verify the settings:
ufw status verbose
Start Wireguard Service
wg-quick up wg0
wg-quickis a convenient wrapper around many of the common functions in
wg. You can turn off the wg0 interface with
wg-quick down wg0
Enable the Wireguard service to automatically restart on boot:
systemctl enable wg-quick@wg0
Check if the VPN tunnel is running:
wg show ifconfig wg0
The process for setting up a client is essentially the same as the server. If your client uses Ubuntu, follow the instructions above. For other Linux distributions please refer to the WireGuard docs for installation instruction.
Generate a key pair for the client if you have not already:
umask 077 wg genkey | tee privatekey | wg pubkey > publickey
The only difference between the client and server is the contents of the configuration file–the client’s
wg0.confmust contain its IP addresses.
1 2 3
[Interface] PrivateKey = <Output of privatekey file that contains your private key> Address = 192.168.2.2/24, fd86:ea04:1115::5/64
Connect the Client and Server
There are two ways to add peer information to WireGuard; this guide will demonstrate both methods.
The first method is to directly edit the client’s
wg0.conffile with the server’s information:
1 2 3 4
[Peer] PublicKey = <Server Public key> Endpoint = <Server Public IP>:51820 AllowedIPs = 192.168.2.1/24, fd86:ea04:1115::1/64
Use the server’s public key, public IP address, and port.
wg-quick up wg0 systemctl enable wg-quick@wg0
The second way of adding peer information is through the command line. This information will be added to the config file automatically because of the SaveConfig option specified earlier.
Run the following command from the server, where the example IP addresses are those of the client:
wg set wg0 peer <Client Public Key> endpoint <Client IP address>:51820 allowed-ips 192.168.2.2/24,fd86:ea04:1115::5/64
Verify the connection:
Regardless of which method you choose, there will be a Peer section in the output of this command if the setup was successful. This Peer section will be automatically added to
wg0.conf when the service is restarted. If you would like to add this information immediately to the config file, you can run:
wg-quick save wg0
Additional clients can be added using the same procedure.
Test the Connection
Return to the client and ping the server:
ping 192.168.2.1 wg
The last two lines of the output of wg should be similar to:
latest handshake: 1 minute, 17 seconds ago transfer: 98.86 KiB received, 43.08 KiB sent
This indicates that you now have a private connection between the server and client. You can also ping the client from the server to verify that the connection works both ways.
The process used in this guide can be extended to configure network topologies. As mentioned previously, Wireguard is an evolving technology. If you use WireGuard, you should monitor the official documentation and todo list for critical updates and new/upcoming features.
Join our Community
This guide is published under a CC BY-ND 4.0 license.