~/home/blogs/host-a-vpn-on-your-rasberry-pi.md

Host a VPN on your Rasberry Pi!

I set up my Rasberry Pi with OpenVPN and a DDNS service. Now I can access my home network from anywhere.

- Raul G.
2021-02-08

As I discussed in my last post, I set up my Rasberry Pi as a network attached storage. It's currently running a Samba server so that it behaves like a simple Windows file share.

Each share has custom permissions and they require password authentication.

At the moment, this file server is only available locally, and I have absolutely no intention of opening it to the internet.

So, I am going to set up this same rasberry Pi as an OpenVPN server.

I don't have a static IP address, so I will also configure my pi with a DDNS service.

Ideally, a free DDNS with Linux support.

No Static Ip? No Problem...DDNS


If you're not familiar with networking and stuff like DNS, you may want to read into it before trying to set up a VPN.

To summarize, internet addresses tend to use IPv4, so you see addresses that look like 1.1.1.1 and 172.217.4.174.

However, when you use the internet, you typically just type google.com, or rgonzalez.tech into your address bar.

That is the purpose of the DNS service. It translates domain names into IP addresses.

Unfortunately, the IP address that my internet service provider gives me tends to change every few weeks, so simply pointing a domain like vpn.rgonzalez.tech to an IP won't be enough.

I could purchase a static IP address to resolve that issue, but my VPN server won't be mission-critical and I'm trying to keep my costs low, so a DDNS should suffice.

I'm going to go with NoIP, simply because I have used them before and I don't mind clicking on their email once a month for free service.

🤔 Make me wonder if they're simply milking me to teach robots about fire hydrants and traffic lights.

Anyway, I went ahead and set up my new DDNS address and got started setting up their DUC (Dynamic Update Client)for Linux.

It was pretty simple, but that's probably because I already had make installed on my Pi.

Prepping The Network


Now that I am going to use this Rasberry Pi as a host, I need to configure it with a static local IP address.

Again, this Pi has Ubuntu 20.04 installed. I just need to change the IP to static and configure the subnet/gateway.

In the future, I may also have this lil' Pi run a DNS service. We'll see how it handles routing VPN traffic first, I have another Pi ready to go in case we need more juice.

(Could also use my Windows gaming PC to host some stuff on Hyper-V. I never really turn it off anyway. We'll see.)

I digress, the point is that this Pi needs to be set to static. I'm accessing the Pi over SSH, so I don't have access to the GUI.

I followed this guide to change the local IP and it worked flawlessly. 

Port Forwarding

So, the Rasberry Pi's IP won't randomly change anymore, so we can reliably point network requests to this rasberry Pi when they arrive to our home. I'm going to host the VPN service on the default port, which is 1194 & I'm going to use UDP, so I simply create the port forwarding rule in my router and move on!

If you need any help with port forwarding, I suggest you google for your router's model number. For example, if you're using a Spectrum F@stModem, you should enter:

Spectrum F@stModem + "Port Forwarding"

into google. Also, this link might be helpful: https://portforward.com/

You can also use online network testing tools to see if the ports are open.

Keep in mind that if you forwarded the port, but the rasberry Pi isn't hosting a service on that port yet, the port will read as "closed".

In fact, the way that I'm going to set up my VPN auth, it will always read as if the port is closed. (Extra security!)

Hosting a VPN


So, the first thing I'm going to do with my rasberry Pi is enable IP forwarding. That is what allows a computer to behave like a router. 

Typically, when a computer receives a network packet that does not belong to it, it simply drops the packet. If you enable IP forwarding, the computer will attempt to send it through the router/interface it was destined for.

I'm enabling this because I want any device on my home's network to be accessible through my VPN connection. Vice versa, I want devices on my home network to communicate with my VPN clients seamlessly.

Here's a quick article that shows you how to enable and disable IP forwarding in Linux.

Now that our Rasberry Pi can behave like a router, we can install openvpn and create a PKI followed by the server configuration.

This stuff is covered by the OpenVPN HOWTO 2.x guide, so I won't explain it further. I genuinely suggest you set aside an evening to read the HOWTO thoroughly.

Creating the PKI

Following the guide that I linked above, we use easy-rsa3 to create a PKI and Certificate Authority.


 ./easyrsa init-pki
 ./easyrsa build-ca

The certificate authority is literally just a Certificate and a Key that will create all further server cert/keys & client cert/keys.

Once the CA is built, we can use easyrsa to build the server certificate/key & any new client certificate/keys. Also, don't forget to generate a ta.key for tls-auth.

it'll make your server more secure.

My favorite part of this step is generating the DH.pem file.

Creating the Server Config

To be honest, we're not really "creating" the server configuration so much as we are modifying a template.

When you install OpenVPN, you might find the server.conf file in /usr/share/docs/openvpn/sample-config-files/

Again, the guide above mentions this stuff, so I'll move on. You can copy the sample server.conf file and modify it to suit your needs.

The important changes in my case were:

  • The location of my certificate & key files
  • I decided to change my tunnel subnet to 172.20.0.0/24
    • I doubt I'll run into a WiFi network using that subnet address, 😅
    • change server 10.8.0.0 255.255.255.0 to server 172.20.0.0 255.255.255.0
  • I'm also going to inform clients that this server can contact the 192.168.254.0/24 network.
    • Add the push "route 192.168.254.0 255.255.255.0" command to the server config.
    • This will allow clients to communicate with any device on my home network.
    • It will also require that I create a static route in my home router.
      • Route 172.20.0.0/24 to my Rasberry Pi
      • This is because all client devices will be in the tunnel subnet.

That should be enough to run this server. I wrote a quick shell script to run openvpn with my server.conf file.


#!/bin/bash
/usr/sbin/openvpn /etc/openvpn/server/server.conf

Last thing to do was add that script to crontab. @reboot /etc/openvpn/server/launch_vpn_server.sh

Connecting To the VPN


Just as the HOWTO guide mentioned how to create the server certificates and other important files, it also explains how to

create client certificates and client configuration files.

The first device I'm going to add is going to be my phone. Luckily, OpenVPN has a free mobile app called "OpenVPN Connect". 

The same name is used for the windows desktop OpenVPN client.

We generate the client certificate/key and configure the client.conf file to use these credentials. Finally, we rename client.conf to client.ovpn.

To simplify the installation of these configuration files, we're going to embed the certs and keys into the .ovpn file. You can read more about that here.

Finally, install the .ovpn files into your devices and you're done! You have a private VPN.

Please, let me know if you have any questions.

Thanks for reading!

Share this post