How to setup WireGuard VPN Server



wireguard-logo

This tutorial covers setting up a WireGuard VPN for tunnelling our traffic into some server on the internet for increasing our online privacy.

Disclaimer

The WireGuard setup described in this article only covers IPv4 and does not cover IPv6. This means if your computer wants to access the internet by using IPv6 then that IPv6 traffic will not be tunneled through VPN. But if you know enough you may implement IPv6 tunnelling also.

Any actions and or activities related to the material contained within this Website is solely your responsibility.The misuse of the information in this website can result in criminal charges brought against the persons in question. The author will not be held responsible in the event any criminal charges be brought against any individuals misusing the information in this website to break the law.

What is WireGuard?

WireGuard is a virtual private network protocol[1]. WireGuard is a Layer 3[2] secure tunnel and it runs as a Linux kernel module which is going to be merged into future Linux kernels[3]. It aims for better performance than the IPsec and OpenVPN tunneling protocols. Here its whitepaper.

How to setup WireGuard VPN server?

In this tutorial I am going to use a basic-level DigitalOcean droplet.

  • 1vCPU
  • 1GB RAM
  • 25GB Storage
  • OS: Ubuntu 18.04
  • !root access is required.

Install WireGuard

Since WireGuard is a kernel module then we will need correct kernel headers installed on our system. Following command will try to install correct linux kernel. You may need to update apt-get first.

  • sudo apt-get install linux-headers-$(uname --kernel-release)

I’ll use a WireGuard package for Ubuntu systems which is provided by the WireGuard project. Let’s add their WireGuard PPA to our server.

  • sudo add-apt-repository ppa:wireguard/wireguard
  • sudo apt-get update
  • sudo apt-get install wireguard-dkms wireguard-tools

Above commands are just standard PPA adding commands.

Generate encryption keys

Since WireGuard is a point-to-point protocol, each participant of the VPN connection needs public/private encryption key pairs.

To create the server key pair and add directly into WireGuard config file execute the following command.

  • (umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)

This command writes following initial content to /etc/wireguard/wg0.conf file and restricts its file permissions to 077 by using umask.

[Interface]
PrivateKey =

  • wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey

This second command is generates our server’s private key and writes it into the config file I mentioned above. Then, it pipes that private key to wg pubkey command which generates our server’s public key from that private key. After that it pipes public key to the file /etc/wireguard/publickey/.

If you didn’t understand that second command you may try them separately.

P.S. If you may notice we are creating a network interface called wg0, there should be no interface named wg0 in your server.

Edit initial config file

Open /etc/wireguard/wg0.conf file with your favorite text editor. I’ll use nvim for it.

  • sudo nvim /etc/wireguard/wg0.conf

In this file you should see our initial config with your private key. We need to define following settings to this file.

  • Address: Our server’s VPN address(not the public IP address)
  • SaveConfig: This option allows wg-quick command to save config file.
  • PostUp: After a VPN connection establishes it will execute this command. In our case, it will set iptables rules which will forward our traffic from interface wg0 to eth0 and vice versa.
  • PostDown: After VPN connection closes it will execute this command. In our case, I’ll remove iptables forwarding rules.
  • ListenPort: Our VPN server’s public listening port(can be any bindable port and it’s UDP not TCP). I’ll use port 65534
  • PrivateKey: VPN Server’s private key

At the end it should look like this.

[Interface]
Address = 10.0.0.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -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
ListenPort = 65534
PrivateKey = <OUR GENERATED PRIVATE KEY WITHOUT <> SYMBOLS>

Enable kernel traffic forwarding

We need to enable traffic forwarding in order to allow our traffic flows into our virtual private network. To achieve this execute following command.

cat << EOF >> /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
EOF
sysctl -p

Enable WireGuard system service

With enabling WireGuard as a system service, it will start automatically at every system startup. To do this execute following command.

How to setup WireGuard VPN client?

This client tutorial assumes you’re using Ubuntu 18.04 operating system for your computer and Android operating system for your mobile device.

Install WireGuard to your operating system.

This step is basically the same as installing WireGuard to the server. If you don’t use Ubuntu on your computer you should google this step :)

Generate encryption keys

As I said before, we need public/private key pair for every participant. Since client is another participant then we need another key pair for it. Generate them by using same command on your computer

  • (umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
  • wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey

Edit client’s config file first

After creating your client key pair, we need to add your client’s public key to server’s config file. And we need to add server’s public key to client’s config file. It is similar to config file of server.

Open client’s /etc/wireguard/wg0.conf file with your favorite text editor and fill necessary information in it.

  • INTERFACE
    • PrivateKey: Client’s private key
    • Address: Our client’s VPN address(not the public IP address)
    • DNS: DNS server address(I’ll use 1.1.1.1 this prevents DNS leak to compromise our real IP behind VPN)
  • PEER
    • PublicKey: Server’s public key
    • Endpoint: Server’s IP address and port number(e.g. 66.66.66.66:65534)
    • AllowedIPs: Which IP addresses are allowed to use our VPN. By setting 0.0.0.0/0 here will forwards our computer’s entire network traffic through VPN.
[Interface]
PrivateKey = <CLIENT's PRIVATE KEY HERE WITHOUT <> SYMBOLS>
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <SERVER's PUBLIC KEY HERE WITHOUT <> SYMBOLS>
Endpoint = <SERVER's PUBLIC IP ADDRESS>:65534
AllowedIPs = 0.0.0.0/0covers
PersistentKeepalive = 21

Edit server’s config file

We added our server’s public key to client’s config file. Now, we need to add client’s public key to server’s config file. So open server’s config file /etc/wireguard/wg0.conf with your favorite text editor and append the following [Peer] section to the server’s config file.

  • PEER
    • PublicKey: Client’s public key
    • AllowedIPs: Client’s VPN IP address with the subnet mask /32
[Peer]
PublicKey = <CLIENT's PUBLIC KEY HERE WITHOUT <> SYMBOLS>
AllowedIPs = 10.0.0.2/32
  • After appending it, the final config file of the server should look like this.
[Interface]
Address = 10.0.0.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -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
ListenPort = 65534
PrivateKey = <SERVER's PRIVATE KEY>

[Peer]
PublicKey = <CLIENT's PUBLIC KEY>
AllowedIPs = 10.0.0.2/32

Test VPN Connection

If there was no error happened during the setup. You should be able to connect your VPN by executing following command in your computer.

Before connecting to VPN let’s check your real IP address by executing following command.

  • curl -s ipinfo.io/ip

Then connect to your VPN by executing the following command. This command automatically sets forwarding rules and initiates VPN connection.

  • sudo wg-quick up wg0

After connected your VPN, check your IP address again by executing the same curl command again. The IP addresses before and after should be different.

When you want to disconnect from your VPN execute following command in your computer. The following command will try to restore forwarding rules and disconnect you from VPN.

  • sudo wg-quick down wg0

You can check some stats by executing following command on either client’s computer or server computer.

  • sudo wg show

How to setup WireGuard VPN client on Android?

Install WireGuard App

I think setting up WireGuard VPN client on Android is easier than Ubuntu computers. You just need to download WireGuard from Google Play. Click here for Google Play link.

wireguard-android



wireguard-android

Edit server’s config

After you set up WireGuard on Android, copy public key of Android client and add it as another peer to server’s config file. Edit following and append it to server config file at /etc/wireguard/wg0.conf

[Peer]
PublicKey = <ANDROID CLIENT's PUBLIC KEY WITHOUT <> SYMBOLS>
AllowedIPs = 10.0.0.3/32

Conclusion

In my opinion, WireGuard setup is easier than OpenVPN or IPsec setup. WireGuard claims that it has better performance than others but I did not test it. Some people on reddit or other forums says that it’s more secure than OpenVPN but I am unable to verify this. However, I liked WireGuard than OpenVPN but I wish WireGuard has TCP listening option but UDP is also OK.

Reference: