Release date: December 28th 2020, updated September 1st 2022
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 update
sudo 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-common
sudo add-apt-repository ppa:vbernat/haproxy-2.1
sudo apt-get update
sudo 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/certbot
sudo apt-get update
sudo 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
#!/usr/bin/env bash
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
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
stats timeout 30s
user haproxy
group haproxy
daemon
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-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-sslv3
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend ssl
bind 10.0.100.10:443 ssl crt /etc/ssl/desktop.frelab.net/desktop.frelab.net.pem
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt-backend if letsencrypt-acl
redirect scheme https code 301 if !{ ssl_fc }
mode http
default_backend ssl
backend ssl
mode http
balance source (IT IS IMPORTANT TO SET SOURCE AS UAG WON'T WORK WITH ROUND ROBIN)
option forwardfor
server hz-uag-01 10.0.100.11:443 check ssl verify none
server hz-uag-02 10.0.100.12:443 check ssl verify none
backend letsencrypt-backend
server letsencrypt 127.0.0.1:8888
listen stats
bind 10.0.100.10:1936
stats enable
stats hide-version
stats refresh 30s
stats show-node
stats auth stats:password
stats 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.cfg
sudo 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: HAProxy Export certificates
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.