These notes were written after I configured my first RaspberryPI. It is a RaspberryPI 4 Model B with 8GB RAM, a 64-bit processor, and a 32 GB SD card. The main goal was to host a self-hosted library web application only accessible to me.
2023-09-15 17:38:06.532471+00
If I understand correctly, there are two ways of displaying a private server publicly. Either I have to set up port forwarding, in other words configuring my router to forward external requests to a device inside the private network, or employ tunnels between a provider and my RaspberryPI (purely software). Tunnels, as quoted by Cloudflare, "creates an encrypted tunnel between your origin web server and Cloudflare's nearest data center, all without opening any public inbound ports.". It hides your public IP address, blocks direct attacks (DDoS, etc.), provides authentication features (Zero Trust), and much more. Therefore, I decided to use tunnels over port forwarding since it seemed too demanding to configure securely.
To configure the tunnel, I followed this tutorial: Set up your first tunnel. Following are my ingress rules in the cloudflared configuration file:
ingress:
- hostname: diderikk.xyz
service: http://localhost:8080
- hostname: library.diderikk.xyz
service: http://localhost:3000
- hostname: ssh.diderikk.xyz
service: ssh://localhost:69
- service: http_status:404
To add domains/subdomains to my tunnel I use the following command:cloudflared tunnel route dns -f <tunnel_id> example.domain.com
After I configured the Cloudflare tunnel, I hosted my applications by running Docker containers on the RaspberryPI and updating the configuration file to match a domain/sub-domain to the local port, as defined above. However, I aimed to have the applications only be accessed by me. Cloudflare has the functionality to achieve this. For each application I host on the RaspberryPI, I can create a Cloudflare application. Cloudflare applications have multiple security features, but in this case, I only need policy settings to define who will have access to the application. I require the user to have my public IP address and access to my email addresses as follows:
Therefore, if you try to access library.diderikk.xyz, you will see the following page:
Likewise, suppose you get access to my public IP address. In that case, you will still need to receive a code only authorized to be sent to one of the email addresses specified in the policies. If a separate one is used, access won't be permitted.
As mentioned, I added a policy that causes Cloudflare to only authorized users with an IP address equal to my public home address. However, this will prevent me from accessing the hosted applications while away from my home network. Therefore, I installed and created a Tailscale network. "Tailscale is a VPN service that makes the devices and applications you own accessible anywhere in the world, securely and effortlessly. It enables encrypted point-to-point connections, which means only devices on your private network can communicate with each other.". Additionally, it has received great feedback and recommendations on the subreddit r/selfhosted. As of writing this note, I have added three nodes to my Tailscale network: my laptop, phone, and the RaspberryPI, and assigned the RaspberryPi as an exit node. As a result, I can connect any of my nodes to the exit node and, from there, access any applications hosted on the RaspberryPI/home network. Another option would be to install a VPN service such as Wireguard onto the RasperryPI and connect to the home network using the VPN.
Lastly, the goal was to host a private library application. I selected Calibre Web from this GitHub repo list of eBooks, primarily based on the number of GitHub stars. It provides a simple setup with a docker image using environment variables to configure volumes storing PDF/EPUB files.