This is going to serve as a quick and dirty introduction to using HAProxy in tandem with ACME on your pfsense machine to serve some pages via reverse proxy with SSL/TLS encrypted traffic.
The ACME portion is optional, but it’s trivial and good practice. Note that while it makes it much easier, you don’t need a domain or a dynamic DNS service that allows TXT records to verify ownership. If you don’t have these options, the firewall can host the challenge file for validation via the
Webroot Local Folder option, or the
Standalone option worst-case.
First we’re going to quickly install the required packages - navigate to
Available Packages; install
(OPTIONAL) Once those are ready, we're going to do the letsencrypt portion. (0:56)
Account keysand press
Set a name, select the ACME server (
Production ACME v2), set your email address, and press
Create new account keyto generate your key. Once the box is populated, press
Register ACME account keyand hit
Now that we’ve got an account key, we can make a cert. Navigate to
Add. Fill in the name and description for your reference, and ensure the account you just made is selected below.
Scroll down to
Domain SAN List,this is where we validate your ownership of the destination on your cert. We’re going to operate as though you have a domain, but again this process does not require one - if your DDNS service allows TXT records (like DuckDNS), you can use that. If not, you can use webroot local folder with some HAProxy config, or the Standalone option.
With our own domain, we’ll give ourselves a wildcard cert for subdomain usage. Enter the FQDN and the FQDN with an asterisk subdomain as two separate entries.
For the method, select one that is an integration for your DNS provider if available, otherwise you’ll have to use manual (which will require a few extra steps).
After that, press Save. It will return us to the
Certificates page with an
Renew button next to our new entry.
- With anything other than the manual options, these buttons are a fire and forget solution - you click
Issueto get the cert, it’ll tell you when it succeeds, and you’re set.
With manual, you have to manually enter the keys it gives you as TXT records where your nameservers are managed, so there’s an additional step or two.
You’ll see that the
Last renewed field is updated, that means your cert is valid.
Now we’ll do the actual reverse proxy steps, so
Navigate to `Services`->`HAProxy`->`Settings`. (3:12)
Check the box at the top to enable HAProxy. Set your maximum connections to something around 1000.
Set an internal stats port to enable the HAProxy status monitor, which is very convenient to identify outages or manage your load balancer.
You can also optionally set up logging and alerts for a similar purpose here.
We need to set our Diffie-Hellman size, so change
Max SSL Diffie-Hellman sizeto 2048 under
Let’s define our servers in some backends now.
Navigate to `Backend` and Press `Add`. (3:52)
Enter a name - I generally use the subdomain or path I’m using.
Add the server by pressing the arrow in the server list. Name it and enter the IP address and port that the service is listening on.
Note that you do not need to check Encrypt or enter any certificate information here, that’s all being handled by HAProxy, not your servers.
You can enter multiple servers for a single backend and set the mode to backup for failover or active for load balancing.
If you do the latter, you’ll want to select a load balancing method by expanding the
Load balancing section, and selecting whatever is appropriate - round robin and least connections are both solid choices.
- Save and apply your settings.
Make a backend for each service you’d like to expose. Also note that for Plex, you will still need the listen port to be forwarded.
Now we’ll make frontends for these services.
First, we'll make a shared frontend for all HTTPS traffic. (4:56)
Name your service (
Change the port to 443 and check the box for SSL offloading.
separate sockets in
- Scroll to
SSL Offloading, and select the certificate that you just created with ACME.
If you’re not using letsencrypt, leave the port and offloading settings as is.
Saveand apply your changes.
Next, we'll make an HTTPS enforcement rule. (5:37)
Make a new rule, call it
http_redirect. Have it listen on WAN at port 80, no offloading.
Actions. Press the arrow to create one. Change the action to
http-request redirectand set the rule to
Save and apply.
Now we can make the individual frontends for your services. (6:01)
Press Add, enter the name, and check the
Shared Frontendbox and select
Access Control liststo define which backend is used based on the subdomain/path given. You can use
host starts withor
host containsfor subdomains, and
path starts withor
path containsfor paths. In value, set the subdomain/path that will be used to access the service (i.e.
ombifor ombi.domain.com, or
For subdomains, you will need that subdomain to be pointing at your WAN address. Paths are more appropriate for a dynamic DNS setup.
- Create an Action with action
Use Backend, set the conditional ACL name to the name of the rule you made above, and set the backend to the associated service you’re exposing.
You can set a default backend if you want something else to display if your Ombi backend is down.
- Press Save and apply your changes.
Once you’ve done this for your various services, we can go make some firewall rules.
Navigate to `Firewall` -> `Rules` (7:25)
- Create a new one called
HAProxy_HTTP. Pass IPv4 TCP traffic on the WAN interface, with destination
This firewallat port 80 (select HTTP in the
Destination Port Range
- Make an identical entry for
HAProxy_HTTPStraffic at port 443.
Once these firewall rules are made, your subdomains/paths will now reach the services you created frontends and backends for in HAProxy.