Welcome to my HAProxy section. As part of my VMware Unified Access Gateway and Workspace ONE Access set up, I saw the need for a load balancing mechanism in my lab. As I don’t have a high-end Load Balancer easily available in my lab, I did some googling and found a very good open- source alternative, HAProxy. Before I started this setup, I reviewed VMware Digital Workspace Tech Zone’s Load Balancing Unified Access Gateway for Horizon.
Below I will describe how I installed and configured HAProxy on an Ubuntu 20.04 server. As I’m in no sense a Linux-expert, this has been planned for quite some while and I will be using Snapshots to ensure I have a fallback if anything goes wrong during the installation. My design will look like this:
The first thing I have to do is to create a virtual machine for this role. This I have documented here: HAProxy Virtual Machine Set Up
Next, I will install Ubuntu Server 20.04 in my virtual machine, documented here: HAProxy OS Installation
Finally, I can install and configure HAProxy with LetsEncrypt. First of all, I’m going to update the system packages:
sudo apt-get updatesudo apt-get upgrade
Next, I enable the PPA Repository for HAProxy and install it. For this set up I’m using the 2.1 version. The latest versions and builds are available here: HAProxy
sudo apt-get install software-properties-commonsudo add-apt-repository ppa:vbernat/haproxy-2.1sudo apt-get updatesudo apt-get install haproxy=2.1.\*
As I mentioned to begin with, I’m no Linux expert. Therefore I prefer to take some snapshots during the setup, which gives me the opportunity to roll back if I run into problems further into the set up. I will document at what point I take the snapshots below. All snapshots are taken with the VM shutdown
SNAPSHOT: Post-HAProxy-Installation
Now that HAProxy is installed, I can continue with installing LetsEncrypt
sudo add-apt-repository -y ppa:certbot/certbotsudo apt-get updatesudo apt-get install -y certbot
SNAPSHOT: Post-LetsEncrypt-Installation
Now I can request a new certificate for my HAProxy. Before I do this I make sure I have a public DNS pointer in place and the appropriate NAT/Port openings in my firewall. I will be using DNS challenge for my LetsEncrypt renewals, as I don’t want to open port 80 whenever I will do renewals.
sudo certbot -d desktop.frelab.net --manual --preferred-challenges dns certonly
When I run this command I will be represented with at text-string to put in a TXT-pointer in my public DNS Zone. Lets Encrypt now gives me a SSL Certificate in 2 files. As HAProxy requires 1 .pem file I have to merge the certificate-files using the following commands:
First I make a folder to store my certificate
sudo mkdir -p /etc/ssl/desktop.frelab.net
Next I merge the two files into my certificate “/etc/ssl/desktop.frelab.net/desktop.frelab.net.pem“
sudo cat /etc/letsencrypt/live/desktop.frelab.net/fullchain.pem \ /etc/letsencrypt/live/desktop.frelab.net/privkey.pem \| sudo tee /etc/ssl/desktop.frelab.net/desktop.frelab.net.pem
As it is a tedious task to renew certificates, I will create a CRON-job which will automatically renew my certificate. First I will edit the CRON job LetsEncrypt created during installation.
sudo nano /etc/cron.d/certbot
I will run a script on the first day of every month. I replace the current content with the following line
0 0 1 * * root bash /opt/update-certs.sh
Now I need to create the script that I specified in the CRON job above.This script will basically run all the commands needed to renew the certificate and merge it to one PEM-file.
sudo nano /opt/update-certs.sh
I add the following lines to the script
certbot renew --force-renewal --tls-sni-01-port=8888 (This will renew the certificate)bash -c "cat /etc/letsencrypt/live/desktop.frelab.net/fullchain.pem /etc/letsencrypt/live/desktop.frelab.net/privkey.pem > /etc/ssl/desktop.frelab.net/desktop.frelab.net.pem" (This will merge the certificate-files to one PEM-file)
SNAPSHOT: Post-LetsEncrypt-Certificate
Finally I configure my haproxy.cfg file to be using the LetsEncrypt certificate. This is my complete haproxy config: haproxy.cfg
globallog /dev/log local0log /dev/log local1 noticechroot /var/lib/haproxystats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listenersstats timeout 30suser haproxygroup haproxydaemonca-base /etc/ssl/certscrt-base /etc/ssl/privatessl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5$ssl-default-bind-options no-sslv3defaultslog globalmode httpoption httplogoption dontlognulltimeout connect 5000timeout client 50000timeout server 50000errorfile 400 /etc/haproxy/errors/400.httperrorfile 403 /etc/haproxy/errors/403.httperrorfile 408 /etc/haproxy/errors/408.httperrorfile 500 /etc/haproxy/errors/500.httperrorfile 502 /etc/haproxy/errors/502.httperrorfile 503 /etc/haproxy/errors/503.httperrorfile 504 /etc/haproxy/errors/504.httpfrontend sslbind 10.0.100.10:443 ssl crt /etc/ssl/desktop.frelab.net/desktop.frelab.net.pemacl letsencrypt-acl path_beg /.well-known/acme-challenge/use_backend letsencrypt-backend if letsencrypt-aclredirect scheme https code 301 if !{ ssl_fc }mode httpdefault_backend sslbackend sslmode httpbalance source <strong>(IT IS IMPORTANT TO SET SOURCE AS UAG WON'T WORK WITH ROUND ROBIN)</strong>option forwardforserver hz-uag-01 10.0.100.11:443 check ssl verify noneserver hz-uag-02 10.0.100.12:443 check ssl verify nonebackend letsencrypt-backendserver letsencrypt 127.0.0.1:8888</sub><sub>listen statsbind 10.0.100.10:1936stats enablestats hide-versionstats refresh 30sstats show-nodestats auth stats:passwordstats uri /stats
Now that have made all necessary changes in my HAProxy set up, I will verify my set up before restarting the HAProxy service
haproxy -c -f /etc/haproxy/haproxy.cfgsudo service haproxy restart
As I will be using this HAProxy in front of my VMware UAG’s, I will need to export the letsencrypt certificates and import them on the UAG’s. This I have documented here: How to Export Certificates from HAProxy
This completes my HAProxy set up. I have now tested and verified that everything works as per my design. I can now delete my snapshots and add the new server to my backup jobs. As an Open Source Load Balancer this more than delivers on my requirements. I’m aware that I’m not even close to using all of the potential of HAProxy, but it works like a charm in my lab.
Recommended reading:
VMware Digital Workspace Tech Zone: Load Balancing Unified Access Gateway for Horizon
koromicha’s post at kifarunix.com: Install and Setup HAProxy on Ubuntu 20.04
Dean Longstaff’s post: HAProxy as Reverse Proxy + SSL Termination
Rahul’s post at techadmin.net: How to Setup HAProxy Load Balancer on Ubuntu 18.04 & 16.04
Disclaimer: Every tips/tricks/posting I have published here, is tried and tested in different it-solutions. It is not guaranteed to work everywhere, but is meant as a tip for other users out there. Remember, Google is your friend and don’t be afraid to steal with pride! Feel free to comment below as needed.
