This tutorial is going to show you how to set up your own WireGuard VPN server on Ubuntu. WireGuard is made specifically for the Linux kernel. It runs inside the Linux kernel and allows you to create fast, modern, and secure VPN tunnel.
Features of WireGuard VPN
- Lightweight and super fast speed, blowing OpenVPN out of the water.
- Cross-platform. WireGuard can run on Linux, BSD, macOS, Windows, Android, iOS, and OpenWRT.
- User authentication is done by exchanging public keys, similar to SSH keys.
- It assigns static tunnel IP addresses to VPN clients. Some folks may not like it, but it can be useful in some cases.
- Mobile devices can switch between Wi-Fi and mobile network seamlessly without dropping any connectivity.
- It aims to replace OpenVPN and IPSec in most use cases.
Prerequisites
This tutorial assumes that the VPN server and VPN client are both running Ubuntu operating system.
Step 1: Install WireGuard on Ubuntu Server and Desktop
Log into your Ubuntu server, then run the following commands to install WireGuard.
Ubuntu 20.04
sudo apt update sudo apt install wireguard wireguard-tools
Ubuntu 18.04/16.04
sudo apt install software-properties-common sudo add-apt-repository ppa:wireguard/wireguard -y sudo apt update sudo apt install wireguard wireguard-tools wireguard-dkms
Ubuntu 18.04/16.04 will automatically build the wireguard module into the Linux kernel with the help of wireguard-dkms
. Ubuntu 20.04 ships with a Linux kernel that has a built-in wireguard module, so you don’t need to install the wireguard-dkms
package on Ubuntu 20.04.
Then use the same commands to install WireGuard on your local Ubuntu computer (the VPN client). Note that you also need to install the openresolv
package on the client to configure DNS server.
sudo apt install openresolv
Step 2: Generate Public/Private Keypair
Server
Run the following command on the Ubuntu server to create a public/private key pair, which will be saved under /etc/wireguard/
directory.
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
Client
Run the following command to create a public/private key pair on the local Ubuntu computer (the VPN client).
wg genkey | sudo tee /etc/wireguard/client_private.key | wg pubkey | sudo tee /etc/wireguard/client_public.key
Step 3: Create WireGuard Configuration File
Server
Use a command-line text editor like Nano to create a WireGuard configuration file on the Ubuntu server. wg0
will be the network interface name.
sudo nano /etc/wireguard/wg0.conf
Copy the following text and paste it to your configuration file. You need to use your own server private key and client public key.
[Interface] Address = 10.10.10.1/24 SaveConfig = true PrivateKey = UIFH XXjJ0g0uAZJ6vPqsbb/o68SYVQdmYJpy/FlGFA= ListenPort = 51820 [Peer] PublicKey = 75VNV7HqFh 3QIT5OHZkcjWfbjx8tc6Ck62gZJT/KRA= AllowedIPs = 10.10.10.2/32
Where:
- Address: Specify the private IP address of the VPN server. Here I’m using the 10.10.10.0/24 network range. 10.10.10.1 is the private IP address for the VPN server.
- SaveConfig: the configuration should be saved on shutdown using the current status of the interface.
- PrivateKey: The private key of VPN server, which can be found in the
/etc/wireguard/server_private.key
file on the server. - ListenPort: WireGuard VPN server will be listening on UDP port 51820, which is the default.
- PublicKey: The public key of VPN client, which can be found in the
/etc/wireguard/client_public.key
file on the client computer. - AllowedIPs: IP addresses the VPN client is allowed to use. In this example, the client can only use the 10.10.10.2 IP address inside the VPN tunnel.
Save and close the file. (To save a file in Nano text editor, press Ctrl O
, then press Enter to confirm. Press Ctrl X
to exit.)
Change the file permission mode so that only root user can read the files.
sudo chmod 600 /etc/wireguard/ -R
Client
Use a command-line text editor like Nano to create a WireGuard configuration file on your local Ubuntu computer. wg-client0
will be the network interface name.
sudo nano /etc/wireguard/wg-client0.conf
Copy the following text and paste it to your configuration file. You need to use your own client private key and server public key.
[Interface] Address = 10.10.10.2/24 DNS = 10.10.10.1 PrivateKey = cOFA x5UvHF a3xJ6enLatG DoE3I5PhMgKrMKkUyXI= [Peer] PublicKey = RaoAdsIEIwgV9DHNSubxWVG nZ1GP/c3OU6A/efBJ0I= AllowedIPs = 0.0.0.0/0 Endpoint = 12.34.56.78:51820
Where:
- Address: Specify the private IP address of the VPN client.
- DNS: specify 10.10.10.1 (VPN server) as the DNS server. It will be configured via the
resolvconf
command. - PrivateKey: The client’s private key, which can be found in the
/etc/wireguard/client_private.key
file on the client computer. - PublicKey: The server’s public key, which can be found in the
/etc/wireguard/server_public.key
file on the server. - AllowedIPs: 0.0.0.0/0 represents the whole Internet, which means all traffic to the Internet should be routed via the VPN.
- Endpoint: The public IP address and port number of VPN server. Replace 12.34.56.78 with your server’s real public IP address.
Save and close the file.
Change the file mode so that only root user can read the files.
sudo chmod 600 /etc/wireguard/ -R
Step 4: Enable IP Forwarding on the Server
In order for the VPN server to route packets between VPN clients and the Internet, we need to enable IP forwarding. Edit sysctl.conf
file.
sudo nano /etc/sysctl.conf
Add the following line at the end of this file.
net.ipv4.ip_forward = 1
Save and close the file. Then apply the changes with the below command. The -p option will load sysctl settings from /etc/sysctl.conf file. This command will preserve our changes across system reboots.
sudo sysctl -p
Step 5: Configure IP Masquerading on the Server
We need to set up IP masquerading in the server firewall, so that the server becomes a virtual router for VPN clients. I will use UFW, which is a front end to the iptables firewall. Install UFW on Ubuntu with:
sudo apt install ufw
First, you need to allow SSH traffic.
sudo ufw allow 22/tcp
Then edit /etc/default/ufw
file.
sudo nano /etc/default/ufw
Change the default forward policy from “DROP” to “ACCEPT”.
DEFAULT_FORWARD_POLICY="ACCEPT"
Save and close the file. Next, find the name of your server’s main network interface.
ip addr
As you can see, it’s named ens3
on my Ubuntu server.
To configure IP masquerading, we have to add iptables command in a UFW configuration file.
sudo nano /etc/ufw/before.rules
By default, there are some rules for the filter
table. Add the following lines at the end of this file. Replace ens3
with your own network interface name.
# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ens3 -j MASQUERADE
# End each table with the 'COMMIT' line or these rules won't be processed
COMMIT
In Nano text editor, you can go to the end of the file by pressing Ctrl W
, then pressing Ctrl V
.
The above lines will append (-A) a rule to the end of of POSTROUTING chain of nat table. It will link your virtual private network with the Internet. And also hide your network from the outside world. So the Internet can only see your VPN server’s IP, but can’t see your VPN client’s IP, just like your home router hides your private home network.
Save and close the file. Then enable UFW.
sudo ufw enable
If you have enabled UFW before, then you can use systemctl to restart UFW.
sudo systemctl restart ufw
Now if you list the rules in the POSTROUTING chain of the NAT table by using the following command:
sudo iptables -t nat -L POSTROUTING
You can see the Masquerade rule.
Step 6: Install a DNS Resolver on the Server
Since we specify the VPN server as the DNS server for client, we need to run a DNS resolver on the VPN server. We can install the bind9 DNS server.
sudo apt install bind9
Once it’s installed, BIND will automatically start. You can check its status with:
systemctl status bind9
Sample output:
● named.service - BIND Domain Name Server Loaded: loaded (/lib/systemd/system/named.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2020-05-17 08:11:26 UTC; 37s ago Docs: man:named(8) Main PID: 13820 (named) Tasks: 5 (limit: 1074) Memory: 14.3M CGroup: /system.slice/named.service └─13820 /usr/sbin/named -f -u bind
If it’s not running, start it with:
sudo systemctl start bind9
Edit the BIND DNS server’s configuration file.
sudo nano /etc/bind/named.conf.options
Add the following line to allow VPN clients to send recursive DNS queries.
allow-recursion { 127.0.0.1; 10.10.10.0/24; };
Save and close the file. Restart BIND9 for the changes to take effect.
sudo systemctl restart bind9
Then you need to run the following command to allow VPN clients to connect to port 53.
sudo ufw insert 1 allow in from 10.10.10.0/24
Step 7: Open WireGuard Port in Firewall
Run the following command to open UDP port 51820 on the server.
sudo ufw allow 51820/udp
Step 8: Start WireGuard
server
Run the following command on the server to start WireGuard.
sudo wg-quick up /etc/wireguard/wg0.conf
To stop it, run
sudo wg-quick down /etc/wireguard/wg0.conf
You can also use systemd service to start WireGuard.
sudo systemctl start [email protected]
Enable auto-start at system boot time.
sudo systemctl enable [email protected]
Check its status with the following command. It’s status should be active (exited)
.
systemctl status [email protected]
Now WireGuard server is ready to accept client connections.
Client
Start WireGuard.
sudo systemctl start [email protected]
Enable auto-start at system boot time.
sudo systemctl enable [email protected]
Check its status:
systemctl status [email protected]
Now go to this website: http://icanhazip.com/
to check your public IP address. If everything went well, it should display your VPN server’s public IP address instead of your client computer’s public IP address.
VPN Kill Switch
By default, your computer can access the Internet via the normal gateway when the VPN connection is disrupted. You may want to enable the kill switch feature, which prevents the flow of unencrypted packets through non-WireGuard interfaces.
Edit the client configuration file.
sudo nano /etc/wireguard/wg-client0.conf
Add the following two lines in the [interface]
section.
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
Like this:
[Interface] Address = 10.10.10.2/24 DNS = 10.10.10.1 PrivateKey = cOFA x5UvHF a3xJ6enLatG DoE3I5PhMgKrMKkUyXI= PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT [Peer] PublicKey = RaoAdsIEIwgV9DHNSubxWVG nZ1GP/c3OU6A/efBJ0I= AllowedIPs = 0.0.0.0/0 Endpoint = 12.34.56.78:51820
Save and close the file. Then restart the WireGuard client.
sudo systemctl restart [email protected]
Wrapping Up
That’s it! I hope this tutorial helped you install and configure WireGuard on Ubuntu. As always, if you found this post useful, then subscribe to our free newsletter to get more tips and tricks 🙂
Rate this tutorial
[Total: 0 Average: 0]