Published on October 6th, 2017 | by Manish Gehlot13
How to setup WireGuard VPN on your Debian GNU/Linux server with IPv6 support?
This is comprehensive guide to configure a WireGuard VPN server on Debian Jessie or newer GNU/Linux distribution. Although, I am going to use my favorite Debian Stable for this guide but it would equally work for derivatives including but not limited to Ubuntu.
For those who don’t know, WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than other VPN protocols including but not limited to OpenVPN and IPSec. As you probably know, WireGuard is not stable and being heavily developed as we speak, but even in its unoptimized state it is up to four times fast than popular OpenVPN protocol and delivers much lower ping time in comparison.
WireGuard aims to be as simple to configure as SSH. A connection is established by an exchange of public keys between server and client just like SSH keys and only a client with its public key present in server configuration file would be authorized.
More information can be found at https://www.wireguard.com/
- A high performance Linux server with a Public IPv4 and IPv6 address on NIC
- Root or sudo access to the same.
- SSH client like OpenSSH
A. SSH into your Linux server
Login into your Linux server with root or an user account with sudo access as follows:
ssh root@<Linux server IP>
Depending on the SSH authentication scheme you have configured, you may be prompted for password or to confirm the keys.
B. Installing latest WireGuard from Debian unstable’s repo
# echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list
# printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable
# apt update
# apt install wireguard-dkms wireguard-tools
C. WireGuard VPN server configuration
All the configurations for WireGuard VPN server are stored in a file at /etc/wireguard/wg0.conf, it need not be called wg0.conf, it could be server.conf or udp.conf.
I have written a model server configuration file wg0.conf for you already and we would discuss the same below. I would be explaining every line to you and also provide you with additional commands (not part and parcel of wg0.conf) required for a particular option to work, if any.
Without wasting any further time, let’s begin with the server configuration file now.
You are advised to read the manual of wg-quick and wg command, as it is used a lot in the guide.
Let’s start by generating private key for WireGuard server. The below command prints a private key.
$ wg genkey
wg0.conf begins here
PrivateKey = <PRIVATE KEY OF SERVER GENERATED ABOVE>
Defines tunnel interface and specifies WireGuard server’s private key generated above.
Address = 10.0.0.1/24, fd86:ea04:1115::1/64
ListenPort = 51820
Address sets private IPv4 and IPv6 addresses for WireGuard server to be setup behind public IP of Linux server. ListenPort specifies UDP port our VPN server would use to listen for connections.
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
PostUp and PostDown sets Linux IP Masquerade rules respectively to allow all the clients to share Linux server’s Internet IPv4 and IPv6 address and clear the rules once the tunnel is down, keeping the tables neat and tidy. SaveConfig saves anything added while the tunnel is up and running like a newly added client to server configuration file.
D. Packet forwarding, firewall rules and more
Packing forwarding is required to forward traffic from clients to the Internet.
Edit /etc/sysctl.conf as follows:
# nano /etc/sysctl.conf
Look for following entries and uncomment them by removing a ‘#’ in beginning.
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
Save, exit and then enable it as follows:
# sysctl -p
Configuring a firewall is a must to prevent unauthorized access to your VPS. I have used ufw, which is a popular and easy to use front-end for iptables.
Lets start by installing it
# aptitude install ufw
Allowing connections to SSH and WireGuard VPN port in ufw before enabling it:
# ufw allow 51820/udp
# ufw allow 22/tcp
# ufw enable
Enabling ufw with ufw enable, would give you a warning, “Command may disrupt existing ssh connections. Proceed with operation (y|n)?”
Type y without any hesitation.
Once enabled verify it with the following command:
# ufw status verbose
E. Starting WireGuard VPN server and enabling it to run on reboot
# wg-quick up wg0
# systemctl enable [email protected]
You can check if the VPN tunnel is running as follows:
# wg show
# ifconfig wg0
wg show shows server’s public key in the output, kindly make a note of it as we would require it for the client configuration file.
Hurrah! Done with WireGuard VPN server-side setup.
F. WireGuard VPN Client configuration
This is to be done on a local client machine with Debian GNU/Linux or its derivatives and other GNU/Linux distributions. Installation of WireGuard on Debian GNU/Linux client machine is exactly the same as we did in the para B above. For other linux distributions please refer to, https://www.wireguard.com/install/.
A model client configuration file client.conf is made available below. All the options used therein are either similar to server configuration above or self-explanatory, still refer to the manual whenever required.
Before we move to configuration file, lets generate key pair for the client using wg command as follows:
$ wg genkey | tee privatekey | wg pubkey > publickey
It would generate and store your public and private key in publickey and privatekey text files respectively.
Moving to client.conf
PrivateKey = <Output of privatekey file that contains your private key>
Address = 10.0.0.5/24, fd86:ea04:1115::5/64
PublicKey = <Server's public key from *wg show* command on server>
Endpoint = <Linux server's Public IP>:51820
AllowedIPs = 0.0.0.0/0, ::/0
Save the above as client.conf in /etc/wireguard/ directory of your local machine after fixing the PrivateKey of client, PublicKey of server and Endpoint IP or Public IP of your Linux server.
G. Adding WireGuard client(s) to VPN server on Linux server
Next we add a client or peer on VPN server by executing the following wg command on Linux server:
# wg set wg0 peer <PUBLIC KEY OF CLIENT> allowed-ips 10.0.0.5,fd86:ea04:1115::5
A newly added client can be verified on Linux server by executing wg show command. Any number of clients with their respective public key can be added while tunnel or VPN server is up and running! SaveConfig entry added to server configuration above writes it to wg0.conf when the VPN server is brought down for any reason.
More clients can be added similarly:
# wg set wg0 peer <PUBLIC KEY OF CLIENT2> allowed-ips 10.0.0.10,fd86:ea04:1115::10
Job on WireGuard VPN server is done here. You may close your active SSH connection to it, if any.
H. Connecting to WireGuard VPN server from a local machine
Connect to your WireGuard VPN server on GNU/Linux client as follows to test your VPN setup for 1st time:
$ sudo wg-quick up client
wg-quick command is a script that looks for client.conf in /etc/wireguard/ and use wg command to setup your VPN connection on local machine in seconds.
Verify the connection with wg command and by pinging server’s Interface IP as follows:
$ sudo wg
$ ifconfig client
$ ping 10.0.0.1
Upon successful connection last two lines of the output of above sudo wg should look as follows:
latest handshake: 1 minute, 17 seconds ago
transfer: 98.86 KiB received, 43.08 KiB sent
Visit a website like https://duckduckgo.com/IP_Address or https://ipchicken.com to check your IP, if it is your Linux server’s public IP then you did it! Also visit https://ipv6.google.com to ensure that you have IPv6 connectivity.
As of now, WireGuard is only supported on GNU/Linux because support on more platforms is expected. Although, current linux based embedded devices like routers can expect huge performance boost vs other prominent VPN protocols like OpenVPN.
Finally! We have successfully hosted a secure, modern and fast VPN server based on WireGuard VPN on a Linux server not just for you but even for your loved ones.
For any issues, suggestions or further help, you are free to comment.
Thanks for reading!