Wireless Bridge + VPN Gateway

There’s quite a few guides out there that cover how to make a VPN gateway on a Raspberry Pi, but all of them fall short of getting all of the pieces of the puzzle in place, so I had to figure it out the hard way.

What is a VPN Gateway?

A VPN Gateway provides its VPN connection to other devices. This is especially useful in the case of devices which don’t support VPN connections, like Rokus, Smart TVs, Game Consoles, etc. These devices will connect to the Raspberry Pi to get their VPN connection.

What is a Wireless Bridge?

A Wireless Bridge provides WiFi to devices which otherwise wouldn’t have it. How it works is you connect your Raspberry Pi to the WiFi network, and from there plug in an Ethernet cable into your device of choice. Personally, I plug the ethernet cable into an Asus router set to Access Point Mode, so I can run a connection for multiple devices easily.

Can you visualize how this will work?

From the perspective of downloading, this is how the traffic will flow:

Internet–>VPN Server–>WiFi Card–>Raspberry Pi–>Ethernet Cable

Of course it’s more complex than that realistically, but as an oversimplified example thats how this will work.

There’s a lot of routing going on here also, so let’s sketch that out really quick as well, assuming we are downloading a file from 1.1.1.1. Our pretend VPN server IP is 69.69.69.69.

1.1.1.1–>69.69.69.69–>192.168.1.59–>10.9.0.1

Anyone with networking knowledge is already looking at this and wondering why we have routing going on in between two different private subnets. We need to do this because many network cards do not support Layer 2 Bridging between an Ethernet interface and a VPN interface. We overcome this limitation by adding in an additional layer of routing, and make sure to not restrict the traffic so that we can avoid many of the hassles of a double-NAT network. Let’s face it though, no matter what this setup will add a little overhead since its a VPN. (TLDR: its a workaround)

Prerequisites

  • A Raspberry Pi, or other Debian-based device with both an Ethernet port, and wireless card
  • Cat5e Ethernet Cable or better
  • A WireGuard VPN server to connect to (I recommend PiVPN)
  • Fresh install of Raspbian or Debian, depending on what device you end up using.

Actually Settings things up

I won’t go over how to install Linux, as I really genuinely hope that anyone doing something this complex already has this covered.

Here’s what you need to get done:

  1. Install raspbian on your raspberry pi
  2. Install debian or Ubuntu server LTS on the VPN server you’ll be using

Installing the VPN Server

In my scenario I went with OpenVPN because it has a proven track record, albeit terrible documentation, thus why I have made this guide.

Steps to install

  1. Log into your VPN server (the VM or other server which your raspberry pi will connect to
  2. Install PiVPN using sudo curl -L https://install.pivpn.io | bash
  3. Choose the option to install OpenVPN
  4. Accept the default prompts for each question asked (UDP, port number, etc.)
  5. Once you have completed installing PiVPN it’ll ask you to reboot, let’s hit no on that as we have one other quick change to make; adding in some commands to deal with lower-than-usual MTUs of some weird network setups

Custom Commands

As mentioned above, let’s tweak our config file for the VPN server.

  1. Edit the Server config
sudo nano /etc/openvpn/server.conf

2. Scroll to the bottom of the file and add the following lines:

#####MTU TWEAKS#####

#Set UDP to fragment packets larger than 1354 bytes to prevent packets from being dropped 
fragment 1354
#Tell TCP traffic to abide by a hard limit of 1354 bytes
mssfix 1354

#####END OF MTU TWEAKS#####

3. Press CTRL+X, and follow the prompts to save the file

4. Reboot the server

sudo reboot now

Creating a VPN profile

Now that we have our VPN server running, we should take a moment and verify everything is working by making a VPN profile.

1. Add a new profile using the PiVPN CLI, and include the argument nopass so it doesnt ask for a password every time we connect

pivpn -a nopass

2. Here’s the output from the command, and how I usually answer it:

ubuntu@ovpn-udp:~$ pivpn -a nopass
Enter a Name for the Client:  test-account
How many days should the certificate last?  1080
spawn ./easyrsa build-client-full test-account nopass

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1f  31 Mar 2020
Generating an EC private key
writing new private key to '/etc/openvpn/easy-rsa/pki/easy-rsa-28752.zvTXsV/tmp.1cY4EI'
-----
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-28752.zvTXsV/tmp.NDnb4h
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'test-account'
Certificate is to be certified until Sep 14 13:34:36 2024 GMT (1080 days)

Write out database with 1 new entries
Data Base Updated

Client's cert found: test-account.crt
Client's Private Key found: test-account.key
CA public Key found: ca.crt
tls Private Key found: ta.key
::: Updated hosts file for Pi-hole


========================================================
Done! test-account.ovpn successfully created! 
test-account.ovpn was copied to:
  /home/ubuntu/ovpns
for easy transfer. Please use this profile only on one
device and create additional profiles for other devices.
========================================================

3. Now lets download our VPN profile, you can connect into your server using Filezilla by running in the quickbar sftp://IP.ADDRESS and entering in your username and password

4. Navigate to the folder mentioned in your above console output, in my case /home/ubuntu/ovpns, find your file and download it.

5. Next we will need to make the same edits to the file we made to the server config from earlier, this time, we want to do it at the bottom of the client section of the config file, like so:

client
dev tun
proto udp
remote xxxxxxxx 3479
resolv-retry infinite
nobind
remote-cert-tls server
tls-version-min 1.2
verify-x509-name ovpn-xxx-fa6c-42f0-b509-xxxx name=
cipher AES-256-CBC
auth SHA256
auth-nocache
verb 3
#####MTU TWEAKS#####

#Set UDP to fragment packets larger than 1354 bytes to prevent packets from being dropped 
fragment 1354
#Tell TCP traffic to abide by a hard limit of 1354 bytes
mssfix 1354

#####END OF MTU TWEAKS#####

If you’re looking to just copy and paste, here’s that text again:

#####MTU TWEAKS#####

#Set UDP to fragment packets larger than 1354 bytes to prevent packets from being dropped 
fragment 1354
#Tell TCP traffic to abide by a hard limit of 1354 bytes
mssfix 1354

#####END OF MTU TWEAKS#####

6. Save your config file and connect it on a computer. Again, if you don’t know how to do this, you shouldn’t be working on an advanced VPN concept first.

7. If everything connects and works fine, you know you are all set and you have a working VPN connection!


Comments

Leave a Reply