I’ve started using WireGuard and I noticed a few niceties missing when compared to OpenVPN, the biggest of them being not having a half-convenient key management scheme, so it only made sense to make a script to ease things up.

You may download the script right away.

When using OpenVPN you are required to have a PKI set up. Using the easy-rsa scripts the process of adding and removing authorized users is straightforward using the signed keys (for adding users) and the certificate revocation list (for kicking them out).

On wireguard this doesn’t exist as of today. Keys are stand-alone and not signed by the server, requiring you to add every single client public key to the server configuration, so I decided I wanted something similar to OpenVPN’s easy-rsa script for adding and removing users from a Wireguard config file.

wg-helper

wg-helper is a shell script that eases the creation of WireGuard configuration and client management.

Starting up

First, download the script and unzip it somewhere on your machine, for example at the ~/wg/ directory. This script depends on the wg tool being installed and available on your PATH. Many distros will provide a package for it.

Then we need to edit the wg0.conf.base config file, which contains the server configuration excluding the PrivateKey config. The sample wg0.conf.base looks like this:

[Interface]
Address = 172.32.0.1/24
SaveConfig = true
ListenPort = 51820

This config will make the WireGuard interface use the 172.32.0.0/24 subnet and assign the 172.32.0.1 address to it. Hence, peers on the VPN network must have an address within the /24 subnet.

Before starting the creation of any keys, wg-helper.sh needs to be edited to at least have a default allowed address for when a per-client address is not defined. So we open wg-helper.sh on a text editor:

#!/bin/sh

OUT_CONFIG="wg0.conf"
BASE_CONFIG="wg0.conf.base"
CLIENT_IPS="client-addresses.txt"
EXE=`basename "$0"`
DEFAULT_IP='172.32.0.0/24'

And edit the DEFAULT_IP variable to match the subnet selected on the wg0.conf.base file, on this example, it is 172.32.0.0/24.

Creating server keys

The wg-helper.sh script provides the following commands, as shown when running ./wg-helper.sh -h:

Usage: wg-helper.sh <COMMAND> [...]

Available Commands:
  gen-config        Generates the wg0.conf file
  gen-server        Generates server key
  add-client <NAME> Generates client key; It will be used on next gen-config
  del-client <NAME> Removes client key

To create the server keys we simply run ./wg-helper.sh gen-server after which a directory named server containing server.key and server.pub files, which contain the private and public key of the server respectively. A sample output would look like:

$ ./wg-helper.sh gen-server
$ cat server/server.key server/server.pub
8JSDPMnUBmNJBV++QMIQpaMQv9QavIZ8p6la7n2bFEs=
5CfkEnC83RnBIZX4N21P94FzTuFDvmPS1X+DEvPvXiY=

The server.pub key is what peer configurations must set on their PublicKey attribute.

Creating a client

The process to create a client is similar to creating the server keys, only this time a user name is required. Running ./wg-helper.sh add-client user-001 will create a clients directory (if not existing) and a user-001.key and user-001.pub files containing the client private and public key respectively. A sample output would look like:

$ ./wg-helper.sh add-client user-001
$ cat clients/user-001.key clients/user-001.pub
YJ2WxYUx29ai+zKSN5j2KhkgLfFhThsNWmYcHcfd1mY=
eOW9hzTRIQBm3LN9JYPYGp7PmZVzcvo5vT3pBHIoIWI=

The .key will be used on the client config file, while the .pub will be used by this script to generate the server configuration.

Generating the server configuration

Once a base configuration, a server key, and one or more clients are created, we can generate the server configuration file using the ./wg-helper.sh gen-config command. The output of which will look like:

$ ./wg-helper.sh gen-config
Generating wg0.conf
  - Adding client user-001
  - Adding client user-002
  - Adding client user-003
  - Adding client user-004

After which, the file wg0.conf (or whatever you configured on the script) will be created or updated. The contents of the wg0.conf file will look like somewhat like this:

[Interface]
Address = 172.32.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = 8JSDPMnUBmNJBV++QMIQpaMQv9QavIZ8p6la7n2bFEs=

#user-001
[peer]
PublicKey = eOW9hzTRIQBm3LN9JYPYGp7PmZVzcvo5vT3pBHIoIWI=
AllowedIPs = 172.32.0.0/24

#user-002
[peer]
PublicKey = 0hMknaJqn/+a8qRtSaaWKyuvEzaZiz3RRNFp69QzJk8=
AllowedIPs = 172.32.0.0/24

#user-003
[peer]
PublicKey = VExpZFZQc9A/aihKqGoNvN+PePdspL+/Rut1X6MxiTQ=
AllowedIPs = 172.32.0.0/24

#user-004
[peer]
PublicKey = ixaUYSIEgsnyKuzV+BLsAlcOadi4Bb0bGLSf9P/do0Q=
AllowedIPs = 172.32.0.0/24

This file can then be copied to /etc/wireguard/ and brought up with wg-quick up wg0. Clients may choose any IP on the 172.32.0.0/24 subnet. If you want to make sure each peer is allowed one and only one IP address, check the next section.

Assigning IP addresses to clients

Each client may be assigned an individual IP address by overriding the AllowedIPs attribute, to make things easier, wg-helper.sh may look at a list of <ADDRESS>:<CLIENT> pairs stored on the client-addresses.txt file. For example, if we want to give user-004 the 172.32.0.200/32 address, we shall append the following line to the client-addresses.txt file.

172.32.0.200/32:user-004

Then after saving and running ./wg-helper.sh gen-config

$ ./wg-helper.sh gen-config
Generating wg0.conf
  - Adding client user-001
  - Adding client user-002
  - Adding client user-003
  - Adding client user-004 (with address 172.32.0.200/32)

The [peer] entry for user-004 will look like this:

#user-004
[peer]
PublicKey = ixaUYSIEgsnyKuzV+BLsAlcOadi4Bb0bGLSf9P/do0Q=
AllowedIPs = 172.32.0.200/32

Restricting the client IP address to 172.32.0.200.

Removing a client

To remove clients just run ./wg-helper.sh del-client <CLIENT> and then regenerate the configuration file with ./wg-helper.sh gen-config. This will remove the keys from the clients directory.

To sum up…

This is just a helper script for making more convenient the most basic of WireGuard configuration, I hope it will be useful for someone out there.

Revision history

Rev. Description Download
Rev.1 Initial release ZIP
Rev.2 Added client config generation ZIP