wireguard 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 looked quite interesting, I thought of writing a small tutorial.
I normally use Gentoo (and macos) so this guide is about Gentoo.
Wireguard sets up peers identified by an public key and manages a virtual network interface 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 (
If you want to have some advanced feature make sure that your kernel has the following settings:
After that using
emerge will get you all you need:
$ emerge wireguard
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).
Create your keys
The first step is to create the public-private key pair that identifies your peer.
wg genkeygenerates a private key for you.
- You feed it to
wg pubkeyto have your public key.
In a single line:
$ wg genkey | tee privkey | wg pubkey > pubkey
Prepare a configuration file
wg setconf use an ini-like configuration file.
If you put it in
wg-quick would just need the interface name and would look it up for you.
The minimum configuration needs an
[Interface] and a
You may add additional peers later.
A server would specify its
ListenPort and identify the peers by their
[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>
AllowedIPs mask let you specify how much you want to route over the vpn.
0.0.0.0/0 you tell you want to route ALL the traffic through it.
Using a configuration
wg-quick is really simple to use, assuming you have created
$ wg-quick up wg0
$ wg-quick down wg0
If you are using netifrc from version
0.6.1 wireguard is supported and you can have a configuration such as:
wg0.conf file like the above but stripped of the
Wireguard is a breeze to set up compared to nearly all the other vpn solutions.
Non-linux systems can currently use a go implementation and in the future a rust implementation (help welcome).
Android and macos have already some pretty front-ends that make the setup easy even on those platforms.
I hope you enjoyed it 🙂