Setting up a simple VPN with WireGuard and Raspberry Pi as the server

Since WireGuard will become part of the future Linux kernel 5.6, I decided to see how best to integrate this VPN with my LTE router/access point on Raspberry Pi.

Hardware

  • Raspberry Pi 3 with an LTE module and a public IP address. Here will be a VPN server (further referred to as edgewalker)
  • An Android phone that should use the VPN for all communications
  • A Linux laptop that should use the VPN only within the network

Every device that connects to the VPN should be able to connect to all other devices. For example, the phone should be able to connect to the web server on the laptop if both devices are part of the VPN network. If the setup turns out to be simple enough, we might consider connecting the desktop to the VPN (via Ethernet).

Considering that wired and wireless connections are becoming increasingly less secure over time (targeted attacks, the KRACK attack against WPA2 and the Dragonblood attack against WPA3), I am seriously considering using WireGuard for all my devices, regardless of the environment they operate in.

Software Installation

WireGuard provides precompiled packages for most Linux distributions, Windows, and macOS. Applications for Android and iOS are available through app directories.

I have the latest Fedora Linux 31, and before installation, I was too lazy to read the manual. I just found the packages wireguard-tools, installed them, and then couldn't understand why nothing was working. Further investigation revealed that I didn't have the wireguard-dkms (with the network driver) package installed, and it wasn't in my distribution's repository.

If I had read the instructions, I would have taken the correct steps:

$ sudo dnf copr enable jdoss/wireguard
$ sudo dnf install wireguard-dkms wireguard-tools

On my Raspberry Pi, I have the Raspbian Buster distribution installed, and there's already a package wireguard, installing it:

$ sudo apt install wireguard

On my Android phone, I installed the WireGuard VPN from the official Google App Store.

Key Installation

For node authentication, WireGuard uses a simple private/public key scheme for VPN node authentication. You can easily create VPN keys using the following command:

$ wg genkey | tee wg-laptop-private.key |  wg pubkey > wg-laptop-public.key
$ wg genkey | tee wg-server-private.key |  wg pubkey > wg-server-public.key
$ wg genkey | tee wg-mobile-private.key |  wg pubkey > wg-mobile-public.key

This gives us three pairs of keys (six files). Let's not refer to the files in the configs, but instead copy the content here: each key is one line in base64.

Creating a configuration file for the VPN server (Raspberry Pi)

The configuration is quite simple; I created the following file /etc/wireguard/wg0.conf:

[Interface]
Address = 10.200.200.1/24
ListenPort = 51820
PrivateKey = 
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wwan0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wwan0 -j MASQUERADE

[Peer]
# laptop
PublicKey = 
AllowedIPs = 10.200.200.2/32

[Peer]
# mobile phone
PublicKey = 
AllowedIPs = 10.200.200.3/32

A couple of notes:

  • You need to insert the lines from the key files in the appropriate places
  • My VPN network uses a private address range 10.200.200.0/24
  • For the commands PostUp/PostDown I specified the external network interface wwan0; you may have a different one (for example, eth0)

The VPN network can be easily started with the following command:

$ sudo wg-quick up wg0

One small detail: I used dnsmasq bound to the network interface br0, I also added devices wg0 to the list of allowed devices. In dnsmasq, this is done by adding a new line with the network interface in the configuration file /etc/dnsmasq.conf, for example:

interface=br0
interface=wg0

Furthermore, I added an iptable rule to allow traffic on the listening UDP port (51280):

$ sudo iptables -I INPUT -p udp --dport 51820 -j ACCEPT

Now that everything is working, we can set up the automatic start of the VPN tunnel:

$ sudo systemctl enable wg-quick@wg0.service

Client configuration on the laptop

On the laptop, we create a configuration file /etc/wireguard/wg0.conf with the same settings:

[Interface]
Address = 10.200.200.2/24
PrivateKey = 

[Peer]
PublicKey = 
AllowedIPs = 10.200.200.0/24
Endpoint = edgewalker:51820

Notes:

  • Instead of edgewalker, you need to specify the public IP or host of the VPN server
  • By setting up AllowedIPs to 10.200.200.0/24, we use the VPN only for access to the internal network. Traffic to all other IP addresses/servers will still go through the 'normal' open channels. A pre-configured DNS server will also be used on the laptop.

For testing and automatic startup, we use the same commands wg-quick and systemd:

$ sudo wg-quick up wg0
$ sudo systemctl enable wg-quick@wg0.service

Configuring the client on the Android phone

For the Android phone, we create a very similar configuration file (let's call it mobile.conf):

[Interface]
Address = 10.200.200.3/24
PrivateKey = 
DNS = 10.200.200.1
        
[Peer]
PublicKey = 
AllowedIPs = 0.0.0.0/0
Endpoint = edgewalker:51820

Unlike the configuration on a laptop, the phone must use our VPN server as the DNS server (line DNS), and also route all traffic through the VPN tunnel (AllowedIPs = 0.0.0.0/0).

Instead of copying the file to the mobile device, it can be converted into a QR code:

$ sudo apt install qrencode
$ qrencode -t ansiutf8 < mobile.conf

The QR code will appear in the console as ASCII. It can be scanned from the Android VPN app to automatically configure the VPN tunnel.

Output

Setting up WireGuard is simply magical compared to OpenVPN.

Source: habr.com

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster