In this post I will describe a basic WireGuard-setup using two peers (a "server" and a "client"). I will assume the server is running on Arch Linux and the client is running on Android.
I will also demonstrate how to route all Internet traffic of the client will be routed through the server.
Note: Strictly speaking, the words "client" and "server" don't mean much in the WireGuard world, WireGuard only knows "peers". I will stick to those terms anyway because they make sense in my example.
First we need to install WireGuard:
sudo pacman -S wireguard-tools
WireGuard is using public-private key cryptography so we need to create the public and private keys:
umask 0077; wg genkey > server_private.key) wg pubkey < server_private.key > server.pub
Now we can create the configuration file for the server in the following location: /etc/wireguard/wg0.conf
[Interface] Address = 10.0.0.1/24 ListenPort = 64871 PrivateKey = <ServerPrivateKey> PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <device> -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <device> -j MASQUERADE
With Address
we specify the Address of the server inside the VPN.
ListenPort
should be self-explanatory, this is the port you will probably want to forward inside your router settings so your sever is reachable from outside of your home network.
PrivateKey
is the content of the private key file we created earlier (not the filename!).
The PostUp
and PostDown
commands are used for forwarding all traffic that is arriving on the wireguard interface to another network device.
Instead of <device>
you will want to enter the network device you use to connect to the internet on your server.
The device id can be found for example by using ip a
. In the following example the id to use would be enp3s01
.
.... 2: enp3s01: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 ....
Note that this can be a security risk. If you don't want to forward all internet traffic via your server you can simply skip those steps.
Now we can quickly start and stop the interface using sudo wg-quick up wg0
and sudo wg-quick down wg0
.
That's all we need to do on the server for now
The client config is very similar, save that one to a file in any folder eg. client1.conf
[Interface] Address = 10.0.0.2/24 PrivateKey = <ClientPrivateKey> [Peer] PublicKey = <ServerPublicKey> Endpoint = <ServerHost>:64871 AllowedIPs = 0.0.0.0/0,::/0
The Address
is, like in the configuration for the server, the clients Address inside the VPN.
We need to generate a private-public key pair for the client as well.
The Android App for example has an option to the generate keys.
This would be the most secure way to do it, create a private and public key pair on the client and only share the public key with the server.
For simplicity sake I will generate the private and public key on the server and export the config as a qr-code for the android app.
So we generate another key pair, and set the PrivateKey
key in out config accordingly :
umask 0077; wg genkey > client1_private.key) wg pubkey < client1_private.key > client1.pub
The [Peer]
section is new. Here we need to enter the PublicKey
of the server.
In the Endpoint
we need to insert the public Ip-Address(Or host name) of the Server and the Port. So not 10.0.0.1.
AllowedIPs = 0.0.0.0/0,::/0
means: All traffic to all IPv4 and IPv6 Addresses will be forwarded to the server.
That's the entire client config, we need to add a few lines to the server now:
# Server Config, add to end of wg0.conf [Peer] PublicKey = <CLientPublicKey> # VPN client's IP address in the VPN AllowedIPs = 10.0.0.3/32
Note that AllowedIPs = 10.0.0.3/32
is the same as the one in the [Interface]
section in the client config, but the subnet mask is different.
If you don't specify a host Address (/32). This has something to do with Cryptokey-Routing but it has been too long since I worked with routing and subnet mask stuff, so I am not able to explain it properly. More information on this topic can be found on this great (german) tutorial
If we had multiple "clients" we would need to repeat the [Peer]
section for each one, at least on the server.
I used the "official" WireGuard Android App from the Play Store. There are Alternatives on Fdroid.
We can now simply generate a QR-Code that we can scan with the WireGuard App:
qrencode -t png -r client1.conf -o client1.png
Ǹow, simply open the Android app, press the "+" Button, and select the Item to scan the QR Code.
If everything was set up correctly the Android App should show that data was received and sent. That's all the steps needed to set up a basic VPN with Arch Linux and Android.
The Server Configuration is not persistent, so you have to run sudo wg-quick up wg0
every time you restart your server.
The Arch Wiki has a great documentation on how to achieve persistent configurations.