Ever since Linus Torvalds praised Wireguard, I’ve been wanting to try it out.
Last week I finally got around to play with it, and boy was it easy and elegant to set up.
It was really easy to set up, it took me longer to write this blog post than to set up wireguard on 3 peers.
I used a Fedora Server as a first endpoint and my Fedora Workstation as a second endpoint.
Later on I also easily added my Android phone as a third endpoint, and set up the Fedora Server as a VPN server (routing traffic to the internal and external networks).
Let me walk you through the setup steps.
We need to install wireguard first as it is not yet part of the mainline kernel.
On the Fedora Server and Workstation:
sudo dnf copr enable jdoss/wireguard sudo dnf install wireguard-dkms wireguard-tools
Setting up the endpoints
As you will see below the setup is very similar for both endpoints.
Note the difference in IP addresses.
We will choose a static tunnel IP per host in the 10.0.0.0/24 range, but it could be any range of your choosing.
Create a keypair on each host:
wg genkey > private wg pubkey < private
Take note of the public key to configure your other client later on.
Our first endpoint has a private IP address of 192.168.2.1/24 on enp2s0, adapt it to match your machine’s private IP address.
ip link add dev wg0 type wireguard ip address add dev wg0 10.0.0.1/24 wg set wg0 listen-port 51820 private-key ./private
wg set wg0 peer <peer2-public-key> allowed-ips 10.0.0.2/32 endpoint <peer2-pulic-ip>:51820 ip link set wg0 up
allowed-ips setting denotes what network lies at the other end of the tunnel.
Routes will automatically be set up towards these networks when the interface becomes active.
As a starting point we can use the other peer’s tunnel IP address.
ip link add dev wg0 type wireguard ip address add dev wg0 10.0.0.2/24 wg set wg0 listen-port 51820 private-key ./private
wg set wg0 peer <peer2-public-key> allowed-ips 10.0.0.1/24 endpoint <peer1-pulic-ip>:51820 ip link set wg0 up
At this point you should be able to ping the other endpoint his 10.0.0.x address after the interface is up.
wg command should show you some useful output as well.
Remember when doing tcpdump and forwarding ports, the connection is over UDP, not TCP!
Hint if you run with firewalld enabled:
firewall-cmd --add-port 51820/udp, see Additional Settings below to do this automatically.
NAT and Dynamic endpoint IP address
If you are, like me, trying to set up your laptop to connect to a remote server, your public IP will most definitely change a lot.
The solution to this is to use Dynamic DNS and use this DNS name in your endpoint configuration.
Even on Android there is an app for that.
Also, there is a setting called
persistent-keepalive that will assist firewalls to keep the tunnel alive.
The CLI tools are nice and all, but I want the VPN link to come up with my Fedora Server and easily bring up the connection with one commmand on my Workstation.
wg-quick has got you covered.
First export the current config to a file, link it to the device and enable the systemd service (if you want to bring the device up at boot time).
wg showconf > /etc/wiregaurd/wg0.conf chmod 700 /etc/wireguard/wg0.conf wg setconf wg0 /etc/wireguard/wg0.conf
You can now easily issue
wg-quick up wg0 and
wg-quick down wg0.
To have it start at boot-time issue
systemctl enable wg-quick@wg0. (make sure you stop it first manually before starting the service)
Once you have Dynamic DNS set up on your Android using this app,
Android app setup
Install the Wireguard Android app.
The configuration is pretty straight-forward, but maybe just choose a different port than the one for your laptop, in case you are on the same network.
allowed-ips section, specify ‘0.0.0.0/0. ::0/0’ if you want to forward all internet traffic over this VPN (recommended for public WiFi).
Add peer configuration on the server
I added this Peer configuration to the existing
wg0.conf file on the Server:
[Peer] #mobile PublicKey = <android-public-key> AllowedIPs = 10.0.0.3/32 Endpoint = server.dyndns.com:51821 PersistentKeepalive = 25
When forwarding traffic to the outside, make sure IP forwarding is on.
To have the port and masquerading be set up automatically whenever I bring up the wireguard interface, I added soem
My Interface Settings on the server are as follows;
[Interface] Address = 10.0.0.1/24 PostUp = firewall-cmd --add-port 51820/udp && firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.0.0.0/24 masquerade' PostDown = firewall-cmd --remove-port 51820/udp && firewall-cmd --remove-rich-rule='rule family=ipv4 source address=10.0.0.0/24 masquerade' ListenPort = 51820 PrivateKey = <private-key>
Now you can enjoy a very fast and easy to maintain VPN configuration on the road, whether it’s on your mobile or on your laptop.