Set up a simple VPN with WireGuard and Raspberry Pi as a server

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

Equipment

  • Raspberry Pi 3 with LTE module and public IP. There will be a VPN server (hereinafter referred to as edgewalker)
  • An Android phone that must use a VPN for all communications
  • Linux laptop that needs to use VPN only inside the network

Every device that connects to a VPN must be able to connect to every other device. For example, a phone should be able to connect to a web server on a laptop if both devices are part of a VPN network. If the setup is simple enough, then you can think about connecting to a VPN and a desktop (via Ethernet).

Considering that wired and wireless connections are becoming less secure over time (targeted attacks, KRACK WPA2 hacking attack ΠΈ Dragonblood attack against WPA3), I'm seriously considering using WireGuard for all my devices, no matter what environment they're running in.

Software installation

WireGuard provides precompiled packages for most Linux, Windows and macOS distributions. Apps for Android and iOS are delivered through app catalogs.

I have the latest Fedora Linux 31 and I was too lazy to read the manual before installing. Just found the packages wireguard-tools, installed them, and then couldn't figure out why nothing was working. Further investigation revealed that I did not have the package installed wireguard-dkms (with a network driver), and it was not in the repository of my distribution.

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

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

I have the Raspbian Buster distribution installed on my Raspberry Pi, there is already a package wireguard, install it:

$ sudo apt install wireguard

I installed the app on my android phone WireGuardVPN from the official catalog of the Google App Store.

Installing keys

To authenticate nodes, Wireguard uses a simple private/public key scheme to authenticate VPN nodes. You can easily create VPN keys with 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 key pairs (six files). We will not refer to files in configs, but copy the contents here: each key is one line in base64.

Creating a Configuration File for a 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 = <copy private key from wg-server-private.key>
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 = <copy public key from wg-laptop-public.key>
AllowedIPs = 10.200.200.2/32

[Peer]
# mobile phone
PublicKey = <copy public key from wg-mobile-public.key>
AllowedIPs = 10.200.200.3/32

A couple of notes:

  • In the appropriate places you need to insert the lines from the files with the keys
  • My VPN is using internal range 10.200.200.0/24
  • For teams PostUp/PostDown I have an external network interface wwan0, you may have a different one (for example, eth0)

The VPN network is easily brought up with the following command:

$ sudo wg-quick up wg0

One small detail: as a DNS server, I used dnsmasq connected to 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 to the configuration file /etc/dnsmasq.conf, For example:

interface=br0
interface=wg0

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

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

Now that everything is working, we can register the automatic launch of the VPN tunnel:

$ sudo systemctl enable [email protected]

Laptop client configuration

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

[Interface]
Address = 10.200.200.2/24
PrivateKey = <copy private key from wg-laptop-private.key>

[Peer]
PublicKey = <copy public key from wg-server-public.key>
AllowedIPs = 10.200.200.0/24
Endpoint = edgewalker:51820

Notes:

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

For testing and automatic launch, we use the same commands wg-quick ΠΈ systemd:

$ sudo wg-quick up wg0
$ sudo systemctl enable [email protected]

Setting up a client on an Android phone

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

[Interface]
Address = 10.200.200.3/24
PrivateKey = <copy private key from wg-mobile-private.key>
DNS = 10.200.200.1
        
[Peer]
PublicKey = <copy public key from wg-server-public.key>
AllowedIPs = 0.0.0.0/0
Endpoint = edgewalker:51820

Unlike the laptop configuration, the phone should use our VPN server as its DNS server (string DNS), as well as pass all traffic through the VPN tunnel (AllowedIPs = 0.0.0.0/0).

Instead of copying the file to your mobile device, you can convert it to a QR code:

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

The QR code will be output to the console as ASCII. It can be scanned from the Android VPN app and set up a VPN tunnel automatically.

Hack and predictor Aviator

Setting up WireGuard is just magical compared to OpenVPN.

Source: habr.com

Add a comment