Installing HAProxy on pfSense with SSL access to web server

3 minute read

Introduction

HAProxy is a small but powerful reverse proxy, and allows for loadbalancing between multiple (web)servers, but also acl (Access Control Lists) allow for selecting a specific backend or action depending on flexible criteria. And though many features are available through webGUI. For all possible options please look at the official HAProxy documentation.

I have an nginx service in an Linux VM as a web server with a site nginx.example.com. In next time will be second VM with another web-service. I want to utilize HAProxy on my edge router (pfSense-2.4) to proxy to their appropriate backend VMs.

Environment

In this article I’ll be showing you how to do this with next version of components:

  1. pfSense 2.4.4
  2. haproxy package 0.59_19 (with included haproxy 1.7.11)
  3. Linux VM with NGINX accessed by IP 192.168.100.3
  4. Domain nginx.example.com directed on WAN pfSense.

Installation

So this post will describe how to open a web server from Internet by HTTPS and DNS name (nginx.example.com). Now it is accessible by local ip (192.168.100.3). The pfSense is edge router. And it already has free LetsEncrypt SSL certificates (how to get them - read previous post). HAproxy will help to make it easy.

haproxy package

Under System / Package Manager / Available Packages find a package haproxy. Click the install button and allow it to complete.

haproxy_package_install

configure haproxy

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

My setup is like so:

haproxy_configure

create backend

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 a host.

I have one host with NGINX-service listened 80 port on local IP 192.168.102.3.

haproxy_backend

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.

create 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 frontend that will routing all user requests to right backend based on hostname information. ACL provides many functions to optimize administrate all frontends in one place.

Use secure (https) connection with LetsEncrypt SSL certificates.

My frontend configuration looks like this:

haproxy_frontend

create firewall rule

Now create two firewall rules (Firewall / Rules /WAN). It is open TCP-ports 80 and 443 through WAN interface for opening our HAProxy to the external world.

haproxy_firewall_edit

haproxy_firewall_full

test everything

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

The site should have a “green” status because is used a secured connection.

haproxy_test

Some notes

After enable fronted with HTTPS I’ve got next warning message:

Starting haproxy:
[WARNING] 279/113603 (85707) : Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.

This is not error in the first place. To fix it change DH value throw HAproxy settings webGUI (Services / HAProxy / Settings). Tuning -> Max SSL Diffie-Hellman size = 2048

dh_tunning

The solution was founded in the forum

Additional information