How to Enable Wireguard For Linux
December 21, 2020
December 20, 2020
This tutorial assumes that you are using Debian 10 Buster, running sudo interactively, the Cinnamon desktop, have at least two Debian-based OSes to work with, an Autonomous System (AS), a working internet connection, some money to spend, and an understanding of subnets, firewall exceptions and the command line. I will include as many pictures and context as I possibly can. This will be a CLI-dominant tutorial.
After terminating payments for my personal IP through another provider, I decided to establish a direct relationship with Digital Ocean, similar to when I dumped GeekSquad in 2016 so I could pursue a direct relationship with Trend Micro. No matter what industry it is, middlepersons complicate EVERYTHING.
I signed up for a droplet with DigialOcean, and installed Debian Buster x64 on it. When you create a droplet, you are asked to set a password or use SSH keys. Please set the password now and enable SSH keys later. Make sure it has high entropy. Once you do, be sure to allow port 22 through the firewall under Droplet >> Networking >> Firewall. Give your firewall a name, and then assign it to the droplet you need to access. Rather than use "ALL IPv4", please specify the public IP of the computer you are using ONLY. Then log in through SSH via the terminal. I've got a tutorial for SSH.
Once you've logged in, you'll need to refresh the list of available packages. We're going to use the command line extensively. Please review the tutorial on VNC if you'd like to peek at this process from a GUI. Please type the following into the command line. This step should be done on both client and server. Alternatively, this specific step can be done in Synaptic. If you choose Synaptic, please read this note for Debian 10. Click the "Search" button on the top right and use the term "wireguard" and press "Search". Once you see the wireguard entry, click its white square and select "Mark for Installation". Consent to dependencies and click "Mark". Click Apply in the top left and then "Apply" on the resulting window. If the square is green, it is already installed.
echo "deb http://deb.debian.org/debian buster-backports main" | sudo tee /etc/apt/sources.list.d/buster-backports.list
sudo apt update
sudo apt install wireguard wireguard-tools wireguard-dkms linux-headers-$(uname -r)
The first line adds the Wireguard backport for Debian buster as a repository source so that it can be found when your download it. The second line refreshes the dpkg list. The third line downloads wireguard and its toolkit, in addition to headers. Wireguard won't work if the headers don't accommodate it. Once it is finished installing, you'll need to install a DNS resolver later. This step must be done on both client and server. Please type the following into the command line. Alternate choices possible.
sudo apt install resolvconf
This is where the fun begins. We will now generate keys that the Wireguard interface will use to talk between itself and its peers. These steps must be done on both client and server. Enter the following into the command line:
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
This will generate two files, "server_private.key" and "server_public.key", which will appear in the root-only directory "/etc/wireguard". If you attempt to access this directory through Nemo, it will show an X, indicating you're not allowed to view it. Either open as root using the context menu, or use sudo -i in the command line if you need to perform filesystem operations. On the client, you should substitute "server_" for "client_" in the filenames. Open the command line and type the following command before reading further:
sudo modprobe wireguard
If you see "FATAL" in the output, wireguard is missing from your Linux header. It has to be in the header because it's loaded at boot time. If you don't see any output, you can move on to the next step. Now, you will need to plan your network map. You cannot use the network map of any other adapter. Pick any class A, B or C arrangement. For purposes of this tutorial, we will pick 172.16.79.0/27, which allows a network with 30 possible hosts. You will also need to make sure that this is reflected in all wg0.conf files you create on each machine, and each NAT rule you set must include this mapping otherwise the packets will be dropped. A server sample file is shown here and a client file is shown here - you should adjust it to suit your needs.
Now there's some heavy lifting involved. You will need to edit several system files to define how wireguard packets are handled on the server, and you will need to install the programs needed to set those options. Let's start with ip forwarding. Remember that null netmask in your client config? We have to tell the server that passing through is OK first. Type the following into the command line: this will open a plain text editor in the same window. Lines that are actionable are white -comments are teal and will be ignored:
Edit Line 28 by pressing CTRL + SHIFT + [-] with your keyboard. Enter Line 28 when asked and change the resulting value to 1. Save the file by pressing CTRL + S. Exit by pressing CTRL + X. We also need to make sure these settings persist across reboots. Type the following into the command line:
sudo sysctl -p
Now we need to install the Firewall app. Please note that the rules you set on this firewall take precedent over a rule you set in the DO UI that was not already set. If you set a rule in the DO UI, it will be ignored bt UFW. We should install it. If you got the GUI working, open Synaptic and click on the Search button in the top right corner and enter the term 'ufw' and press "Search". You will see two entries. One is 'ufw', which is the command line tool. The other is 'gufw', which is the GUI version of it. Click the white box next to 'gufw' and select "Mark for Installation". Consent to dependencies, which includes 'ufw', and click "Mark". Click Apply and then "Apply" in the resulting window to continue. If you choose to use the CLI, type the following, one at a time:
apt-get install ufw
At this point, you will need to know which interface is connected to the internet. On the droplet, it's usually eth0 and the inet entry corresponds to the entry listed as your droplet's Public IP. But to be sure, type ifconfig into your command line anyway. IP masquerading must also be configured, and you will need to add some rules to the NAT table located in the file /etc/ufw/before.rules. Open this file in nano, and navigate to line 78 and add the following entries.
Once this is done, you will need to restart the firewall. Use the following lines in the command prompt:
systemctl enable ufw
ufw allow 12208/udp
The first line restarts the firewall, the second enables port 12208 from our example config to pass in and out of the server. Confirm the rules are properly enabled by typing the following into the command line:
iptables -t nat -L POSTROUTING
Your output should resemble this. If not, you it's possible you made a typo somewhere. I did it too. Just repeat the steps and use XED if you need to use the Find text option to identify typos or verify input.
Still here? Now we get to install our very own DNS resolver! I hope you didn't forget to install resolvconf. If you're using Synaptic, use the search button on the top right and type "bind9" as the query and then click the "Search" button. Click the white square next to the "bind9" and click "Mark for Installation" in the resulting menu. Consent to additional dependencies and click "Mark". Then click "Apply" on the top left, and then "Apply" in the foreground window. If you're using CLI, enter this command:
apt-get install bind9
Check if it's running by typing systemctl status bind9 in the command line. If it's not active, type systemctl start bind9 and press enter. We will need to edit its configuration file to accommodate our Wireguard network. Open /etc/bind/named.conf.options and edit line 23 as follows. You will need to restart bind9 using the following commands:
systemctl restart bind9
sudo ufw insert 1 allow in from 172.16.79.0/27
The first line restarts bind9, the second permits your Wireguard network to connect to port 53. If you chose a different mapping in earlier steps, you must insert the same mapping in this step. Now, we shall fire up the Wireguard client on the server side first, followed by at least one client. Enter this command in the terminal on either:
wg-quick up wg0
The example uses wg0, but you can name the interface file anything you want. If you'd like this to start up each time Linux boots, you'll need to enable the wg-quick service by typing the following commands:
systemctl enable email@example.com
To check the status, type the following:
systemctl status firstname.lastname@example.org
To terminate the wireguard connection, type wg-quick down wg0. It's ideal to terminate it if you need access to a local resource at home. If you set up your printer on the local network, for example, it might have an IP address for the local network but will not be visible on your Wireguard network. To verify connectivity, ping the DNS address of your Wireguard server FROM the peer by typing the following:
ping -c 4 172.16.79.1
If you get a response, you should be able to talk to other devices on the network. If not, consider saving debug logs. Enter the following as a privileged user:
echo 'module wireguard +p' | sudo tee /sys/kernel/debug/dynamic_debug/control
To disable logging, enter this command:
echo 'module wireguard -p' | sudo tee /sys/kernel/debug/dynamic_debug/control
If you've configured everything correctly, congrats! Visit this page on my site to see how you appear. You should see the public IP of your droplet and not the public IP of your carrier ISP.
© 2020 Mass Transit Honchkrow, Xiao Guonan, IVPN Helpdesk, The Digital Life