Since VPNs Are Getting Hacked, Build Your Own

ScytheSalvation

*Nix Master
Registered
Build a virtual private network with Wireguard

Posted by Peter Maynard on October 28, 2019




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.
 
Back
Top