This tutorial will show you how to use HAProxy reverse proxy on pfSense to serve multiple domains or utilize multiple web servers behind a single public IP address.
This purpose of the guide is to show you how to create a basic reverse proxy configuration to allow hosting multiple webservers with a single public IP. HTTPS/SSL is outside of the scope of this guide. Additionally, this guide assumes you have pfSense 2.3 or newer installed and have at least two web servers already configured.
Log in to your pfSense web UI and navigate to System > Package Manager and click on Available Packages, and search for haproxy. For the purpose of this guide we won’t worry about haproxy_devel.
Now we need to allow traffic through the firewall.
Navigate to Firewall > Rules. Click on Add and create a new rule. Under Destination select This Firewall (self) from the dropdown menu and then under Destination Port select HTTP (80) for both the From and To menus. Leave everything else as they are. Click on Save and Apply Changes.
Now that we’ve set installed HAProxy and allowed HTTP traffic to route to it, we need to configure our backends.
Navigate to Services > HAProxy, click on the Backends tab, and click on Add.
Let’s name the first one Backend1. Under Server List, click on the downward arrow and give the server a name; I’m going to use Webhost1. Under address and port put in the local IP of the server, in this case it is 10.0.0.1 with port 80.
Scroll down to Advanced Settings and check Transparent ClientIP and select the appropriate interface from the dropdown list – it will usually be LAN or OPT1 (or whatever you named the OPT1 interface if you’ve set one up). Click on Save.
To set up the second backend we’ll save some time by duplicating the one we just made. Go back to the Backends page and on click on the icon under Actions that looks like two pages, one in front of the other. Rename the server pool, the server name in the pool, and change the IP address to the correct one for your second server. In our case we changed it to Backend2, Webhost2, and 10.0.0.11 respectively. Save.
Now we need to tell HAProxy which backend server to use for which domain. Because we are only using one public IP address we need to create a shared frontend.
Navigate to Services > HAProxy. On the Frontend tab click on Add.
Give your shared frontend a name. I’m going to use SharedFrontend. Under Listen Address select WAN Address (IPv4) and put 80 for the port. Now scroll down to the Advanced Settings and check Forwardfor so HAProxy will tell the servers what IP addresses are accessing the domains. Click on Save.
Now that that’s done, we’re going to create the frontend to our first domain. Click on Add.
Let’s name this one WebTest1 and check Shared Frontend. The previous frontend we created should show up by default. Now set up the ACLs, or Access Control Lists – this will tell HAProxy where the traffic is supposed to go. Click the downward arrow and give the ACL a name. We’ll use ACL1. Under Expressions select Host Matches. Value is where you will input the domain of the first site – here we’ll put webtest1.briantruscott.com.
Below is where we’ll determine what action takes place for the ACL. Click on the downward arrow there and under Condition ACL Names type ACL1. Make sure the backend is set to Backend1. You can choose the default backend below, but it is not necessary. Click on save.
Once again we’ll save time by using the duplicate option to create another frontend. Change the frontend name, ACL name, ACL value, condition acl name, and backend to reflect the second server. We’ll use WebTest2, Webhost2, webtest2.briantruscott.com, and Backend2 respectively.
Almost done! Now we just need to start the HAProxy service. Click on the Settings tab and check Enable HAProxy and then set the maximum number of connections. You’ll need to determine what’s appropriate for your site and ultimately the hardware that pfSense is installed on, but for this tutorial we’ll just set it to 10. Click on Save and finally click on Apply Changes.
HAProxy should now be up and running and directing the traffic to the appropriate servers! Keep in mind that this is a very basic configuration to give you something to start with.