How To Use A Digital Ocean VPS And Caddy As A Reverse Proxy For A Self Hosted Raspberry Pi Website (Behind A Firewall) Using An SSH Reverse Tunnel
This tutorial is inspired by a question posted on the Rasberry Pi Stack Exchange site titled “Website behind Firewall: How to SSL through a Reverse SSH Tunnel?”.
A little background. The person posting the question is using a Raspberry Pi to host a website and has opened a reverse SSH tunnel from their Raspberry Pi to a VPS..for the sake of this tutorial, a Digital Ocean VPS. The original poster has pointed DNS for a custom domain to the Digital Ocean VPS and would like to know how to access the Pi’s website from said domain.
In this tutorial we will cover setting up a self hosted website using a Raspberry Pi and Docker. Obtaining and setting up a Digital Ocean VPS. Installing Caddy on our VPS to be used as a proxy server to route traffic to our custom domain back to the Raspberry Pi via an ssh reverse tunnel. An added benefit of using Caddy is that Caddy will obtain a free SSL certificate via Let’s encrypt for us.
So, if this is of interest to you continue reading…
What is a Raspberry Pi?
Raspberry Pi is an ultra affordable computer the size of a credit card and can be had for as little as $35 dollars for a 2GB model capable of running Raspberry Pi OS and Ubuntu. For this tutorial we will also be running Docker on the Raspberry Pi and use an Apache Docker container to host our website.
What is a Digital Ocean VPS?
Digital Ocean is a cloud provider offering services ranging from managed databases and storage to hosted Virtual Private Server (VPS) solutions. A VPS is a virtual computer hosted on managed infrastructure. You don’t have to worry about the underlying hardware, but have to manage the OS on the VPS.
What is SSH?
SSH is a secure shell typically used for server administration. It allows a remote system to access another system using public/private key pairs to secure the connection. In our use case we will be using the SSH session to create a reverse tunnel from our Raspberry Pi to a Digital Ocean VPS. You can SSH into another system with the following command.
Where “user” is the username with access credentials on the remote server and “ip” is the FQDN or IP address of the remote system.
What is a Reverse SSH Tunnel?
A reverse ssh tunnel is a tunnel in which the originating system maps a port on the remote system giving the remote system access to services on the originating system. Later in the tutorial we will create a reverse tunnel from the Raspberry Pi with the following command
ssh -R 8081:127.0.0.1:8080 user@ip
As you can see the SSH command is a bit different for a reverse tunnel. The -R flag is where the magic happens. We are telling our Digital Ocean VPS that any request made to port 8081 should be forwarded over the tunnel to port 8080 on the Raspberry Pi
What is Caddy?
Caddy is an open source web server that automatically takes care of SSL provisioning via Let’s Encrypt. In our use case we will be using Caddy as a Reverse Web Proxy for our self hosted site. This is the piece that will allow our VPS to serve pages from our Raspberry Pi which is being tunneled to our VPS via SSH. That was a bit long winded…but, hopefully it makes sense.
What is a Reverse Proxy?
A reverse proxy is a server that sits in front of an application server, in our case the Raspberry Pi, and will proxy requested made to our VPS via our custom domain name to the Raspberry Pi.
Proxies add a layer of security by limiting public access to the proxy server — allowing our application servers to be hosted in a more isolated network such as our home.
Self Hosting a Website on the Raspberry Pi
For demonstration purposes, and in case you don’t already have a self hosted website, let’s set one up quickly using Docker via the command below (hint…this will work on any server or desktop that has Docker installed…not just a Raspberry Pi).
docker run -dit -p 8080:80 httpd
With this command we are asking Docker to run the Apache httpd container and map it to port 8080 on the Raspberry Pi.
For the sake of brevity I will not go into setting up Docker. If you don’t already have Docker installed you can install Docker Desktop fairly quickly with the Get Started with Docker link found in the reference section below.
Now that we have a website up and running we can navigate to it via our browser. My Raspberry Pi has an address of 10.10.10.27 as depicted in the picture below.
As you can see, we are good to go. Let’s move on to creating our VPS…
Creating A Digital Ocean VPS
Sign in to Digital Ocean and create a droplet.
If you do not have an account please use this referral link as every person using this link gets $100 in credit which can be used over 60 days. If you end up spending $25 with Digital Ocean, I’ll get a $25 credit I can use towards creating some more exciting tutorials.
For this tutorial I will be creating an Ubuntu 20.04 server on the Basic $5/mo plan in the San Francisco region with password authentication.
Note: If you run your server less than a month you will only pay for what you use. This plan is charged at $0.007/hour.
Now let’s configure the VPS…
Setting Up Our VPS
Create a firewall rule allowing Port 22, 80, and 443 inbound to our VPS by clicking on “Networking” and then “Firewalls”.
Depending on your use case you may want to further limit each of the rules to only allow traffic from your IP address.
Now that the firewall rules have been taken care of let’s ssh into the VPS
ssh root@<ip address of Digital Ocean VPS>
Per good practice let’s update the server.
apt update && sudo apt upgrade -y
Install Caddy…the commands below have been taken directly from the Caddy website via the link in the Reference section below.
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https && \curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/cfg/gpg/gpg.155B6D79CA56EA34.key' | sudo apt-key add - && \curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/cfg/setup/config.deb.txt?distro=debian&version=any-version' | sudo tee -a /etc/apt/sources.list.d/caddy-stable.list && \sudo apt update && \sudo apt install caddy
Create A Reverse SSH Tunnel from the Raspberry Pi to the VPS
Now that Caddy is installed we can create our reverse ssh tunnel via the command below.
ssh -R 8081:127.0.0.1:8080 root@<ip address of Digital Ocean VPS>
Let’s test to make sure the reverse ssh tunnel is working with the following curl command.
If all is working as expected the curl should return the following or something similar if you are using another source outside of this tutorial for your self hosted site.
This is another topic I will not go in to much detail for the sake of the tutorial. In short, create and “A” record for your custom domain to point to the public IP address of your VPS.
Creating the Reverse Proxy with Caddy
We can now see the fruits of our endeavor by starting the revers proxy. If all works as expected we will have a public facing site.
caddy reverse-proxy --from tutorial.rickjacobo.com --to 127.0.0.1:8081
Check your domain to see if the proxy server is working
If you made it to this point and have a working site a congratulations is in order. Congrats!!!
- Get Started with Docker
- Install Caddy
- Original Question Posted on the Raspberry Pi Stack Exchange Site
As always, thanks for reading the post. Please note this post contains affiliate links — While I wholeheartedly endorse the products I write about — If you use these links I may earn a commission…thanks again.