I run a variety of homelab services as many of us do over at /r/homelab, a handful of which are based around my Plex server. For a while I was accessing my various services via their hostnames and port numbers, but I felt that was too pedestrian and decided to start using a reverse proxy. I’ve been running PfSense for quite some time now and have been aware of Squid Reverse, but after some flaky performance I switched over to using HAProxy. Now all of my services can be accessed via presentable URLs like https://plex.edwork.org rather than http://plex.edwork.org:32400.
HAProxy proxies anything served over HTTP from X number of web servers, matched via their HTTP HOST Header. DNS records point both hostA.edwork.org and hostB.edwork.org to the IP of HAProxy, and based on what I’ve configured host1 gets routed to server A and host2 gets routed to server B. In addition to this, any request that comes in on port 80 gets a 301 redirect to the same URL, just with SSL tacked on to it. SSL offloading is great because we don’t have to configure certificates on each individual service, and as long as the link between HAProxy and your service is secure there’s no worry about insecure connections.
Here’s how to get it set up in PfSense:
Warning: This article assumes you have a somewhat familiar knowledge of IP Addressing, PfSense, HTTP, and DNS.
First, you’ll want to configure your backend(s). Click ‘Add’ at the bottom of the list to get started. Assign it a name, address, and port:
Leave the ‘balance’ at ‘none’ and change ‘Health Check Method’ to ‘Basic’. If you don’t set it to basic and leave it at HTTP, it may work but sometimes the detection is faulty and HAProxy will give you a 503 that the site is down - your results may vary.
Add as many backend services as you need, this may include your random webserver, sonarr, plex, radarr, couchpotato, you name it.
Next, I find it best to create a Virtual IP for HAProxy to listen on. This way you can create custom rules around the Virtual IP rather than using your WAN or LAN interface. I created an IP: 10.101.101.101 with a /32 mask in order for it to be the only IP in the subnet, and made it an IP alias.
Once you’ve setup your Virtual IP, you’ll want to port forward both port 80 and 443
Back to HAProxy, we’ll configure the Front End. I setup port 80 and 443 (be sure to check the SSL box) to listen on my Virtual IP. Give it a name, description, and set it to active. Keep the type as ‘http / https(offloading)’.
Access Control Lists - you can do a bunch of stuff here, like restrict access based on client certificates which I may go into at a later date, but all we’re going to do here is do hostname matching. Create a new entry like the example below:
Next we’ll create a matching Action for the ACL, like below:
Under Advanced Settings I’ve checked the box to ‘Use forwardfor option’, set ‘use httpclose option’ to ‘http-keep-alive (default)’ and under Advanced Pass Thru put (only if you want to redirect http traffic to https):
If you’ve been opting in for SSL features this whole time you will need to have some certificates loaded into PfSense. You can do so under System > Cert. Manager. HAProxy will match the right cert to the hostname of the requested URL.
Last configure all hostnames to point to your IP alias. This way HAProxy handles all inbound requests and forwards them to their. If you’re using PfSense’s Unbound DNS resolver this is easy but unfortunetly is outside the scope of this article.
Hope this helps someone, if you have any questions feel free to email me or message me on Hangouts: firstname.lastname@example.org