Skip to content

tuckertwo/wireguard-conf-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Wireguard configuration tools

There are many tools that exist to configure Wireguard VPNs; some are simple, some complex; some are free, others are limited and exorbitant; and some may work, while others may not. These are mine. I wrote them to strike a specific balance with respect to complexity; I wanted something uncomplicated enough that I wouldn't have to do incredible amounts of setup and ad hoc work just to get a VPN running (so I intentionally left out automatic provisioning and config distribution), while also eliminating the tedious and error-prone work of manually copying configuration data from one file to another.

The tools operate on a JSON5 file; this format was chosen because JSON5 allows comments (and JSON doesn't, which is a stupid decision in my opinion) and also permits more liberal syntax without compromising integrity. This file is formatted as an array of objects (associative arrays); each object represents a host in the network. Annotated examples are below.

There are, at the moment, two tools in use: keys.py and files.py. Both take JSON5 input on STDIN, and keys.py sends JSON5 output to STDOUT.

After writing a config file for the first time, or after adding new hosts, pipe it to keys.py to populate it with public/private keypairs. This script is idempotent—that is, it will never modify hosts that already have keypairs.

Once all hosts have keys, pipe the populated JSON5 configuration file to files.py. For every host in the configuration file, files.py will write a WireGuard configuration to <sname>.conf; furthermore, for phones, files.py will create a QR code with the configuration at <sname>.svg. After these files are generated, it is your responsibility to distribute and update them. Good luck!

System requirements

This script has, thus far, only been tested on Linux and FreeBSD, but there is no inherent reason for it not to work on other systems. My WireGuard configuration tools require the latest version of Python 3, along with the below packages (I recommend to install them with conda):

  • nacl (for keys.py)
  • json5
  • qrcode (for files.py)

Configuration files

A JSON5 configuration file must be an array of objects with the following keys; each object represents a host.

Key Type Description Remarks
name String The long name of the host. Used to populate the friendly_name field used by the WireGuard Promethius exporter among others. Required.
sname String The short name of the host. Gives its name to the WireGuard configs generated by files.py. Required.
server Boolean Whether or not this host is a server. Required.
primary Boolean Whether or not this host is the primary server. Required for servers.
phone Boolean Whether or not this host is running the WireGuard iOS or Android app. files.py will generate QR codes for phones. Required.
ips Array of IP/CIDR values The IPs of a host. Servers automatically own the entire subnet; other hosts simply own one IP. Required.
hostname IP or DNS name The hostname of a host. Required for servers, optional for all others.
port An integer between 0 and 65535, inclusive. The port that WireGuard is to listen on. Required if hostname is set; optional otherwise. Can be set when hostname is unset.
addl_nets Array of IP/CIDR values (as strings) Lists additional subnets handled by this host. Optional.

Routing stuff

All hosts directly route to servers, and vice versa. That is, they route traffic directly from one host to another over the public Internet. When non-server hosts send packets to each other, they must route them through the primary server; needless to say, the primary must have an appropriately-configured firewall. Furthermore, packets sent to subnets listed in a host's addl_nets key are unconditionally routed thereto.

Examples of host objects

A server

  {
    "name": "Expensive server",
    "sname": "short_name",
    "server": true,
    "primary": true,
    "phone": false,
    "ips": [
      "10.84.0.1/16",
      "fdf9:167d:2a5a::1/112"
    ],
    "hostname": "adams.example.com",
    "port": 50000
  },

A client

  {
    // The spectral desktop has no fixed location and does not seem to exist,
    // but it is kept on the VPN to appease the WireGods.
    "name": "Spectral desktop", 
    "sname": "spectral",
    "server": false,
    "primary": false,
    "phone": false,
    "ips": [
      "10.84.0.2/16",
      "fdf9:167d:2a5a::2/112"
    ],
    "hostname": "foo.bar.org",
    "port": 50000
  },

WireGuard observations

  • WireGuard has terrible documentation, but is otherwise an excellent, reliable, and secure VPN system.
  • wg-quick will take care of most WireGuard setup necessary, including the setup of the wgn network interface and routing table stuff.
  • Configuring alternate routing (i.e. using an Ethernet connection for a particular subnet but falling back on WireGuard when not available) is possible, but extremely difficult. Woe betide those who try it.
  • Phone apps work well, but will not accept configuration files that have entries that they don't recognize (like SaveConfig).
  • Configuration files are pretty simple TOML/INI files. If I had known that, I would've used a library to write those files.
  • There are many ways to bring up WireGuard interfaces on boot. On Ubuntu, use NetworkManager; on Void, use the wireguard service that comes with the WireGuard tools; on FreeBSD, put the config files in /etc/wireguard and use a custom RC script.

About

Simple tools for generating WireGuard configuration files

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages