~/home/blogs/hosting-a-vpn-on-raspberry-pi.md

Hosting a Secure VPN on a Raspberry Pi with OpenVPN

A guide to configuring a Raspberry Pi as a secure, self-hosted VPN server with OpenVPN, covering network prep, DDNS, easy-rsa for PKI, and server/client setup.

- Raul G.
2021-02-08

1. Objective: Secure Remote Access to a Home Network

After setting up a local network attached storage (NAS), the next logical step is to enable secure remote access to it and other home network resources. Exposing a file share directly to the internet is a significant security risk. A far more secure solution is to create a Virtual Private Network (VPN).

This guide details the process of configuring a Raspberry Pi to act as a robust OpenVPN server. This allows for the creation of an encrypted tunnel from any client device (a laptop, phone, etc.) back to the home network, effectively placing the remote device on the local LAN.

2. Pre-Configuration: Network Groundwork

Before installing OpenVPN, several networking prerequisites must be met to ensure the server is stable and reachable from the internet.

A. Dynamic DNS (DDNS) for a Dynamic IP

Most residential internet service providers assign dynamic IP addresses that change periodically. To provide a consistent endpoint for the VPN, a Dynamic DNS service is essential. DDNS maps a static hostname (e.g., my-home-vpn.noip.com) to your changing public IP address.

I used a free service from NoIP, which requires running a small client on the Raspberry Pi. This Dynamic Update Client (DUC) periodically checks the public IP and updates the DNS record if it has changed.

B. Static Local IP for the Raspberry Pi

The VPN server itself needs a predictable IP address on the local network. This is crucial for setting up port forwarding. I configured a static IP for the Pi by editing the netplan configuration file in /etc/netplan/, ensuring it would not change on reboot.

C. Port Forwarding on the Router

To allow incoming VPN connections, a port forwarding rule must be configured on the home router. This rule directs all traffic arriving on a specific port from the internet to the static local IP of the Raspberry Pi.

  • Service: OpenVPN
  • Protocol: UDP (preferred for VPNs)
  • Port: 1194 (the standard for OpenVPN)
  • Destination IP: The static IP of the Raspberry Pi.

3. Step 1: OpenVPN Server Installation and Configuration

With the network prepared, we can now set up the OpenVPN server.

A. Enable IP Forwarding

A VPN server must be able to route traffic between networks (the public internet and the private LAN). This requires enabling IP forwarding in the Linux kernel. This is done by uncommenting the net.ipv4.ip_forward=1 line in /etc/sysctl.conf and applying the change with sudo sysctl -p.

B. Public Key Infrastructure (PKI) with Easy-RSA

OpenVPN uses a Public Key Infrastructure (PKI) to manage authentication and encryption. The easy-rsa tool simplifies the creation of the necessary certificates and keys.

  1. Initialize PKI: ./easyrsa init-pki
  2. Build Certificate Authority (CA): ./easyrsa build-ca
  3. Generate Server Certificate & Key: ./easyrsa build-server-full server nopass
  4. Generate Diffie-Hellman Parameters: ./easyrsa gen-dh
  5. Generate TLS Auth Key: openvpn --genkey --secret ta.key

This process creates a CA that acts as the root of trust, along with a unique certificate/key pair for the server.

Generating Diffie-Hellman parameters, a critical step for secure key exchange.

C. Server Configuration (server.conf)

The main OpenVPN configuration file dictates the server's behavior. Starting with the sample server.conf file, I made the following key changes:

  • Certificate Paths: Pointed to the newly generated ca.crt, server.crt, server.key, dh.pem, and ta.key files.
  • VPN Subnet: Defined the virtual network for VPN clients (e.g., server 10.8.0.0 255.255.255.0). This should be a different subnet from the local LAN.
  • Pushing Routes: To allow VPN clients to access the entire home network, I added the line push "route 192.168.1.0 255.255.255.0" (replacing the IP with my home network's subnet).
  • Static Route: On my home router, I added a static route to direct all traffic destined for the VPN subnet (10.8.0.0/24) to the Raspberry Pi's static IP. This ensures two-way communication.

Finally, I configured the OpenVPN service to start automatically on boot using systemd or a simple @reboot cron job.

4. Step 2: Client Configuration

For each device that needs to connect to the VPN, a unique client certificate and key pair must be generated.

  1. Generate Client Certificate & Key: ./easyrsa build-client-full my-laptop nopass
  2. Create .ovpn Profile: A client configuration file (.ovpn) is created, specifying the DDNS hostname, port, and paths to its certificate and key. For portability, the contents of the ca.crt, my-laptop.crt, and my-laptop.key can be embedded directly into the .ovpn file.

This profile can then be imported into any OpenVPN client, such as OpenVPN Connect on Windows or mobile devices.

5. Conclusion

This project successfully established a secure and reliable personal VPN, enabling encrypted remote access to my home network resources from anywhere. It serves as a practical application of fundamental networking concepts, including DNS, IP routing, and public key cryptography, demonstrating the power of a simple Raspberry Pi in building robust, self-hosted infrastructure.

Share this post