====================== HAProxy on |pfsense| ====================== .. meta:: :description: HA Proxy on pfSense :keywords: pfSense, networking, security, firewall, network, firewalling, load balancing, ha proxy, haproxy, virtualhosts :robots: noindex,nofollow **HAProxy** is an high performance TCP/HTTP load balancer. With **HA Proxy** on |pfsense| we can publish and balancing applications from our **DMZ**. We can use **Let's Encrypt** certificates centrally in |pfsense| without load it on each servers, this permit to automatically renew each certificate form |pfsense|. Scenario ========= For this tutorial we will configure **HAProxy** to publish two **Apache** virtualhosts through a **WAN CARP** ip address of our |pfsense| HA system. |br| This two virtualhost will be balanced in two different servers in HTTPS. |br| The x 509 certificates will reside only in |pfsense|, **HAProxy** will put in the middle and will open a crypted connection with client and one not crypted with server. Planning ========== Here we need to decide the FQDN for the servers and virtualhosts. .. list-table:: Servers :widths: 25 25 :header-rows: 1 :align: center * - Server - IP Address * - web1.oneos.it - 192.168.34.100 * - web2.oneos.it - 192.168.34.101 .. list-table:: VirtualHosts :widths: 25 25 :header-rows: 1 :align: center * - FQDN - CARP IP * - bc.oneos.it - 203.0.113.254 * - docs.oneos.it - 203.0.113.254 .. attention:: Virtualhost FQDN must be registered on DNS authoritative for domain ``oneos.it`` To make a test we need two ``index.php`` that identify the server where the page reside. |br| This pages will load in every webroot directory of the virtualhosts one for ``web1.oneos.it`` and one for ``web2.oneos.it`` .. highlight:: html :linenothreshold: 1 :: WEB1.ONEOS.IT

I'm on web1.oneos.it server

.. highlight:: html :linenothreshold: 1 :: WEB2.ONEOS.IT

I'm on web2.oneos.it server

Prerequisites ============== We assume that the two servers are already configured to publish virtualhosts in HTTP only and with working PHP module, if not, you can read this tutorial: :doc:`apache-vhosts`. For publish these sites in HTTPS we need to obtain valid certificates, for this tutorial we will use :abbr:`ACME(Automatic Certificate Management Environment)` for request to Let's Encrypt. |br| You can view how to obtain valid certificates from Let's Encrypt here: :doc:`letsencrypt`. Installation Basics ==================== In |pfsense| it's possible to install **HAProxy** using the **Package Manager** utility. Go to **System** |rarrow| **Package Manager** |rarrow| **Available Packages** and install the ``haproxy`` package. |br| HA Proxy Configurations ========================= There is a tab called **Templates**. In this page there are some template for easy configure exactly this scenario, and other things, we do not use it because we need to learn how **HAProxy** works. We configure first **Beckend** section, **Frontend** and finally we will active **HAProxy** on **Sectings** section. Backend -------- Go to **Services** |rarrow| **HAProxy** |rarrow| **Bakend** tab. |br| On **Backend** tab will add a server pool for each virtualhost |br| Click |btn-add-plus| button to configure first virtualhost ``bc.oneos.it``. Backend - ``bc.oneos.it`` '''''''''''''''''''''''''' Name: bc.oneos.it Server list: In the Table click on down arrow |fa-level-down| to add a server. Mode: active Name: web1 Forwardto: Address-Port Address: 192.168.34.100 Port: 80 Encrypt(SSL): uncheked CA: Acmecert: O=Let's Encrypt, CN=R3, C=US (CA: Acmecert: O=Internet Security Research Group, CN=ISRG Root X1, C=US) [Server cert] Client Certificate: bc.oneos.it (CA: Acmecert: O=Let's Encrypt, CN=R3, C=US) [Server cert] .. note:: Repeat for all servers in a pool. Server list: In the Table click on down arrow |fa-level-down| to add a server. Mode: active Name: web2 Forwardto: Address-Port Address: 192.168.34.101 Port: 80 Encrypt(SSL): uncheked CA: Let's Encrypt Client Certificate: bc.oneos.it Loadbalancing Options (when multiple servers are defined) Round Robin Click |btn-save| The first virtualhost beckend was finishd. |br| Backend - ``docs.oneos.it`` ''''''''''''''''''''''''''''' Click |btn-add-plus| button to configure the second virtualhost ``docs.oneos.it`` Name: docs.oneos.it Server list: In the Table click on down arrow |fa-level-down| to add a server. Mode: active Name: web1 Forwardto: Address-Port Address: 192.168.34.100 Port: 80 Encrypt(SSL): uncheked CA: Let's Encrypt Client Certificate: docs.oneos.it .. note:: Repeat for all servers in a pool. Server list: In the Table click on down arrow |fa-level-down| to add a server. Mode: active Name: web2 Forwardto: Address-Port Address: 192.168.34.101 Port: 80 Encrypt(SSL): uncheked CA: Let's Encrypt Client Certificate: docs.oneos.it Loadbalancing Options (when multiple servers are defined) Round Robin Click |btn-save| The result of **Server list** must be the same here. .. figure:: images/back_bc_1.png :alt: Backend bc.oneos.it :width: 700px :class: with-shadow :align: center Backend bc.oneos.it All virtualhosts was completed, now we need to configure the **HAProxy** frontend. |br| Frontend --------- Go to **Frontend** tab and click **Add**. For this tutorial we need 5 different frontend, two to hook to the beckends and the other three as explaned below. https_shared: This is the **SSL termination**, all request to applications will pass to this frontend and will perform encryption and dectryption of all traffic between client and servers. This type of frontend will use to put the virtualhosts on the same frontend ip addreess like **CARP IP** or **Ip Alias**. http_deny: This is a rule that block all request without a domain name, for example with ip address with HTTP status 403 (forbidden). http_redirect: All traffic to port 80 (``HTTP``) will be redirect to port 443 (``HTTPS``). Click |btn-add-down| Frontend - ``https_shared`` '''''''''''''''''''''''''''' Name: https_shared External address: In the Table Listen address: ``203.0.113.254 (WAN CARP Gateway)`` Port: ``443`` SSL Offloading ``checked`` Type: ``http/https(offloading)`` Separate sockets: ``checked`` Certificate: ``bc.oneos.it`` Add ACL for certificate Subject Alternative Names: ``checked`` Additional certificates: In the Table click on down arrow |fa-level-down| to add a server. Certificates: ``docs.oneos.it`` Add ACL for certificate Subject Alternative Names: ``checked`` .. note:: **Additional certificates** - you will must add here every new virtualhost. Click |btn-save| Click |btn-add-down| Frontend - ``bc.oneos.it`` '''''''''''''''''''''''''''''' Name: bc.oneos.it Satus: ``Active`` Shared Frontend: ``checked`` Primary Frontend: ``https_shared - http`` Access Control lists: In the Table click on down arrow |fa-level-down| to add a server. Name: ``bc`` Expression: ``Host contains:`` Value: ``bc.oneos.it`` Actions: In the Table click on down arrow |fa-level-down| to add a server. Action: ``Use Backend`` Condition acl names: ``bc`` Backend: ``bc.oneos.it`` Click |btn-save| Click |btn-add-plus| Frontend - ``docs.oneos.it`` '''''''''''''''''''''''''''''' Name: docs.oneos.it Satus: ``Active`` Shared Frontend: ``checked`` Primary Frontend: ``https_shared - http`` Access Control lists: In the Table click on down arrow |fa-level-down| to add a server. Name: ``docs`` Expression: ``Host contains:`` Value: ``docs.oneos.it`` Actions: In the Table click on down arrow |fa-level-down| to add a server. Action: ``Use Backend`` Condition acl names: ``docs`` Backend: ``docs.oneos.it`` Click |btn-save| Frontend - ``http_deny`` '''''''''''''''''''''''''''' Name: ``http_deny`` Status: ``Active`` Shared Frontend: ``checked`` Primary frontend: ``https_shared - http`` Access Control lists: In the Table click on down arrow |fa-level-down| to add a server. Name: ``not_domain`` Expression: ``Host contains:`` Not: ``checked`` Value: ``oneos.it`` Actions: In the Table click on down arrow |fa-level-down| to add a server. Action: ``http-request deny`` Condition acl names: ``not_domain`` Click |btn-save| Click |btn-add-plus| Frontend - ``http_redirect`` '''''''''''''''''''''''''''''' Name: ``http_redirect`` Status: ``Active`` Shared Frontend: ``unchecked`` External adress: In the Table click on down arrow |fa-level-down| to add a server. Listen address: ``203.0.103.254 (WAN CARP Gateway)`` Port: ``80`` Actions: In the Table click on down arrow |fa-level-down| to add a server. Action: ``http-request redirect`` rule: ``scheme https`` Click |btn-save| Settings ''''''''' Go to **Settings** tab. |br| Check **Enabel HAProxy**. |br| Maximum connections: 1000 Carp monitor: ``203.0.113.254 (WAN CARP Gateway)`` Internal stats port: 2200 HAProxy Sync: ``checked``, this is for |pfsense| HA systems, will syncronize configuration with Secondary |pfsense|. Click |btn-save| Firewall Rules ================ For publish the virtualhosts it's necessary to make a rule on **WAN** interface that open the ``HTTP`` and ``HTTPS`` ports on **CARP WAN Gateway**. |br| Go to **Firewall** |rarrow| **Alias** and make an alias for **HTTP** and **HTTPS** ports. Click on |btn-add-plus|. |br| Name: ``HTTP_PORTS`` Descriptions: ``HTTP and HTTPS ports`` Type: ``Port(s)`` Port: ``80`` - ``port 80`` |br| click on |btn-add-port| |br| ``443`` - ``port 443`` Gp to **Firewall** |rarrow| **Rules** |rarrow| **WAN** and click on |btn-add-up| Action: ``Pass`` Interface: ``WAN`` Address Family: ``IPv4`` Protocol: ``TCP`` Source: ``any`` Destination: ``This firewall (self)`` Destination Port Range: ``other`` Custom: ``HTTP_PORTS`` Click |btn-save| |br| Click |btn-apply| Verifing HAProxy ================= We will make some tests. - Open a browser and go to http://bc.oneos.it. **HAProxy** redirect you on https://bc.oneos.it, check the validity of the certificate. Now reload the page, you should see the web page on the second server. - Make the same test for http://docs.oneos.it. HAProxy Stats ============== In the tab **Stats** there are some useful statistics, and in a tab **Stats FS** there is a link on the same statistic page without user login. |br| The link is \https://PFSENSEADMINPAGE:PORT/haproxy/haproxy_stats.php?haproxystats=1.