2021-03-03
md
Installing WireGuard on openmediavault 5.6.1 (March 2021)
<-Installing and Configuring WireGuard on Raspberry Pi OS (January 2021)

While building a network-attached storage (NAS) device based on openmediavault (omv), I wanted to add a virtual private network (VPN) server to provide secure remote access to the NAS and to other resources on the local network. This made sense to me because currently the NAS will be left on at all times. Of course the VPN server will be WireGuard because of my past experience with it. In essence then, I wanted to duplicate what was done with the Raspberry Pi hosting my home automation system on a Intel Core i5-2400 system. Since both Raspberry Pi OS and omv are based on Debian, the procedure to install the VPN is almost identical on both systems as will be shown below.

This is all experimental. In the near future, the local network will be revamped. The plan calls for the addition of a firewall, probably based on pfSense, and the segregation of devices into different VLANs (written, as if I know what I'm talking about!) Clearly, some thought will have to be given to remote access. Time will tell if changes to the VPN servers are required.

Table of Contents

  1. Re-inventing the Wheel
  2. Installing WireGuard
  3. Configuring WireGuard
    1. Installing the Adrian Mihalko User Management Script
    2. Generating the Private and Public Server Keys
    3. Creating and Editing the Server Definition File
    4. Editing the Client Configuration Template
    5. Editing the Server Configuration Template
    6. Managing the WireGuard Service
  4. Managing Users and Using the VPN

Re-inventing the Wheel toc

Someone had probably added WireGuard in omv. So I did a quick search and found the beta openmediavault-wireguard plugin. However, development seems to be halted since there has been only one commit in the last 18 months, and that was almost exactly a year ago.

There is also a June 30, 2019 forum discussion [HowTo] WireGuard with omv Super-Easy by henfri with many replies. The discussion starts with an installation script by henfri. I have not used it as it is not as complete as the Adrian Mihalko script which has worked very well on a Raspberry Pi and works just as well in Debian. If the henfri script is used, be aware that it uses UPnP to forward the necessary UDP port at the router. Many recommend disabling UPnP altogether, so perhaps one should forward the port manually or disable UPnP once WireGuard has been installed.

Finally, I will mention the OpenVPN plugin, openmediavault-openvpn 5.1, found in the usual in the OMV-Extras.org channel. That usually means juggling CA certificates and other complications, but there are advantages to this older VPN, although I will not go into that topic here. I have not tested this plugin.

This was a cursory search and I apologize to everyone whose contribution has been overlooked.

Installing WireGuard toc

Installing openmediavault on a second generation i5 computer was fairly straightforward following the instructions in the New User Guide - Getting Started with Openmediavault 5. As recommended, all the configuration was done with the omv Web-based administration tool, including defining the host name (vault in my case), setting up a static IP address, doing system updates and so on. But when I wanted to install a WireGuard VPN, I had to return to the command line and use standard Debian tools.

Version 5.6.1 of omv released February 27, 2021 is based on Debian 10.8 with version 5.10.0 of the Linux kernel. Given that this version of Debian was released on February 6, 2021, it was not too surprising that installing wireguard was quite straight forward. In what follows, I opened an SSH session as root from a terminal on my desktop.

michel@hp:~$ ssh root@vault.local root@vault.local's password: xxxxxx not shown on screen Linux vault.local 5.10.0-0.bpo.3-amd64 #1 SMP Debian 5.10.13-1~bpo10+1 (2021-02-11) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Tue Mar 2 14:10:20 2021 from 192.168.1.132 root@vault:~# pwd /root root@vault:~#

Using a terminal from a Linux desktop to the omv machine is very simple: all that is required is to press the hotkey combination (usually AltT) to bring up a terminal emulator and then entering the ssh command as shown above. Perhaps those using a different desktop operating system might want to use a terminal emulator in a Web browser. There was a plugin called shellinabox for just that purpose in omv 4. This is no longer available in omv 5 as far as I can determine. There are recommendations to use Dockerized Wetty (weTTY in a Docker) as a replacement for the plugin. I do not have experience with either of these approaches.

Even though a user was added in omv, made a member of the important groups (users, adm, sudo etc.), no directory for that user was created in the home directory. That is why I logged in as root as shown above which is something I rarely do. In any case, the WireGuard installation requires root privileges, so this will eliminate the need for the sudo prefix usually needed when installing packages.

Once logged in, I checked that WireGuard was not already present, and then just installed it from the buster-backports repository. Contrary to past installations in Raspbian and a recent installation in Rasbpberry Pi OS, this was done with a single install command.

root@vault:~# which wg root@vault:~# apt install wireguard -y Reading package lists... Done ... The following NEW packages will be installed: wireguard wireguard-tools 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 95.6 kB of archives. After this operation, 344 kB of additional disk space will be used. Get:1 http://httpredir.debian.org/debian buster-backports/main amd64 wireguard-tools amd64 1.0.20200827-1~bpo10+1 [87.4 kB] Get:2 http://httpredir.debian.org/debian buster-backports/main amd64 wireguard all 1.0.20200827-1~bpo10+1 [8,192 B] Fetched 95.6 kB in 1s (86.2 kB/s) ... Setting up wireguard (1.0.20200827-1~bpo10+1) ...

Unlike on the Raspberry Pi, the installation was completed in a short time. A quick check verified that the tools were now available. As a further test, the VPN server was started with an empty configuration file.

root@vault:~# which wg wg-quick /usr/bin/wg /usr/bin/wg-quick root@vault:# touch /etc/wireguard/wg0.conf root@vault:# wg-quick up wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip link set mtu 1420 up dev wg0

From there, it is easy enough to check that the WireGuard interface was created and that the VPN server was listening for incoming connections.

root@vault:~# ip a ... 2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether ... 3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none root@vault:# wg interface: wg0 listening port: 55129

Of course, that last command, wg, did not display much information because no connection was established. Because the Ethernet interface on my system it named eno1 instead of the classic eth0, it will be necessary to adapt configuration script later on.

Configuring WireGuard toc

It is necessary to configure Wireguard in order to do anything useful. In the past I used a script by Adrian Mihalko to easily configure WireGuard on the Raspberry Pi. There is nothing in that script that is really Pi centric and it works just as well in the Debian distribution hosting omv. It would be worthwhile to read User management with Wireguard User Management Script written by Adrian Milhalko and return here for more information if needed.

It may be useful to raise a little point here. WireGuard operates a peer-to-peer network. However it is sometimes useful to look at it as a client-server model, such as here where the WireGuard peer running on the omv machine is viewed as a server and the WireGuard peers on various Linux and Android devices are viewed as clients. In the end, peer, server, client and user are all the same thing. Hopefully that will not be a source of confusion.

Installing the Adrian Mihalko User Management Script toc

There are a couple of prerequisites to install: unzip to extract the script from a downloaded .zip archive and qrencode used to generate QR-code images that will make it very easy to configure WireGuard clients on Android and iOS devices.

root@vault:~# apt install unzip ... 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 172 kB of archives. After this operation, 580 kB of additional disk space will be used. ... root@vault:~# apt install qrencode -y ... Need to get 78.0 kB of archives. After this operation, 168 kB of additional disk space will be used. ...

Next the archive containing the script and supporting files needs to be downloaded and its content has to be extracted to a directory that will be called wp_config or any other desired name.

root@vault:~# wget https://github.com/adrianmihalko/wg_config/archive/master.zip ... root@vault:~# unzip -j master.zip -d wg_config ... root@vault:~# mkdir downloads root@vault:~# mv master.zip downloads/wg_config_script.zip

In those last two steps a /root/downloads directory was created and the script archive was moved into it while changing its name to something more meaningful. Instead, it would have been fine to just delete the archive.

Generating the Private and Public Server Keys toc

WireGuard encrypts the data exchanged over the virtual network. Much like SSH, asymmetric encryption is used to set up the secure session. Both server and client (or peers actually) have private and public keys, but only the latter are exchanged for authentication. Again, like SSH, the private keys have to be shared "out-of-band" beforehand. In this case that means that the keys must be manually copied to each peer configuration file. There is no third party "certificate authority" for SSL certificates as when using HTTPS or OpenVPN.

The first step, which is done only once, is to generate the private and public keys of the WireGuard server on the machine.

root@vault:~# cd wg_config root@vault:~/wg_config# wg genkey | tee server_private.key | wg pubkey > server_public.key

These two keys are needed in the next steps. Copy them into a text editor on the desktop or open a second SSH session on the Raspberry Pi for easy access to the keys later.

root@vault:~/wg_config# cat server_public.key AdBZoYYSWjPiZV8fxbN62a4TK8cSDNDKQoAmA73t3qX= root@vault:~/wg_config# cat server_private.key 9H95vdg34DUCbFayzv6syJYWWtmA337DGsnX374YUoQ=

Normally, one never makes the private key public. So the keys shown above are only for demonstration purposes, and you must replace those values with the one actually generated.

Creating and Editing the Server Definition File toc

This step, performed once only, creates the wg.def file which contains data the script will use to make the server and client configuration files.

root@vault:~# ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eno1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 50:65:f3:1b:7a:22 brd ff:ff:ff:ff:ff:ff inet 192.168.1.17/24 brd 192.168.1.255 scope global eno1 valid_lft forever preferred_lft forever
root@vault:~/wg_config# cp wg.def.sample wg.def root@vault:~/wg_config# nano wg.def

This is the original content.

_INTERFACE=wg0 _VPN_NET=192.168.99.0/24 _SERVER_PORT=51820 _SERVER_LISTEN=wg.example.com:$_SERVER_PORT _SERVER_PUBLIC_KEY= _SERVER_PRIVATE_KEY=

And this is how I changed it.

_INTERFACE=wg0 _VPN_NET=192.168.199.0/24 _SERVER_PORT=53122 _SERVER_LISTEN=modomo.twilightparadox.com:$_SERVER_PORT _SERVER_PUBLIC_KEY=AdBZoYYSWjPiZV8fxbN62a4TK8cSDNDKQoAmA73t3qX= _SERVER_PRIVATE_KEY=9H95vdg34DUCbFayzv6syJYWWtmA337DGsnX374YUoQ=

Note the change of the "private" WireGuard subnet from the suggested 192.168.99.0/24 to 192.168.199.0/24. This is because WireGuard is already running on a Raspberry Pi at 192.168.99.1. The _SERVER_PORT is the UDP port that will have to be forwarded to the WireGuard sever by the LAN router or gateway. This can be (perhaps should be) changed. And, of course, it is necessary to change wg.example.com in _SERVER_LISTEN to the host name of the Raspberry Pi which, in my (fictitious) case, is: modomo.twilightparadox.com as explained in 2.2 Public IP Address or Dynamic Host Name. Enter just the domain name without a protocol specifier such as https://. As I explained above, the public IP address assigned to me by my ISP changes so rarely that I could get away with the public IP address instead of a host name for testing purposes!

If the CIDR notation 192.168.99.0/24 is not familiar, just think of the trailing integer after the slash as the number of fixed most significant 1 bits in the subnet mask. Well, that's really clear. Perhaps working out the example will help. The subnet mask is 32 bits (or 4 bytes) of which the most significant 24 are 1s and the least significant 8 bits are 0. Hence the mask is 255.255.255.0. So the virtual network peers will have IP addresses in the 192.168.99.xxx block. The server will be at 192.168.99.1, the first client at 192.168.99.2, the second at 192.168.99.3 and so on. The script will handle this sequential allocation of IP addresses automatically.

It is not necessary to have a second VPN on a completely different "private" subnet as I have done above. At one point in my initial testing of WireGuard, there were three servers with "private" WireGuard IP addresses at 192.168.99.1, 192.168.99.101, and 192.168.99.151 on three different single-board computers. Android and Linux clients could connect to each without problems. Nevertheless, this time I chose different subnets altogether to avoid unnecessary complications. Whatever "private" subnet is chosen, care must be taken to avoid IP address collisions with any device already on the local network.

Editing the Client Configuration Template toc

The client configuration template, client.conf.tpl, used by the script to create each user (or client) configuration file is quite short.

[Interface] Address = $_VPN_IP PrivateKey = $_PRIVATE_KEY [Peer] PublicKey = $_SERVER_PUBLIC_KEY AllowedIPs = 0.0.0.0/0 Endpoint = $_SERVER_LISTEN

I changed the AllowdIPs.

root@vault:~/wg_config# nano client.conf.tpl

[Interface] Address = $_VPN_IP PrivateKey = $_PRIVATE_KEY [Peer] PublicKey = $_SERVER_PUBLIC_KEY AllowedIPs = 192.168.199.1/32, 192.168.1.0/24 Endpoint = $_SERVER_LISTEN

Note that the first AllowedIPs (192.168.99.1/32) is the address of the Wireguard server on the virtual network and the 32-bit mask means that the client/user will not be able to reach any other IP address on the 192.168.99.xx subnet. The second allowed IP address 192.168.1.0/24, which is the 192.168.1.xxx block of IP addresses corresponding to my home local network. The Raspberry Pi has a static IP address on that network: 192.168.1.22, the ISP supplied cable modem/router is at 192.168.1.1 and its integrated DHCP server allocates IP addresses in the 192.168.1.100-200 range where most of my IoT devices can be found. You will, of course, have to adjust the AllowedIPs to refer to the correct IP addresses in your particular situation. It could be that your LAN is on subnet 192.168.1.xxx as suggest above, or 192.168.0.xxx, but some LANs use other blocks of private IPv4 addresses such as 10.0.3.xxx.

Editing the Server Configuration Template toc

In the server configuration template, it is assumed that the name of the network interface used by the host of the WireGuard server is eth0. In my case that is not correct, the Ethernet interface is named eno1 as we saw before, so it was necessary to edit the sever configuration template.

root@vault:~/wg_config# nano server.conf.tpl
[Interface] Address = $_SERVER_IP ListenPort = $_SERVER_PORT PrivateKey = $_SERVER_PRIVATE_KEY PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eno1 -j MASQUERADE

The eth0 interface is replaced by eno1 in the PostUp and PostDown lines that define changes to the server iptables when activating or deactivating the VPN.

Again, this change needs to be done once only if at all.

Managing the WireGuard Service toc

When first installing WireGuard and when testing the installation of the server, it is useful to manually start and stop the service. This is done with the wg-quick utility.

root@vault:~# wg-quick up wg0 [#] ip link add wg0 type wireguard [#] wg setconf wg0 /dev/fd/63 [#] ip -4 address add 192.168.199.1/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE

Again when testing, it may be of value to check on the status of the VPN server. This can be done with the systemd control utility and with the wg utility.

root@vault:~# systemctl status wg-quick@wg0 ● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0 Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled) Active: active (exited) since Tue 2021-03-02 13:39:58 AST; 22h ago Docs: man:wg-quick(8) man:wg(8) https://www.wireguard.com/ https://www.wireguard.com/quickstart/ https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8 https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8 Main PID: 621 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 4915) Memory: 0B CGroup: /system.slice/system-wg\x2dquick.slice/wg-quick@wg0.service Mar 02 13:39:52 vault.local systemd[1]: Starting WireGuard via wg-quick(8) for wg0... ... root@vault:~# wg interface: wg0 public key: AdBZoYYSWjPiZV8fxbN62a4TK8cSDNDKQoAmA73t3qX= private key: (hidden) listening port: 53122

The above is only an indication of the information that may be displayed. It will depend on the number of peers/clients that have been set up. Even more information will be displayed when a client or peer has created a tunnel (i.e. opened a VPN connection) including the number of bytes transmitted and received through the connection.

Once WireGuard is properly installed, the service should be started automatically. This is done with the usual systemctl command.

root@vault:~# sudo systemctl enable wg-quick@wg0 Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service.

This is usually done only once. From then on, whenever the computer is booted, systemd will start the VPN server. If for some reason the WireGuard service should no longer be automatically started, use the disable command.

root@vault:~# sudo systemctl disable wg-quick@wg0 Removed /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service.

It will be possible to enable the service again later. If one thinks about it, a VPN server should really be functioning at all times.

Managing Users and Using the VPN toc

I have already covered in much detail the use of the Mihalko user.sh script to add or delete users in the WireGuard configuration. In the same post, there are descriptions of how to set up WireGuard clients in Android, Linux and Windows. The post also contains a quick explanation of how to use these clients with the WireGuard VPN. The original file by Adrian Mihalko contains instructions for setting up an iOS client.

There is more to using a self-hosted VPN. Again, my previous post about using WireGuard in Raspberry Pi OS contains information about the need to set up a static IP address for the omv machine (something easily done in omv, by the way), the interest in creating a dynamic host name in order to reach the machine from outside the local network. How to forward the UDP port used by WireGuard at the router is described in the post. Enabling IP forwarding is also described in the post. That is needed if the VPN is used to access resources over the local area network not installed on the omv server.

<-Installing and Configuring WireGuard on Raspberry Pi OS (January 2021)