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

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

Equipment


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

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

Considering that wired and wireless connections become less and less secure over time ( targeted attacks , KRACK attack on WPA2 hacking and Dragonblood attack against WPA3 ), I seriously consider the possibility of using WireGuard for all my devices, regardless of the environment in which they work.

Software installation


WireGuard provides pre-compiled packages for most Linux, Windows, and macOS distributions. Android and iOS applications are delivered through application directories.

I have the latest Fedora Linux 31, and before installing I was too lazy to read the manual. I just found the packages wireguard-tools, installed them, and then I could not understand why nothing was working. Further research showed that I did not have a package installed wireguard-dkms(with a network driver), and it was not in the repository of my distribution.

If I read the instructions, I would take the right steps:

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

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

$ sudo apt install wireguard

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

Key Installation


For host authentication, Wireguard uses a simple private / public key scheme for authenticating VPN hosts. 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 the files in the configs, but copy the contents here: each key is one line in base64.

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


The configuration is pretty 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 comments:

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

The VPN network is easily lifted by the following command:

$ sudo wg-quick up wg0

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

interface=br0
interface=wg0

In addition, I added the 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 set the VPN tunnel to start automatically:

$ sudo systemctl enable wg-quick@wg0.service

Client configuration on laptop


On the laptop, create a configuration file /etc/wireguard/wg0.confwith 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 the public IP or host of the VPN server
  • By setting AllowedIPsto 10.200.200.0/24, we use the VPN only to access the internal network. Traffic to all other IP addresses / servers will continue to go through β€œnormal” open channels. A preconfigured DNS server on the laptop will also be used.

For testing and automatic start, we use the same commands wg-quickand systemd:

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

Setting up a client on an Android phone


For an Android phone, 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 configuration on the laptop, the phone must use our VPN server as a DNS server (string DNS), and also pass all the 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. You can scan it from the Android VPN app and automatically configure the VPN tunnel.

Conclusion


Setting up WireGuard is just magical compared to OpenVPN.

Source: https://habr.com/ru/post/undefined/


All Articles