⊕ 2017-05-20
## EDITED: 2017-07-15In the never ending hunt for the ideal VPN software we recently got to play with WireGuard, which has become a quick favourite. This text will serve as a quick-start guide for setting up a OpenVPN-esque default gateway server and a roaming client.
WireGuard offers some extremely powerful features that set it apart from the competition:
ip(8)
userspace utilitiesAfter installing WireGuard, it is necessary to generate keys on both hosts.
1$ umask 077 && mkdir -p /etc/wireguard && cd /etc/wireguard
2$ wg genkey | tee privatekey | wg pubkey > publickey
Next the server needs a configuration file, we will set the listening port to 51820
and allow the client to connect from any IP address. Replace SERVER_PRIVATE_KEY with the servers previously generated key and CLIENT_PUBLIC_KEY with the clients public key, both are base64 encoded strings.
1[Interface]
2ListenPort = 51820
3PrivateKey = SERVER_PRIVATE_KEY
4
5[Peer]
6PublicKey = CLIENT_PUBLIC_KEY
7AllowedIPs = 0.0.0.0/0
Now that we have a configuration we need to set up the interfaces and ensure the server can route the clients with an iptables
NAT rule. Do not forget to make this rule persistent across reboots. The internal network will be set to 10.13.0.0/24
and the server will have an internal IP of 10.13.0.1
, and should be changed to suite the needs of the network.
1# ip link add dev wg0 type wireguard
2# ip address add dev wg0 10.13.0.1/24
3# ip link set wg0 up
4# wg setconf wg0 /etc/wireguard/wg0.conf
5# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
6# sysctl net.ipv4.ip_forward = 1
7# printf "sysctl net.ipv4.ip_forward = 1\n" >> /etc/sysctl.conf
The client is configured in a very similar manner as the server, but it needs to know the IP of the server. Setting the PersistentKeepalive
is optional, but WireGuard is purposefully as silent in its default configuration and if a client is idle on a NAT the connection may be interrupted. This option prevents that by sending a keep alive every declared seconds. Replace CLIENT_PRIVATE_KEY with the clients previously generated key and SERVER_PUBLIC_KEY with the servers public key.
1[Interface]
2ListenPort = 51820
3PrivateKey = CLIENT_PRIVATE_KEY
4
5[Peer]
6PublicKey = SERVER_PUBLIC_KEY
7AllowedIPs = 0.0.0.0/0
8Endpoint = 198.51.100.67:51820
9PersistentKeepalive = 25
Now we initialize the interfaces and set the configuration. The client in this example will have an internal IP of 10.13.0.100
on the same subnet as declared on the server.
1# ip link add dev wg0 type wireguard
2# ip address add dev wg0 10.13.0.100/24
3# ip link set wg0 up
4# wg setconf wg0 /etc/wireguard/wg0.conf
Finally, the client needs to set its default routes (or which ever routes that are necessary) to the server. This requires knowing the original gateway and the IP of the server, in this example the gateway is 192.168.1.1
and the server IP is 198.51.100.67
.
1# ip route add 198.51.100.67 via 192.168.1.1
2# ip route del default
3# ip route add default dev wg0
NOTE: It is important understand that this configuration does will leak DNS requests if the original DHCP acquired DNS server is still routable. To prevent this set a nameserver
in /etc/resolv.conf
to an internal VPN host or to a trusted DNS server elsewhere. There is also the problem of default routes being changed when reconnecting to a wireless network, so there is some manual configuration that may need to be done.
After the server and client are set up the configuration and status can be checked with the wg(8)
utility, if everything was configured properly an example of output on the server would look like the following.
1# wg
2interface: wg0
3 public key: jHhuAqsPKZC25/zjQ9G+1JEGO2FglLxqq4t8gWWW73U=
4 private key: (hidden)
5 listening port: 51820
6
7peer: f2LdqRAog0FfdCbdZLkGKdJfPBkwrSt8XKl1kG8N2Vg=
8 endpoint: 203.0.113.161:4135
9 allowed ips: 0.0.0.0/0
10 latest handshake: 8 seconds ago
11 transfer: 4.40 MiB received, 322.38 MiB sent
The final step is adding the configuration to the default network configuration so that it starts at reboot. This step may be different depending on what distribution of Linux being used, this example will be using /etc/network/interfaces
on the server.
1auto wg0
2iface wg0 inet static
3 pre-up ip link add dev wg0 type wireguard
4 post-up wg setconf wg0 /etc/wireguard/wg0.conf
5 post-up ip link set dev wg0 up
6 address 10.13.0.1
7 netmask 255.255.255.0
If everything is routing properly just check the external IP matches the server, if not traceroute
can help debug any potential issues.