Using Wireguard
Tags: wireguard, linux
Published: 2019-05-03 08:47:09

---
title: Using Wireguard
published: true
description: 
tags: wireguard, linux
---

[wireguard](https://www.wireguard.com/) is a modern, secure and fast vpn tunnel that is extremely simple to setup and works already nearly everywhere.

Since I spent a little bet to play with it because [this](https://git.zx2c4.com/wireguard-rs/about/) looked quite interesting, I thought of writing a small tutorial.

I normally use [Gentoo](https://gentoo.org) (and [macos](https://apple.com)) so this guide is about **Gentoo**.

## General concepts
Wireguard sets up **peers** identified by an [public key](https://en.wikipedia.org/wiki/Public-key_cryptography) and manages a [virtual network interface](https://en.wikipedia.org/wiki/TUN/TAP) and the routing across them (optionally).

The **server** is just a **peer** that knows about loots of peers while a **client** knows how to directly reach the **server** and that's it.

## Setting up in Gentoo
Wireguard on Linux is implemented as a kernel module. 

So in general you have to build the module and the userspace tools (`wg`).
If you want to have some advanced feature make sure that your kernel has the following settings:
> `IP_ADVANCED_ROUTER`
> `IP_MULTIPLE_TABLES`
> `NETFILTER_XT_MARK`

After that using `emerge` will get you all you need:
```
$ emerge wireguard
```

### Tools
The default distribution of tools come with the `wg` command and an helper script called `wg-quick` that  makes easier to bring up and down the virtual network interface.

```
wg help
Usage: wg <cmd> [<args>]

Available subcommands:
  show: Shows the current configuration and device information
  showconf: Shows the current configuration of a given WireGuard interface, for use with `setconf'
  set: Change the current configuration, add peers, remove peers, or change peers
  setconf: Applies a configuration file to a WireGuard interface
  addconf: Appends a configuration file to a WireGuard interface
  genkey: Generates a new private key and writes it to stdout
  genpsk: Generates a new preshared key and writes it to stdout
  pubkey: Reads a private key from stdin and writes a public key to stdout
You may pass `--help' to any of these subcommands to view usage.
```
```
Usage: wg-quick [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ]

  CONFIG_FILE is a configuration file, whose filename is the interface name
  followed by `.conf'. Otherwise, INTERFACE is an interface name, with
  configuration found at /etc/wireguard/INTERFACE.conf. It is to be readable
  by wg(8)'s `setconf' sub-command, with the exception of the following additions
  to the [Interface] section, which are handled by wg-quick:

  - Address: may be specified one or more times and contains one or more
    IP addresses (with an optional CIDR mask) to be set for the interface.
  - DNS: an optional DNS server to use while the device is up.
  - MTU: an optional MTU for the interface; if unspecified, auto-calculated.
  - Table: an optional routing table to which routes will be added; if
    unspecified or `auto', the default table is used. If `off', no routes
    are added.
  - PreUp, PostUp, PreDown, PostDown: script snippets which will be executed
    by bash(1) at the corresponding phases of the link, most commonly used
    to configure DNS. The string `%i' is expanded to INTERFACE.
  - SaveConfig: if set to `true', the configuration is saved from the current
    state of the interface upon shutdown.

See wg-quick(8) for more info and examples.
```
## Creating a configuration
Wireguard is quite straightforward, you can either prepare a configuration with your favourite text editor or generate one by setting by hand the *virtual network device* and then saving the result  `wg showconf` presents.

A configuration file then can be augmented with `wg-quick`-specific options (such as `Address`) or just passed to `wg setconf` while the other networking details are managed by your usual tools (e.g. [ip](https://wiki.gentoo.org/wiki/Iproute2)).

### Create your keys
The first step is to create the public-private key pair that identifies your *peer*.

- `wg genkey`  generates a private key for you.
- You feed it to
`wg pubkey` to have your public key.

In a single line:
```
$ wg genkey | tee privkey | wg pubkey > pubkey
```

 ### Prepare a configuration file
 Both `wg-quick` and `wg setconf` use an *ini-like* configuration file.
 
 If you put it in `/etc/wireguard/${ifname}.conf` then `wg-quick` would just need the interface name and would look it up for you.

The minimum configuration needs an `[Interface]` and a `[Peer]` set.
You may add additional *peers* later.
A *server* would specify its `ListenPort` and identify the *peers* by their `PublicKey`.
```
[Interface]
Address = 192.168.2.1/24
ListenPort = 51820
PrivateKey = <key>

[Peer]
PublicKey = <key>
AllowedIPs = 192.168.2.2/32
```

A *client* would have a *peer* with an `EndPoint` defined and optionally not specify the `ListenPort` in its *interface* description.

```
[Interface]
PrivateKey = <key>
Address = 192.168.2.2/24

[Peer]
PublicKey = <key>
AllowedIPs = 192.168.2.0/24
Endpoint = <ip>:<port>
```
The `AllowedIPs` mask let you specify how much you want to route over the *vpn*.
By setting `0.0.0.0/0` you tell you want to route ALL the traffic through it.

> **NOTE**: `Address` is a `wg-quick`-specific option.

### Using a configuration
`wg-quick` is really simple to use, assuming you have created `/etc/wireguard/wg0.conf`:
```
$ wg-quick up wg0
```
```
$ wg-quick down wg0
```

If you are using [netifrc](https://wiki.gentoo.org/wiki/Netifrc) from version `0.6.1` wireguard is supported and you can have a configuration such as:
```
config_wg0="192.168.2.4/24"
wireguard_wg0="/etc/wireguard/wg0.conf"
```
With the `wg0.conf` file like the above but stripped of the `wg-quick`-specific options.

## Summing up
Wireguard is a breeze to set up compared to nearly all the other *vpn* solutions.

Non-linux systems can currently use a [go implementation](https://git.zx2c4.com/wireguard-go/about/) and in the future a [rust implementation](https://git.zx2c4.com/wireguard-rs/about/) (help welcome).

[Android](https://play.google.com/store/apps/details?id=com.wireguard.android&hl=en_US) and [macos](https://itunes.apple.com/us/app/wireguard/id1451685025) have already some pretty front-ends that make the setup easy even on those platforms.

I hope you enjoyed it :)