I just spent a few hours learning how to setup Wireguard VPN. Once you find a good source, and in my case a few good sources, it’s not that bad. Not being a networking expert, however, I was a bit lost at times on why certain things wouldn’t work.
I want to give a breakdown of how it’s done here, so if any of you want to give it a try, you can.
Setup a Server
In my case I setup a digital ocean server that I already use for an OpenVPN anyway, so no harm no foul on the cost. Didn’t change a bit.
My Server is running Ubuntu 16.04 LTS 64 bit, with 1 GB RAM, and an SSD.
First you need to add the proper repos for installing Wireguard. If you are using something other than Ubuntu, this will be different.
First you need to install the PPA.
sudo add-apt-repository pps:wireguard/wireguard
Next you’ll update the repos.
sudo apt update
And then you need to install the Wireguard kernel addons and tools.
sudo apt install wireguard-dkms wireguard-tools linux-headers-$(uname -r)
The last part above installs the right headers for your version of linux.
Now that wireguard is installed, we need to configure the server. This is pretty simple, and is done ian a couple of steps.
Step 1: Generate the Server Private Key and Public Key using Wireguard to do it. You should do this as root, so use sudo
if you aren’t logged in as root.
umask 077
wg genkey | tee server_private_key | wg pubkey > server_public_key
You can change the name of the files in the command above to whatever you want. Instead of “server_private_key” and “server_public_key” you can name them “private” and “public” if you so desire.
Ok, we have our keys, and we’ll need them momentarily. So, first let’s copy the private key:
cat server_private_key
highlight and copy this key.
Now we’ll start making our server configuration file. I’ll use nano, but feel free to use VI, VIM, emacs, ro whatever editor is your favorite. Again, this will have to be done as root, or with sudo privileges.
nano /etc/wireguard/wg0.conf
This should open a new configuration file for us to edit. This configuration file is what sets up our network vpn server connection. It will be called wg0
.
Inside the configuration file, we need to add the following.
[Interface]
Address = 10.100.100.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = <your generated server_private_key here>
The first line identifies this as a network interface [Interface]
.
Line 2 sets the IP Address we want of this interface on the VPN, feel free to use any private address you like. the /24
at the end says this whole range for 10.100.100 from 0 to 255 will be available.
Line 3 allows new Peers to be added / updated with information when they connect…so keep it as true
.
Lines 4 and 5 setup the necessary IP forwarding so when you are on the VPN you can still get to the internet through your server connection.
Line 6 tells Wireguard what port to listen on for new connections. You can use any port number you want, but remember what you shoose, because you’ll need to set that on each peer later.
Line 7 is whre you’ll paste that Private key you copied a bit ago. Just after the = sign, copy it in there.
Now save (CTRL+O), and then exit nano for now (CTRL+X).
Real quick, we need to make sure ip_forwarding is enabled on the server. So open /etc/sysctl.conf
. Again this needs to be done as root, or with sudo privileges.
nano /etc/sysctl.conf
Next, look down through the file for the line net.ipv4.ip_forward=1
. If it has a #
sign in front of it, remove the #
sign, and save (CTRL+O), and exit the file (CTRL+X).
Now restart that service with the command:
sysctl -p
If you don’t get an error, run this command:
echo 1 > /proc/sys/net/ipv4/ip_forward
and make sure the output is
net.ipv4.ip_forward=1
Whew! Technically, we can now start the Wireguard server, and it will run, but we don’t have any peers yet, so nothing will connect. So, let’s setup a client first.
Client Setup
On your client machine(s), you need to install Wireguard just like we did for the server.
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt update
sudo apt install wireguard-dkms wireguard-tools linux-headers-$(uname -r)
Once that completes, we need to generate our Client Keys.
umask 077
wg genkey | tee client_private_key | wg pubkey > client_public_key
Again, you can name the client private and public keys anything you want.
Now, copy the client_private_key:
cat client_private_key
copy the key that is displayed.
Next we need to create our client configuration file.
sudo nano /etc/wireguard/wg0.conf
Inside this file, we need to add our config, just like we did with the server. We create an interface, then add the server as a Peer.
[Interface]
Address = 10.100.100.2/32
PrivateKey = <your client private key>
[Peer]
PublicKey = <your server's public key>
Endpoint = <your server's public ip address>:51820
AllowedIPs = 10.100.100.0/24
PersistentKeepalive = 21
You’ll paste your client_private_key on line 3, where it is stipulated, then you’ll save the file. Now you need to go and get your server’s public key. On that terminal, do
cat server_public_key
Copy the key shown, and paste that key into the client configuration file on line 6 next to the PublicKey option.
Now, save and close the configuration file on the client, and get the client_public_key using the command:
cat client_public_key
Copy the key shown, and in the terminal for your server, go back into the server wg0.conf file.
nano /etc/wireguard/wg0.conf
From inside this file, you’ll create a [Peer]
secion below the [Interface]
section that is already there.
[Peer]
# Ubuntu iMac
PublicKey = <your client public key here>
AllowedIPs = 10.100.100.2/32
In this addition, you’ll notice I added a comment line # Ubuntu iMac
. This isn’t read by the Wireguard service, so it’s just for me to keep my peer machines straight when I go into this file.
Now save and exit this file.
Almost done now.
Start the server
Now, we need to start wireguard running on the server. The command is pretty easy.
wg-quick up wg0
If you aren’t root, you’ll need to use sudo
to run this command.
The server will start. You can check it by running the command (again as a root / sudo user):
wg
When you run that you should see something like this:
interface: wg0
public key: <your server public key will show here>
private key: (hidden)
listening port: 51820
Start the Client
Okay, now the moment of truth. We start our client.
On your client terminal, again, you’ll just start the service manually using the same command as a bove.
sudo wg-quick up wg0
Then you can check it several ways. First just do the wg
command.
sudo wg
interface: wg0
public key: <your client public key is shown here>
private key: (hidden)
listening port: 55104
peer: <your server public key is shown here>
endpoint: <your server public ip here>:51820
allowed ips: 10.100.100.0/24
latest handshake: 1 minute, 49 seconds ago
transfer: 4.31 MiB received, 289.10 KiB sent
persistent keepalive: every 21 seconds
If you see something like this…you’re doing good. Now let’s try to ping the server using the wireguard ip we gave it.
ping 10.100.100.1
This should start feeding out lines with ping response times similar to this.
PING 10.100.100.1 (10.100.100.1) 56(84) bytes of data.
64 bytes from 10.100.100.1: icmp_seq=1 ttl=64 time=83.2 ms
64 bytes from 10.100.100.1: icmp_seq=2 ttl=64 time=72.8 ms
64 bytes from 10.100.100.1: icmp_seq=3 ttl=64 time=72.7 ms
64 bytes from 10.100.100.1: icmp_seq=4 ttl=64 time=66.7 ms
64 bytes from 10.100.100.1: icmp_seq=5 ttl=64 time=75.0 ms
64 bytes from 10.100.100.1: icmp_seq=6 ttl=64 time=69.7 ms
^C
--- 10.100.100.1 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5007ms
rtt min/avg/max/mdev = 66.704/73.387/83.270/5.158 ms
Use CTRL+C in the terminal to stop the ping process.
If you got ping responses from the server, that’s good. That means your client and server are connected.
Now let’s ping something on the internet, to make sure we still have internet access when we are connect to our wireguard server.
ping google.com
Again, you should see output like that above, with ping response times.
Troubleshooting
If you are having issues getting ping response times, accessing the internet, or your server, you can turn the Wireguard connection off very simply. In your terminal type
sudo wg-quick down wg0
This will take the wireguard connection offline.
If you need to make corrections, or double check your configuration files, you need to turn off the wireguard connection with the command above. Make any changes, then start it back up with the
sudo wg-quick up wg0
command.
Run the wireguard server and client connections as a service so they start automatically on reboot.
This is actually quite simple.
In the terminal on the server type
systemctl enable wg-quick@wg0
Next, type:
systemctl start wg-quick@wg0
Now on the clients, you can continue manually taking them on and offline, or you can do the same commands as above (with root or sudo privileges), and it wireguard will start and connect automatically for you.
Let’s Review
What we did is
- Install Wireguard on our server, and any clients we want.
- Setup our Server Wireguard configuration file.
This file should hold an [Interface]
section with our wireguard server information, and [Peer]
section(s) with any peer public keys, and IPs they should have when connected.
- Setup our Client Wireguard configuration file.
The [Interface]
section here holds our client’s information, and the onty [Peer]
we added was our server.
- Start the Wireguard service on the server, and client.
- Test out connection.
I hope this article inspires you to give it a try, and helps you succeed with Wireguard.
By the way, there are apps to help you add iOS and Android devices as well. I’ll cover those later if there’s interest.