Ubuntu 20.04 set up WireGuard VPN server

How can I install and set up WireGuard VPN server on an Ubuntu 20.4 LTS Linux server? How do I configure Ubuntu 20.04 as the WireGuard VPN server?

WireGuard is an open-source, free, modern, and fast VPN with state-of-the-art cryptography. It is quicker and simpler as compared to IPSec and OpenVPN. Originally, released for the Linux kernel, but it is getting cross-platform support for other operating systems too. This page explains how to install and set up WireGuard VPN on Ubuntu 20.04 LTS Linux server.
Tutorial requirements
Operating system/appUbuntu 20.04 LTS with WireGuard
Root privileges required Yes
Difficulty Easy (rss)
Estimated completion time 10m
Table of contents

Procedure: Ubuntu 20.04 set up WireGuard VPN server

Our sample setup includes a simple peer connection between a cloud server running Ubuntu 20.04 LTS server, and a Ubuntu/Ubuntu/RHEL/SUSE/OpenSUSECentOS Linux desktop client:

The steps are as follows for installing and configuring WireGuard on Ubuntu Linux 20.04 LTS as a VPN server.

Please note that {vivek@ln-sg-vpn-001:~ }$ OR {vivek@ubuntu-20-4-vpn-client:~ }$ is my shell prompt and is not part of actual commands. In other words, you need to copy and paste command after my shell prompt.

Step 1 – Update your system

Run the apt command to install Ubuntu 20.04 security updates:
{vivek@ln-sg-vpn-001:~ }$ sudo apt update
{vivek@ln-sg-vpn-001:~ }$ sudo apt upgrade

Step 2 – Installing a WireGuard VPN server on Ubuntu 20.04 LTS

Now we got our server updates with the latest security patches. It is time for setting up a WireGuard VPN server on Ubuntu 20.04 server. Enter:
{vivek@ln-sg-vpn-001:~ }$ sudo apt install wireguard

Step 3 – Configuring WireGuard server

First we need to create a private and public key pair for the WireGuard server. Let us cd into /etc/wireguard using the cd command {vivek@ln-sg-vpn-001:~ }$ sudo -i
{root@ln-sg-vpn-001:~ }# cd /etc/wireguard/

Execute the following command:
{vivek@ln-sg-vpn-001:~ }# umask 077; wg genkey | tee privatekey | wg pubkey > publickey
To view keys created use the cat command and ls command:
{vivek@ln-sg-vpn-001:~ }# ls -l privatekey publickey
{vivek@ln-sg-vpn-001:~ }# cat privatekey
## Please note down the private key ##
{vivek@ln-sg-vpn-001:~ }# cat publickey

Set Up WireGuard VPN on Ubuntu by Editing wg0.conf

Edit or update the /etc/wireguard/wg0.conf file as follows:
{vivek@ln-sg-vpn-001:~ }$ sudo nano /etc/wireguard/wg0.conf
## OR ##
{vivek@ln-sg-vpn-001:~ }$ sudo vim /etc/wireguard/wg0.conf

Append the following config directives:

## Set Up WireGuard VPN on Ubuntu By Editing/Creating wg0.conf File ##
## My VPN server private IP address ##
Address =
## My VPN server port ##
ListenPort = 41194
## VPN server's private key i.e. /etc/wireguard/privatekey ##
PrivateKey = eEvqkSJVw/7cGUEcJXmeHiNFDLBGOz8GpScshecvNHU=

Save and close the file when using vim text editor.

Step 4 – Set up UFW firewall rules to open requred ports

I am assuming that you have UFW configured and we are going to open UDP 41194 port using the ufw command as follows:
{vivek@ln-sg-vpn-001:~ }$ sudo ufw allow 41194/udp
Verify it:
{vivek@ln-sg-vpn-001:~ }$ sudo ufw status
See “How To Configure Firewall with UFW on Ubuntu 20.04 LTS” for more info.

Step 5 – Enable and start WireGuard service

Turn the WireGuard service at boot time using the systemctl command, run:
{vivek@ln-sg-vpn-001:~ }$ sudo systemctl enable wg-quick@wg0
Start the service, execute:
{vivek@ln-sg-vpn-001:~ }$ sudo systemctl start wg-quick@wg0
Get the service status, run:
{vivek@ln-sg-vpn-001:~ }$ sudo systemctl status wg-quick@wg0

Verify that interface named wg0 is up and running on Ubuntu server using the ip command:
{vivek@ln-sg-vpn-001:~ }$ sudo wg
{vivek@ln-sg-vpn-001:~ }$ sudo ip a show wg0

Step 6 – Wireguard VPN client configuration

The procedure for installing and configuring a VPN client is the same as setting up the server. Let us install the client on an Ubuntu Linux 20.04 LTS desktop:
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo apt install wireguard
Next we need create VPN client config on Ubuntu/Debian/CentOS Linux destkop:
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo -i
{root@ubuntu-20-4-vpn-client:~ }# cd /etc/wireguard/
{root@ubuntu-20-4-vpn-client:~ }# umask 077; wg genkey | tee privatekey | wg pubkey > publickey
{root@ubuntu-20-4-vpn-client:~ }# ls -l publickey privatekey
## Note down the privatekey ##
{root@ubuntu-20-4-vpn-client:~ }# cat privatekey

Edit the /etc/wireguard/wg0.conf file:
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo nano /etc/wireguard/wg0.conf
## OR ##
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo vim /etc/wireguard/wg0.conf

Append the following directives:

## This Desktop/client's private key ##
PrivateKey = uJPzgCQ6WNlAUp3s5rabE/EVt1qYh3Ym01sx6oJI0V4=
## Client ip address ##
Address =
## Ubuntu 20.04 server public key ##
PublicKey = qdjdqh2+N3DEMDUDRob8K3b+9BZFJbT59f+rBrl99zM
## set ACL ##
AllowedIPs =
## Your Ubuntu 20.04 LTS server's public IPv4/IPv6 address and port ##
Endpoint =
##  Key connection alive ##
PersistentKeepalive = 15

Enable and start VPN client/peer connection, run:
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo systemctl enable wg-quick@wg0
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo systemctl start wg-quick@wg0
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo systemctl status wg-quick@wg0

Allow desktop client and Ubuntu server connection over VPN

We need to configure the server-side peer-to-peer VPN option and allow a connection between the client computer and the server. Let us go back to our Ubuntu 20.04 LTS server and edit wg0.conf file to add [Peer] (client) information as follows (type commands on your server box):
{vivek@ln-sg-vpn-001:~ }$ sudo systemctl stop wg-quick@wg0
{vivek@ln-sg-vpn-001:~ }$ sudo vi /etc/wireguard/wg0.conf

Append the following config:

## Desktop/client VPN public key ##
PublicKey = u2ao8GNNUWAirtjq0eL1UpHVkMep5/EUalbZcdH0imc=
## client VPN IP address (note  the /32 subnet) ##
AllowedIPs =

Save and close the file. Next start the service again, run:
{vivek@ln-sg-vpn-001:~ }$ sudo systemctl start wg-quick@wg0

Step 7 – Verification

That is all, folks. By now, both Ubuntu servers and clients must be connected securely using a peer-to-peer VPN called WireGuard. Let us test the connection. Type the following ping command on your client machine/desktop system:
{vivek@ubuntu-20-4-vpn-client:~ }$ ping -c 4
{vivek@ubuntu-20-4-vpn-client:~ }$ sudo wg

Step 8 – Firewall configurations

Now we have set up and configured peer-to-peer VPN networking for our Ubuntu server and client. However, you may want to give access to the Internet for all VPN clients. For these purposes, we need to set up IPv4 and IPv6 firewall rules, including NAT and IP forwarding. See the following tutorial:


Congratulation! You just learned about setting up a WireGuard VPN server on Ubuntu 20.04 LTS server and peer (client machine) on both Ubuntu/CentOS Linux desktop. I strongly suggest that you read WireGuard project documentation here.

This entry is 1 of 6 in the WireGuard moden Linux/Unix/*BSD VPN Tutorial series. Keep reading the rest of the series:
  1. Ubuntu 20.04 set up WireGuard VPN server
  2. CentOS 8 set up WireGuard VPN server
  3. Debian 10 set up WireGuard VPN server
  4. WireGuard Firewall Rules in Linux
  5. Wireguard VPN client in a FreeBSD jail
  6. Alpine Linux set up WireGuard VPN server
🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
8 comments… add one
  • Avigdor Finkelstein Aug 8, 2020 @ 20:28

    The explanation seem to be clear, but eventually is totally
    What is the final structure and content of the configuration file?
    I found the the configuration file is cleaned of the comments, and some of the configuration commands when the service run, so the information in the file disappear.
    How many private and public keys need to be generated?
    I guess that the private should be unique, and so is the public, but the explanation seem to create several public keys. Is that so? What is the difference between the different public keys, if there are more than one.
    It seem as you build a configuration file step by step, but what remain from previous step is not clear.
    Can you clear the issue, please?

    • 🐧 Vivek Gite Aug 9, 2020 @ 16:30

      You need to create public and private keys on both server and client.

  • Hamidreza Sep 5, 2020 @ 19:18

    Could you please make the subnet part a little clear for someone like me who is totally noob in networking?
    you used /24 for server IP and /32 for client IP. why? is it important?

  • Chris Nov 7, 2020 @ 10:26

    Could you share the expected route table after starting wg?

    I have before:

    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         UG    600    0        0 wlp61s0   U     600    0        0 wlp61s0

    And after:

    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         UG    600    0        0 wlp61s0
    link-local     U     1000   0        0 wg0   U     600    0        0 wlp61s0   U     0      0        0 wg0
    $ sudo wg
    interface: wg0
      public key: 
      private key: (hidden)
      listening port: 39414
      endpoint: :41194
      allowed ips:
      transfer: 0 B received, 2.02 KiB sent
      persistent keepalive: every 15 seconds

    ‘ping -c 4’ does not work. Any thoughts?

    • 🐧 Vivek Gite Nov 7, 2020 @ 14:06

      Recheck both server and client keys again. Did you copied correct one?
      Client routing table for wg0:

      Kernel IP routing table
      Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    425    0        0 br0   U     50     0        0 wg0   U     425    0        0 br0
  • Mike Nov 16, 2020 @ 21:36

    I as well cannot ping – issuing ping from client and nothing.
    Double checked the correct keys in both server and client.
    From client side route view:
    root@mike-VirtualBox:/etc/wireguard# route -n

    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    100    0        0 enp0s3     U     1000   0        0 enp0s3   U     0      0        0 wg0   U     100    0        0 enp0s3

    Both my client and server are setup under Oracle VM and both client and server are 20.04 LTS

    • 🐧 Vivek Gite Nov 16, 2020 @ 22:57

      Either it is wrong keys added or firewall config. Re-check again.

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.