Note: it seems the DuckDNS plugin for ACME has a bug - if you have domains on multiple accounts from them, you need to make different certs for each account. ACME attempts to use the first API key regardless of what you set in your SAN list.
Transcription:
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 System → Package Manager → Available Packages; install acme and haproxy.
(OPTIONAL) Once those are ready, we're going to do the letsencrypt portion. (0:56)
-
Navigate to
Services→Acme Certificates→Account keysand pressAdd.
Set a name, select the ACME server (Production ACME v2), set your email address, and pressCreate new account keyto generate your key. Once the box is populated, pressRegister ACME account keyand hitSave. -
Now that we’ve got an account key, we can make a cert. Navigate to
Certificatesand clickAdd. Fill in the name and description for your reference, and ensure the account you just made is selected below.
Scroll down toDomain 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 Issue and 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 underTuning. -
Press
Savefollowed byApply Changes.
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)
-
Navigate to
Frontendand clickAdd. -
Name your service (
https_sharedworks). -
Change the port to 443 and check the box for SSL offloading.
Optionally enable separate sockets in Stats.
- 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.
- Press
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. -
Scroll to
Actions. Press the arrow to create one. Change the action tohttp-request redirectand set the rule toscheme https. -
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 selecthttps_shared. -
We’ll use
Access Control liststo define which backend is used based on the subdomain/path given. You can usehost starts withorhost containsfor subdomains, andpath starts withorpath containsfor paths. In value, set the subdomain/path that will be used to access the service (i.e.ombifor ombi.domain.com, or/ombifor domain.com/ombi).
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 destinationThis firewallat port 80 (select HTTP in theDestination Port RangeFromdropdown). - 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.