I've recently done a post on setting up OPNsense & WireGuard and connecting an Android phone to it, so my next post is how to connect your Ubuntu desktop machine to the same OPNSense instance.

Given that a lot of stuff I've already covered in my original post, I'm not going to cover old ground again, so the prerequisites for this post are that you have a working OPNsense WireGuard implementation already, if you don't then read my previous post to find out how to get it up and running here.

Note: All keys used shown in the screenshots are no longer in  use and were created solely for the purposes of this post, no need to  warn me, or try them out, I guarantee they've been nuked from orbit.

Install WireGuard

I'm currently using Pop_OS! 19.10 on my main ThinkPad, and those that know me will testify to my distrohopping propensity, although my main staple distro for a long while has been the excellent Ubuntu Budgie and I'm still using it on my other ThinkPad.

On any Ubuntu distro or derivative from 19.10 onwards, WireGuard, is present in the default Ubuntu repositories and can be installed easily with

sudo apt install wireguard

If you're currently on any Ubuntu (or derivative) from prior to 19.10 then you will need to add the WireGuard PPA as it's not present in the default Ubuntu repositories.  Again, this can be done easily with

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

Install openresolv

To ensure DNS works with your WireGuard tunnel you also need to install openresolv, luckily it's in the default repositories, so we can install it with

sudo apt install openresolv

Generate your keys

This is easily accomplished with

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

which will create a matched pair of files called privatekey and publickey respectively which we'll use later when setting up our config.

Create your config file

Now we need to create a config file to tell WireGuard how to connect to our OPNsense install.  I prefer nano as my terminal based text editor, if you wish to use Vi, Vim or Emacs then feel free, lets not get into an argument about it.

sudo nano /etc/wireguard/wg0.conf

Now we need to define our config in the nano window.

Here's my config, and we'll discuss it below.

[Interface]
#thinkpad
PrivateKey=CGBzY4DFjUrrCBY5/tlx9EPct8Lin3HdublN0/r9nmk=
Address=10.252.0.3/32
DNS=192.168.0.253

[Peer]
#opnsense
PublicKey=Jtsq3POSdPb8TSrr7rBWL378eU1ribaUte+mX7n6/k0=
Endpoint=linuxserver:51820
AllowedIPs=0.0.0.0/0, ::/0

Interface (ThinkPad)

PrivateKey is easily seen by running cat privatekey which displays the private key we generated earlier.

Address I have already allocated 10.252.0.1 & 10.252.0.2 to my OPNsense and Android phone respectively, so for my laptop I'm going to use 10.252.0.3

DNS As mentioned in my previous post, I have an Adguard DNS server running on a Raspberry Pi on my LAN at 192.168.0.253

Peer (OPNsense)

PublicKey paste into here the public key for your OPNsense WireGuard instance.

Endpoint The address and port where your OPNsense instance can be reached remotely, can be either a static IP or a domain name which resolves correctly.

AllowedIPs Allows all IPs to be accessed on this peer by specifying 0.0.0.0/0

Once you've finished editing your wg0.conf file use Ctrl+x to save and exit.

Add the ThinkPad to OPNsense

I'm not going to cover this in any depth as I did so in my previous OPNsense WireGuard post, but here's a quick screenshot to show the information needed.

Test your tunnel

Now all the configuration is done, it's time to test our tunnel.

wg-quick up wg0

and you should find the tunnel comes up just fine, you can check in the OPNsense Webui by looking at the WireGuard List Configuration tab.

To take the tunnel back down

wg-quick down wg0

You can also check that your DNS settings are being propagated to your Ubuntu desktop with

cat /etc/resolv.conf

which for me gives the output

chbmb@thinkpad:~$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.0.253

when the tunnel is up, and

chbmb@thinkpad:~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0

when the tunnel is down.

Implement a Desktop Toggle

As comfortable as I am at the terminal, I decided the ability to just hit the super key and select a WireGuard toggle from the menu was just too easy not to implement.

You can either follow the instructions below, alternatively feel free to grab the necessary files from my GitHub repository here.  Both folders need to be copied into your home directory.

First install zenity which gives us a GUI prompt to enter our sudo password when the tunnel is toggled up and down, it looks prettier than a terminal opening when you're prompted for the sudo password.

Then we're going to create a folder to keep the wireguard.sh file, the zenity.sh file in and finally, we'll open nano so we can create the wireguard.sh file.

sudo apt install zenity
mkdir -p ~/.wireguard
nano ~/.wireguard/wireguard.sh

Now paste in the bash routine

#!/bin/bash

export SUDO_ASKPASS="/home/$USER/.wireguard/zenity.sh"

if ip a | grep -q 'wg0'; then
   sudo -A wg-quick down wg0
else
   sudo -A wg-quick up wg0
fi

Save it with ctrl+x and then lets make the .sh file that is referenced above.

nano ~/.wireguard/zenity.sh

And simply paste in

#!/bin/bash

zenity --password --title="WireGuard"

lets make them both executable with

chmod +x ~/.wireguard/*.sh

Now we need to find an icon, I suggest looking for one that you find appealing and download it and place it in the ~/.local/share/icons folder.

If you're happy with the default icon then feel free to pull one I uploaded to Github with

mkdir -p ~/.local/share/icons
wget https://raw.githubusercontent.com/CHBMB/wireguard-gnome/master/.local/share/icons/wireguard.png -P ~/.local/share/icons

Next we need to add this to the Gnome menu.

Create a new .desktop file

nano ~/.local/share/applications/wireguard.desktop

And paste in the following

[Desktop Entry]
Type=Application
Name[en_GB]=WireGuard
Categories=System;
X-GNOME-FullName[en_GB]=WireGuard
Comment[en_GB]=Toggle WireGuard
Icon=wireguard.png
NoDisplay=false
Exec=bash -c /home/$USER/.wireguard/wireguard.sh
Terminal=false
X-GNOME-UsesNotifications=true

The final step is to install a Gnome shell extension, WG Indicator from here.

This will add an indicator to your panel to show if wg0 is up or down.

Now you should find you can toggle your WireGuard interface up & down just by selecting WireGuard in your menu.

Which will bring up this dialogue box.

I have no doubt in the course of time that default WireGuard support will be implemented into Gnome in due course, but this is a quick and easy workaround in the meantime, for those of you that prefer the KDE Plasma desktop, I've heard that it already has support, but I haven't confirmed this.