ycakes blog/Basic WireGuard VPN setup
14.05.2025

Basic WireGuard VPN setup

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.

Server setup

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

Client configuration

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.

Next Steps

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.