Wireguard management
Foreword
While Wireguard is still not released as "stable", it provides decent performance on everyday usage.
You'll have to work with linux kernel plugins (DKMS), so it'll probably only work on Linux.
This document will make use of 2 terminals:
- The Wireguard server (world endpoint)
- A "user" (Wireguard client)
It'll be split into those 3 categories:
- Wireguard server setup
- Client management
For shell examples, every shell block will start with # <server>
,
where <server>
is one of those 3 choices:
- Wireguard server will be
VPN
- Client will be
CLIENT
Note that, if I moved into a folder I created during the guide, it'll be noted by suffixing CA/VPN/CLIENT with "in ./
"
Wireguard server setup
Installation
From the debian wiki, we have those steps
to run to add the wireguard repositories to our cache of available packages,
then to install the wireguard dependencies (wireguard
will install
wireguard-dkms
and wireguard-tools
).
# VPN
$ echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list
$ printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
$ apt update
$ apt install wireguard
And that's all we need.
Since it's a kernel plugin, it's recommended to restart your server.
Configuration
We firstly create our wireguard config folder.
# VPN
$ mkdir -p /etc/wireguard/keys
$ cd /etc/wireguard && umask 077
$ cd keys && umask 077
We then generate the public/private key pair.
# VPN in /etc/wireguard/keys
$ wg genkey | tee privatekey | wg pubkey > publickey
This creates two files:
privatekey
must be absolutely kept secretpublickey
will be shared and given to every client, as it's your VPN server identity.
We'll now create our wireguard peer configuration, we'll call the interface wg0
.
We'll use the IP address 10.0.10.1/24
for our VPN server, every client will have
another IP in the same network range (e.g. 10.0.10.2/24
).
We'll also use iptables to manage our network configuration.
Create and edit a file at /etc/wireguard/wg0.conf
.
[Interface]
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
# Address is your VPN endpoint's IP
Address = 10.0.10.1/24
# ListenPort is the port which you want to open on your server, it'll be used
# by the clients to connect to your server.
ListenPort = 59523
PrivateKey = <copy/paste the private key in keys/privatekey here>
We'll load the Wireguard daemon with our configuration file to quickly test that everything's ready.
# VPN
$ wg-quick up wg0
If no error's shown, you can check that the daemon started by running wg
and
looking at the output.
Now, stop the WG daemon.
# VPN
$ wg-quick down wg0
If everything's working, we can configure it to start at system startup.
# VPN
$ systemctl enable wg-quick@wg0
Let's start our server for now.
# VPN
$ systemctl start wg-quick@wg0
Client management
The following steps can be repeated for each client you wish to add.
Setup
Install the wireguard-dkms and wireguard-tools for your system.
- For debian, see at start of guide.
- For Archlinux, either take
wireguard-dkms
orwireguard-archlinux
, thenwireguard-tools
.
Create the folders and generate the certificates as done for the server.
# Client
$ mkdir -p /etc/wireguard/keys
$ cd /etc/wireguard && umask 077
$ cd keys && umask 077
$ wg genkey | tee privatekey | wg pubkey > publickey
Configuration file
We'll have to choose an address for this peer. For this example, I'll use 10.0.10.2/24
.
We also need to decide if we'll proxy everything through our VPN or not (see comments in the config block below).
[Interface]
Address = 10.0.10.2/24
PrivateKey = <copy/paste the private key in keys/privatekey here>
# If your wireguard server hosts a DNS, like pihole, reference it here.
DNS = 10.0.10.1
[Peer]
# This is your server. Put its public key here
PublicKey = OE5Ytufsw69r8xOa6faMaY2iQtd87CMC28mVRgseDEF=
# Only add this line if you want to proxy everything through your VPN.
AllowedIPs = 0.0.0.0/0
# Else, put your VPN's IP
AllowedIPs = 10.0.10.1/24
# Your VPN's IP:port
Endpoint = 51.30.40.40:59523
PersistentKeepalive = 25
Server-side acknowledgement of this client
EDIT: The following command will add the peer to the current instance and automatically update the
wg0.conf
file, it's the preferred method.
wg set wg0 peer <client public key> persistent-keepalive 25 allowed-ips <clientip> endpoint <serverip:port>
You can make it as a bash function (e.g.
wg-add <pubkey> <clientip> <endpoint>
).
function wg-add {wg set wg0 peer $1 persistent-keepalive 25 allowed-ips $2 endpoint $3; }
We now need to change our server-side wg0.conf
file to add a reference to this
client inside the configuration.
Open the file at /etc/wireguard/wg0.conf
on your vpn server, and add the
following configuration block.
[Peer]
PublicKey = <copy/paste your client's public key here>
AllowedIPs = <put your client's IP here>
I recommend to prefix the [Peer]
line with the hostname or a descriptor of the
client you added, to easily organize peers.
Now, restart wireguard on the server, through systemctl restart wg-quick@wg0
.
Client-side wireguard start
Like we did for the server, you should firstly test if the interface can be started, then enable it at startup.
We'll load the Wireguard daemon with our configuration file to quickly test that everything's ready.
# Client
$ wg-quick up wg0
If no error's shown, you can check that the daemon started by running wg
and
looking at the output.
Now, stop the WG daemon.
# Client
$ wg-quick down wg0
If everything's working, we can configure it to start at system startup.
# Client
$ systemctl enable wg-quick@wg0
Let's start our client for now.
# Client
$ systemctl start wg-quick@wg0
Client access revocation
To revoke the client from the server, you simply need to remove the [Peer]
block
related to your revoked client from the server's configuration, then
restart your VPN server.
FAQ: Common problems I encountered
Client to Client: Ping is OK, but everything else is unreachable
That may be because your firewall is configured to drop everything else except ICMP.
With an iptables -L | less
, you may notice a configuration sequence such as the following.
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
ACCEPT all -- anywhere 10.10.0.0/16
ACCEPT all -- 10.10.0.0/16 anywhere
Which literally translates to:
- Drop everything, except ICMP packets
- Accept some stuff
- Accept some stuff
Since rule priority is from first to last, the packet is dropped and it's end of story.
A hackfix you can do to manually enable C2C is to use iptables-save
.
$ iptables-save > rules
$ nvim rules
$ iptables-restore < rules
When in the rules
file, locate the two IPtables config lines which talk about
your wireguard interface (here, 10.10.0.0/16
is a good search keyword),
and put the REJECT
rule below those two consecutive entries.
No Comments