Set Up WireGuard VPN on Ubuntu

Updated by Linode Contributed by Sunit Nandi

Contribute on GitHub

Report an Issue | View File | Edit File

Set Up WireGuard VPN on Ubuntu

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 wg0 and 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 ifconfig and ip.

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.

Do not use WireGuard for critical applications. The project is still undergoing security testing and is likely to receive frequent critical updates in the future.

Update Kernel

Wireguard requires using Ubuntu’s kernel rather than the Linode kernel. Follow these steps after creating your Linode:

  1. In the Linode Manager, open the configuration profile for your Linode and find the Boot Settings section. Select GRUB 2 as your kernel.

    Configuration Profile

  2. Boot your Linode, then connect to it with SSH and complete the standard setup procedure in our Getting Started guide.

  3. Update your system:

    sudo apt update && sudo apt upgrade
  4. Update the kernel:

    sudo apt install linux-image-virtual grub2
  5. Reboot your system from the Linode Manager.

  6. Install kernel headers:

    sudo apt install linux-headers-$(uname -r)

Install WireGuard

  1. Install software-properties-common:

    sudo apt install software-properties-common
  2. Add the Wireguard repository to your sources list:

    sudo add-apt-repository ppa:wireguard/wireguard
  3. 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:

    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/
    DKMS: install completed.
    Setting up wireguard-tools (0.0.20171111-wg1~xenial) ...
    Processing triggers for libc-bin (2.23-0ubuntu9) ...
    If the installation completes but this output does not appear, your kernel is most likely not configured correctly (to double check, the output of modprobe lsmod && lsmod | grep wireguard should not be blank). Refer to the previous section to troubleshoot.

Configure WireGuard Server

  1. 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 cat privatekey and cat publickey respectively.

  2. Open /etc/wireguard/wg0.conf in a text editor and add the following content, replacing <Private Key> with the generated private key:

    PrivateKey = <Private Key>
    Address =, 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 address block for IPv4 and the fd86:ea04:1115::0/64 block 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, iptables is 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

  1. Allow SSH connections and WireGuard’s VPN port:

    ufw allow 51820/udp
    ufw allow 22/tcp
    ufw enable
  2. Verify the settings:

    ufw status verbose

Start Wireguard Service

  1. Start Wireguard:

    wg-quick up wg0
    wg-quick is a convenient wrapper around many of the common functions in wg. You can turn off the wg0 interface with wg-quick down wg0
  2. Enable the Wireguard service to automatically restart on boot:

    systemctl enable wg-quick@wg0
  3. Check if the VPN tunnel is running:

    wg show
    ifconfig wg0

Wireguard Client

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.

  1. Generate a key pair for the client if you have not already:

    umask 077
    wg genkey | tee privatekey | wg pubkey > publickey
  2. The only difference between the client and server is the contents of the configuration file–the client’s wg0.conf must contain its IP addresses.

    PrivateKey = <Output of privatekey file that contains your private key>
    Address =, 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.

  1. The first method is to directly edit the client’s wg0.conf file with the server’s information:

    PublicKey = <Server Public key>
    Endpoint = <Server Public IP>:51820
    AllowedIPs =, fd86:ea04:1115::1/64

    Use the server’s public key, public IP address, and port.

  2. Enable the wg service:

    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.

  1. 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,fd86:ea04:1115::5/64
  2. 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:


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.

Next steps

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

Find answers, ask questions, and help others.

comments powered by Disqus

This guide is published under a CC BY-ND 4.0 license.