Reverse Proxy Setup Part 2

How I Finally Fixed My Reverse Proxy Setup Across WAN and Tailscale VPN

After a series of experiments and iterations, I finally managed to get my reverse proxy setup running seamlessly across both my WAN and Tailscale VPN. The journey was filled with challenges, but it now reliably handles requests and routes traffic to various containers on my network.

The key component of this configuration is a dedicated Linux container on my Proxmox host that acts as a reverse proxy. I set up HAProxy on this container to route incoming traffic to two synchronized Nginx servers. By using Syncthing, I keep the configurations of these Nginx servers identical, ensuring consistent handling of requests. In this setup, HAProxy essentially takes charge of forwarding traffic to the Nginx servers, which then resolve requests to specific containers based on both domain and port.

To manage local DNS, I have two Pi-hole instances: one running on a Raspberry Pi and another on an LXC container. These are synchronized via Gravity Sync, which simplifies the process of maintaining consistency between the two. Pi-hole is configured as my local DNS server and routes specific domain requests to HAProxy. I’ve manually wildcarded certain domains, like *.alpine and *.forest, in the Pi-hole configurations. This setup allows internal DNS resolution to happen seamlessly, with these wildcard domains pointing to specific services within my network.

To enable dynamic routing, I created a Python script that generates container names and associates them with subdomains. In this way, each container name becomes a subdomain, while the wildcarded domain in Pi-hole serves as the root domain for all requests. When HAProxy receives a request, it examines the accessed port and directs traffic accordingly to the Nginx servers, which then handle routing based on subdomain and container name. This dynamic domain association allows for flexible and manageable routing in the local environment.

For VPN access through Tailscale, I configured my Tailscale resolver to point to one of my Pi-hole instances. By installing Tailscale on the Pi-hole, I enabled a smooth routing experience for devices outside my network. Tailscale’s 4via6 subnet router feature was critical, allowing me to access devices remotely using the same domain structure that I use within my LAN. This feature also prevents domain collisions, so my *.alpine and *.forest subdomains continue to work as expected over VPN.

The setup incorporates resilience and failover as well. HAProxy acts as a DNS proxy, and if one of the Nginx servers fails, DNS requests are redirected to alternative services on other containers. Pi-hole serves as a centralized DNS handler for all LAN-based DNS traffic, channeling it through HAProxy. This setup ensures that traffic finds its way to the right destination even if one component encounters issues.

Now that this setup is stable, I’m looking to implement HTTPS across services, both for enhanced security and consistency. Services like Proxmox already default to HTTPS, but my goal is to certify all services, likely using SSL certificates managed by HAProxy. Additionally, I plan to deploy an OPNsense virtual machine to create segmented virtual networks, which will add both organization and a further layer of security to the environment.

This configuration has finally allowed me to achieve a reliable and flexible reverse proxy setup, effectively balancing my local and VPN-connected needs. By using HAProxy, Nginx, Pi-hole, and Tailscale together, I’ve built a system where requests are dynamically resolved and routed to the appropriate containers and services. There’s still more to do in terms of security and network structure, but the foundation is now solid and dependable—an accomplishment I’ve been working towards for quite some time.

Something else I've wanted to implement is a dedicated firewall box, most likely running OPNsense. Many ISP-provided routers lack robust network monitoring tools, so having a firewall with features like Snort and intrusion detection would be ideal. I've been considering whether to build this setup myself or invest in the Ubiquiti ecosystem, known for its ease of use and unified experience. However, I’m leaning toward a custom solution to avoid being locked into any single ecosystem. OPNsense offers incredible customization options, and as someone who enjoys tinkering, it seems like a perfect fit.

The last time I attempted this, I ran OPNsense in a virtual machine on my Proxmox host, setting up my router in bridge mode to connect to the VM. Unfortunately, DHCP issues prevented the assignment of an IP address, leaving my network without proper control. This time, I'm planning to use a dedicated hardware box. It doesn’t need to be overly powerful—an Intel Celeron or an i3 with around 8GB of RAM should be sufficient for my needs.

Looking ahead, I’m also considering mounting everything in a rack for better organization. My current Proxmox host is in a 4U Rosewill case, and I’d like to add a 1U power strip, a 1U router, a network switch, and a patch panel. A dedicated Proxmox dashboard for monitoring would be a great addition to this setup, creating an always-on station for network management. This project is definitely the next step in evolving my home lab and network infrastructure.

Stay tuned for updates as I continue refining the setup, particularly with HTTPS integration and network segmentation in the works!