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 keys
and pressAdd
.
Set a name, select the ACME server (Production ACME v2
), set your email address, and pressCreate new account key
to generate your key. Once the box is populated, pressRegister ACME account key
and hitSave
. -
Now that we’ve got an account key, we can make a cert. Navigate to
Certificates
and 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
Issue
to 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 size
to 2048 underTuning
. -
Press
Save
followed 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
Frontend
and clickAdd
. -
Name your service (
https_shared
works). -
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
Save
and 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 redirect
and 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 Frontend
box and selecthttps_shared
. -
We’ll use
Access Control lists
to define which backend is used based on the subdomain/path given. You can usehost starts with
orhost contains
for subdomains, andpath starts with
orpath contains
for paths. In value, set the subdomain/path that will be used to access the service (i.e.ombi
for ombi.domain.com, or/ombi
for 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 firewall
at port 80 (select HTTP in theDestination Port Range
From
dropdown). - Make an identical entry for
HAProxy_HTTPS
traffic 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.