Build a virtual private network with Wireguard

Wireguard is a new VPN designed as a replacement for IPSec and OpenVPN. Its design goal is to be simple and secure, and it takes advantage of recent technologies such as the Noise Protocol Framework. Some consider Wireguard’s ease of configuration akin to OpenSSH. This article shows you how to deploy and use it.

It is currently in active development, so it might not be the best for production machines. However, Wireguard is under consideration to be included into the Linux kernel. The design has been formally verified,* and proven to be secure against a number of threats.

When deploying Wireguard, keep your Fedora Linux system updated to the most recent version, since Wireguard does not have a stable release cadence.

Set the timezone

To check and set your timezone, first display current time information:

timedatectl

Then if needed, set the correct timezone, for example to Europe/London.

timedatectl set-timezone Europe/London

Note that your system’s real time clock (RTC) may continue to be set to UTC or another timezone.

Install Wireguard

To install, enable the COPR repository for the project and then install with dnf, using sudo:

$ sudo dnf copr enable jdoss/wireguard
$ sudo dnf install wireguard-dkms wireguard-tools

Once installed, two new commands become available, along with support for systemd:

  • wg: Configuration of wireguard interfaces
  • wg-quick Bringing up the VPN tunnels

Create the configuration directory for Wireguard, and apply a umask of 077. A umask of 077 allows read, write, and execute permission for the file’s owner (root), but prohibits read, write, and execute permission for everyone else.

mkdir /etc/wireguard
cd /etc/wireguard
umask 077

Generate Key Pairs

Generate the private key, then derive the public key from it.

$ wg genkey > /etc/wireguard/privkey
$ wg pubkey < /etc/wireguard/privkey > /etc/wireguard/publickey

Alternatively, this can be done in one go:

wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey

There is a vanity address generator, which might be of interest to some. You can also generate a pre-shared key to provide a level of quantum protection:

wg genpsk > psk

This will be the same value for both the server and client, so you only need to run the command once.

Configure Wireguard server and client

Both the client and server have an [Interface] option to specify the IP address assigned to the interface, along with the private keys.

Each peer (server and client) has a [Peer] section containing its respective PublicKey, along with the PresharedKey. Additionally, this block can list allowed IP addresses which can use the tunnel.

Server

A firewall rule is added when the interface is brought up, along with enabling masquerading. Make sure to note the /24 IPv4 address range within Interface, which differs from the client. Edit the /etc/wireguard/wg0.conf file as follows, using the IP address for your server for Address, and the client IP address in AllowedIPs.

[Interface]
Address    = 192.168.2.1/24, fd00:7::1/48
PrivateKey = <SERVER_PRIVATE_KEY>
PostUp     = firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade
PostDown   = firewall-cmd --zone=public --remove-port 51820/udp && firewall-cmd --zone=public --remove-masquerade
ListenPort = 51820

[Peer]
PublicKey    = <CLIENT_PUBLIC_KEY>
PresharedKey = LpI+UivLx1ZqbzjyRaWR2rWN20tbBsOroNdNnjKLMQ=
AllowedIPs   = 192.168.2.2/32, fd00:7::2/48

Allow forwarding of IP packets by adding the following to /etc/sysctl.conf:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Load the new settings:

$ sysctl -p

Forwarding will be preserved after a reboot.

Client

The client is very similar to the server config, but has an optional additional entry of PersistentKeepalive set to 30 seconds. This is to prevent NAT from causing issues, and depending on your setup might not be needed. Setting AllowedIPs to 0.0.0.0/0 will forward all traffic over the tunnel. Edit the client’s /etc/wireguard/wg0.conf file as follows, using your client’s IP address for Address and the server IP address at the Endpoint.

[Interface]
Address    = 192.168.2.2/32, fd00:7::2/48
PrivateKey = <CLIENT_PRIVATE_KEY>

[Peer]
PublicKey    = <SERVER_PUBLIC_KEY>
PresharedKey = LpI+UivLx1ZqbzjyRaWR2rWN20tbBsOroNdNnjWKLM=
AllowedIPs   = 0.0.0.0/0, ::/0

Endpoint     = <SERVER_IP>:51820
PersistentKeepalive = 30

Test Wireguard

Start and check the status of the tunnel on both the server and client:

$ systemctl start wg-quick@wg0
$ systemctl status wg-quick@wg0

To test the connections, try the following:

ping google.com
ping6 ipv6.google.com

Then check external IP addresses:

dig +short myip.opendns.com @resolver1.opendns.com
dig +short -6 myip.opendns.com aaaa @resolver1.ipv6-sandbox.opendns.com

* “Formally verified,” in this sense, means that the design has been proved to have mathematically correct messages and key secrecy, forward secrecy, mutual authentication, session uniqueness, channel binding, and resistance against replay, key compromise impersonation, and denial of server attacks.


Photo by Black Zheng on Unsplash.

For System Administrators Using Software

20 Comments

  1. SeeM

    All pieces in one convenient place. Thank You.

  2. Antti N.

    The main selling point of Wireguard is that it ties the network identity (IP address) to the device identity (PKI). While this makes it easier to secure applications via simple firewall rules, it’s also the main reason why it cannot by itself replace OpenVPN or IPSec in certain applications but requires running other tunneling protocols on top of it.

  3. Mace Moneta

    Why are you still using the COPR, when Wireguard has already been accepted into RPMFusion?

    • The copr repo is the official install method on the site and if there are issues with the RPM, I will do my best to to fix them. 😉

      • Yegor

        My wireguard-client has started crashing after kernel

        5.2.11-200.fc30.x86_64

        , so I stick to that kernel version. I really haven’t dug into the problem beyond

        systemctl status

        and

        journalctl -xb

        , just saw systemd service fails to start. Any idea how to debug?

        • Yegor

          Actually I found out that kernel isn’t rebuild by dkms hook, so I just reinstall “wireguard*” on kernel update.

  4. John Doe

    Newer computers come with UEFI. Anything on secure boot and kernel extensions and MOK list?

  5. Mace Moneta

    COPRs are temporary locations for software before they are accepted for a permanent home – which in the case of Wireguard has already happened. If Fedora itself decides to include Wireguard, it will move from RPMFusion to the Fedora repo. I don’t understand the purpose of maintaining a COPR; it seems out of process for Fedora.

    • @Mace: COPR is sometimes used in the way you describe, but not exclusively. COPR is not an official Fedora repository, though, so this has nothing to do with Fedora process. Ideally the COPR and RPMfusion maintainers can discuss how to handle, and if applicable, approach Wireguard to have official instructions updated.

  6. Bruno

    Hello Peter, good morning!
    So I tried to do exactly like you describe above. But when I finished I tried to up wg0 and the message was couldn’t find the Private Key. So I don’t know what I did wrong because it’s the same as you.
    Other thing when I create the arquive wg0.conf the configs from Server and Client are in the same arquive?
    I didn’t get this? Help

  7. Jack

    One character is missing in the end of client’s PresharedKey.

  8. Mehdi

    Thanks Peter for the article.
    That’s very invaluable piece of information.

  9. Jim

    Nice article, hope to try it out soon.

    Jim

  10. curious_one

    How is it, that preshared keys differ?

    • Scott Nash

      copy the preshared key you created into conf file.

  11. is posible using iodine as transport?

  12. John

    Can Wireguard be used to bypass a blocked website?

  13. Shawn

    Might be better to add a /etc/sysctl.conf.d/wireguard.conf file instead so the initial sysctl.conf isn’t touched.

  14. Shawn

    Make that /etc/sysctl.d/wireguard.conf but yes 🙂

  15. I have similar problem, but get different verbose output from modprobe:

    modprobe -vvv wireguard

    modprobe: INFO: custom logging function 0x55cf4e172a20 registered
    insmod /lib/modules/5.3.11-300.fc31.x86_64/kernel/net/wireguard.ko.xz
    modprobe: INFO: Failed to insert module ‘/lib/modules/5.3.11-300.fc31.x86_64/kernel/net/wireguard.ko.xz’: Operation not permitted
    modprobe: ERROR: could not insert ‘wireguard’: Operation not permitted
    modprobe: INFO: context 0x55cf4eb9b4c0 released

    Any ideas how to get wireguard module loaded? I removed it and rebuild it without success:

    dkms remove -m wireguard -v 0.0.20191012 -k 5.3.11-300.fc31.x86_64
    dkms install -m wireguard -v 0.0.20191012

    Any help us much appreciated.

Comments are Closed

The opinions expressed on this website are those of each author, not of the author's employer or of Red Hat. Fedora Magazine aspires to publish all content under a Creative Commons license but may not be able to do so in all cases. You are responsible for ensuring that you have the necessary permission to reuse any work on this site. The Fedora logo is a trademark of Red Hat, Inc. Terms and Conditions