/ pfSense

pfSense-2.4 + HAProxy - A walkthrough on how to proxy https traffic to multiple sites

Table of Contents

Introduction

I have an nginx service in an Ubuntu server 16.04.3 VM (phxlv-prx01) to reverse proxy all of my web traffic (both public and private) to my actual "backend" servers. This worked great as a single point of entry for all of my public and private web traffic (blog, git, plex, sabnzbd, sonarr, radarr, deluge). However, this presented a potential security problem because the only thing protecting my internal non publicly addressable web traffic panels (like deluge, sab, sonarr, etc) was DNS entries in my external DNS host (AWS Route53).

In order to correct this i had two options:

  1. build out another nginx VM to proxy just my public facing websites and setup my router to NAT 80/443 to that VM instead of the phxlv-prx01 VM
  2. Utilize HAProxy on my edge router (pfSense-2.4) to proxy specific public facing pages (blog, git, cloud) to their appropriate backend VMs

I ended up chosing HAProxy on my edge router which is running pfSense-2.4 right now and this is how I did it.

Step 1 - Install the HAProxy package

login to the pfSense admin panel go to System > Package Manager > Available Packages and install the haproxy package.

Step 2 - Configure HAProxy

Once the package is installed navigate to Services > HAProxy > Settings and configure the settings how you wish, make sure Enable HAProxy is checked, click Save.

My setup is like so:
haproxy-settings-1

Step 3 - Create HAProxy Backends

backends are what HAProxy calls the actual connecting servers, this is known as "upstreams" in NGINX. The next step is to create an HAProxy backend for each of your hosts, I have three hosts (blog, cloud, git) so mine ended up looking like this:
haproxy-backends-1

The config for blog.devita.co looks like this:
blog.devita.co-backend-1

blog.devita.co-backend-2

My linux VMs run on my "SLAN" interface as such the "Transparent Client IP" section should use the SLAN interface for the connections. Yours will probably be different.

Repeat this for each of your seperate backend "apps" or "servers", a tip is you can copy one interface to duplicated it, then edit it as needed.

Step 4 - Create The shared HAProxy HTTPS Frontend

frontends are what HAProxy uses to map something to a backend, in this case were mapping the hostname to a string and sending that matching traffic to the appropriate backend.

The first step is to create a shared-frontend that all your "vhosts" will belong to. I am using https with the ACME certificate package to give me LetsEncrypt SSL certificates for free, so if you're doing SSL make sure to mach the SSL section up to my screenshots.

My shared frontend looks like this:
shared-frontend-1

shared-frontend-2

Step 5 - Create Individual host Frontends

Now create a seperate "frontend" for each host, make sure to check "Shared Frontend" and pick the "shared-frontend" as the "Primary Frontend"!

My blog.devita.co frontend looks like this:

blog.devita.co-frontend-1

Rinse and repeat for each of your hosts, changing the ACL to match the appropriate hostname. I changed my ACL names for each host, I'm not even certain if they need to be unique or not but thats what I did.

Step 6 - Enable HTTP to HTTPS Redirect

Finally we need to redirect port 80 to port 443 we can do this with another frontend.

Create a new frontend call it "http-to-https" and make it match my settings below:
http-to-https-redirect

This will redirect all http to https by default.

Step 7 - Enable WAN port 80 and 443 through the firewall to the router

The final step is to allow the TCP/80 and TCP/443 through the firewall on the WAN interface. Go to Firewall > Rules > WAN and create two new rules that look like the following:

HTTP (80)

firewall-wan-80

HTTPS (443)

firewall-wan-443

Full rules look like this:
wan-firewall-rules-1

Test Everything out

You should now be able to hit http://yourdomain.com and have it redirect to https://yourdomain.com and also correctly go to the right backend server.

Conclusion

If you have any issues or questions, you can reach out to me and I'd be happy to help.