177 lines
7.9 KiB
Markdown
177 lines
7.9 KiB
Markdown
---
|
||
title: Reverse Proxy using a VPS
|
||
description: Self hosted VPS as a Reverse Proxy
|
||
published: true
|
||
date: 2025-12-13T12:40:51.346Z
|
||
tags: public, networking
|
||
editor: markdown
|
||
dateCreated: 2023-10-18T18:42:56.780Z
|
||
---
|
||
|
||
This is a guide to create a reverse proxy using a Virtual Private Server, or VPS so that you can access internally hosted services.
|
||
|
||
# My Situation
|
||
|
||
I host some services from my home lab that I access remotely, such as Home Assistant.
|
||
|
||
In my previous house, I was the account owner for the internet. I was able to get a static IP, and have the ISP open incoming ports 80 and 443 for web traffic.
|
||
|
||
Now I lived in shared accommodation which has an included internet connection, in the form of an Ethernet cable coming out the wall. Everyone just uses the same LAN.
|
||
I do have access to the router, but to maintain an environment that I can ‘home lab freely' in, I wanted to set up my own LAN.
|
||
|
||
I can do this while still utilising the shared connection. We have fiber and my services are not bandwidth heavy.
|
||
|
||
I have configured a router of my own with, with all traffic sent via [Mullvad VPN](https://mullvad.net/en).
|
||
|
||
Now I need to be able to access my internal services externally, using this same internet connection.
|
||
|
||
# The Plan
|
||
|
||
There are some ways I can do this:
|
||
|
||
- A VPN to my network, such as OpenVPN, SSL VPN, WireGuard, or even an overlay network such as TailScale.
|
||
This however this would mean I have to install a VPN app first and configure it. What if someone else wants to watch videos too? They now have to install some VPN app on their TV. Too much work! I just want to be able to browse to a domain to access the site.
|
||
- Get a VPN provider with a static IP. This is not ideal as most VPN providers do not provide static IPs, and if they do, they are quite costly.
|
||
- Use a [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/). I have used this in past, it is free, however it is not overly well suited for streaming video.
|
||
I am working towards a goal of being able to stream 4k video remotely.
|
||
|
||
Instead, I am going to build my own cloud reverse proxy host.
|
||
|
||
This makes use of a Virtual Private Server (VPS) to run Nginx Reverse Proxy Manager. The VPS will have access to the services running on my internal network via a WireGuard VPN.
|
||
|
||
This will connect to my home network with a WireGuard VPN, and will run Reverse Proxy Manager to manage incoming web connections.
|
||
|
||
To make this, I need a few things:
|
||
|
||
1. A VPS. There are many to choose from. In the end I went with a server from [OVHcloud](https://www.ovhcloud.com/en/).
|
||
- WireGuard is efficient compared to other VPN protocols, so the server does not have to be too powerful.
|
||
- Be sure to check how much network traffic the VPS allows. Lots have limits, which may or may not be enough for your use case. I am streaming 4k video so I am looking for unlimited bandwidth.
|
||
2. A router that allows for new VPN interfaces to be created. I use [opnSense](https://opnsense.org/) for my router which does allow this.
|
||
|
||
# VPS Setup
|
||
|
||
First I need to find a VPS provider. As I said before, I went with a server from [OVHcloud](https://www.ovhcloud.com/en/).
|
||
|
||
The server I chose (VLE-4) costs $11 US per month.
|
||
|
||
- 4 vCores
|
||
- 4GB RAM
|
||
- 80 GB NVMe SSD
|
||
- 1 Gbps unmetered connection
|
||
- 1x Static IPv4 address
|
||
- Anti-DDoS Protection Included
|
||
- Ubuntu 23.04
|
||
|
||
Once I purchased the server and it had provisioned, I connected and set up a few things.
|
||
|
||
1. Updated to Ubuntu 23.10
|
||
2. Enabled Key-Based only login: See this guide: [How To Configure SSH Key-Based Authentication on a Linux Server](https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server)
|
||
3. Enable UFW Firewall
|
||
- Allow port 22(SSH), 51820/UDP(WireGuard), 443(HTTPS)
|
||
`sudo ufw allow <PORTS>`
|
||
- Enable UFW
|
||
`sudo ufw enable`
|
||
4. Enabled the edge firewall on my hosting provider.
|
||
|
||
# VPN Setup
|
||
|
||
After this it is time to install WireGuard VPN on the VPS.
|
||
|
||
For this, I mostly followed this guide: [How To Set Up WireGuard on Ubuntu 20.04](https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-20-04)
|
||
|
||
I recommend reading that guide as there are some decisions I made that I do not explain, but at a high level, I followed through the steps up to the end of step 6:
|
||
|
||
- Install WireGurad
|
||
- Create a new WireGuard private and public key pair:
|
||
`wg genkey | sudo tee /etc/wireguard/private.key`
|
||
`sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key`
|
||
- Chose a new IP range, I chose 10.0.20.0/24
|
||
- Created a new WireGuard Configuration file:
|
||
`/etc/wireguard/wg0.conf`
|
||
|
||
I was then able to start the WireGuard server, however I have still not yet added any peers. The guide explains how to do this on another Linux server, but in this case, I do not want to do that. Instead of step 7:
|
||
|
||
This is done in the WireGuard Instance settings in my Router:
|
||
|
||

|
||
|
||

|
||
|
||
Be sure to check the ‘Disable routes’ option in the Instance, as I will do this manually
|
||
For the gateway, it does not matter, just as long as it is unique.
|
||
|
||
Then in the Peers tab:
|
||
|
||
The Pubic Key is the Public key from the WireGuard Server on the VPS
|
||
|
||
The Endpoint Address is the public IP of the VPS.
|
||
|
||

|
||
|
||
After this we can continue with the [Digital Ocean guide](https://www.digitalocean.com/community/tutorials/how-to-set-up-wireguard-on-ubuntu-20-04) from step 8.
|
||
|
||
The below command is then run to add the new opnSense peer to the Wireguard server.
|
||
|
||
`sudo wg set wg0 peer <PUBLIC KEY> allowed-ips 10.0.20.2`
|
||
|
||
After doing this, I can see the VPN connection is up:
|
||
|
||

|
||
|
||
In the end, my /etc/wireguard/wg0.conf file looked like:
|
||
|
||
```plaintext
|
||
[Interface]
|
||
Address = 10.0.20.1/24
|
||
SaveConfig = true
|
||
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||
ListenPort = 51822
|
||
PrivateKey = <SERVER PRIVATE KEY>
|
||
|
||
[Peer]
|
||
PublicKey = <PEER PUBLIC KEY>
|
||
AllowedIPs = 10.0.20.0/24, 10.0.10.0/24
|
||
PersistentKeepalive = 25
|
||
```
|
||
|
||
# Network Setup
|
||
|
||
Now an interface needs to be created on my router for the new VPN connection so that I can configure firewall rules to allow and deny access.
|
||
|
||
For opnSense, this is as simple as going to Interfaces > Assignments, and adding the new interface
|
||
|
||

|
||
|
||
Then configure the settings as below:
|
||
|
||

|
||
|
||
You do not need to configure a IPv4 address, as this will automatically get the IP address specified of the Instance Tunnel Address.
|
||
|
||
After this, I created the below firewall rule so that the new WireGuard interface could access the LAN.
|
||
|
||

|
||
|
||
If you have any strange issues, check the routing table (System > Routes > Status) to see if there are any old entries that need to be deleted.
|
||
|
||
# Reverse Proxy
|
||
|
||
For the reverse Proxy I am using [Nginx Reverse Proxy Manager](https://nginxproxymanager.com/) running in a Docker container.
|
||
|
||
First, install Docker: [Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)
|
||
|
||
Then I installed Portainer to give a nice webUI to manage Docker: [Install Portainer CE with Docker on Linux](https://docs.portainer.io/start/install-ce/server/docker/linux)
|
||
|
||
Then in Portainer I made a new stack (docker compose).
|
||
|
||

|
||
|
||
I was then able to log into Reverse Proxy Manager and create the my domains in Reverse Proxy Manager
|
||
|
||

|
||
|
||
I also needed to point these domains to the public IP of my VPS.
|
||
|
||
Once this was done, I was able to access the internal services via my domain name.
|
||
For example, this website! |