One of the tools that I use for my personal websites, including this blog, is haproxy. These steps produce an install of haproxy that supports all HTTP versions up to HTTP/3.
Here are some distilled instructions for installing it from source. I primarily use Ubuntu.
The center of all this is a series of shell scripts that I use to automate the build and install. At the following github URL you will find all the scripts:
Clone the repo using normal gthub methods.
There is a script included that will do all the prep tasks and install prerequisite packages. It has been tested on Ubuntu Server and AlmaLinux 8, but should work on any RHEL/Fedora clone and all distros derived from Debian, which includes Ubuntu, Mint, and of course Debian. If you have some other OS, you may need to examine the prep_source script and work out what to do for your OS. On Debian-derived systems, the prep_source script will make some carefully tested changes to the file
/etc/apt/sources.list in order to add source repositories. That modification should be safe for all users of Debian-derived systems, but it can’t be 100% guaranteed. It will also install and start docker.
The first time you run through these instructions, you’ll need to do the commands below to prepare the source directory and install/activate the haproxy service in systemd. After the first time, you can skip to the wide horizontal line below to update or reinstall.
cd /path/to/cloned/git/repo sudo ./prep_source sudo ./install-haproxy-service git-haproxy-2.8
If your OS is using some form of sysvinit, the service installer script in the commands above will almost certainly fail to install the haproxy service. You’re on your own for getting that done. Consider switching to something better. Many modern POSIX operating systems are using systemd because it’s more robust than the old sysvinit. There are likely service install instructions for sysvinit that Google can find. The scripts used above will not start the service, as that gets handled later as part of the build.
With the git repos cloned, prerequisite packages installed, and the service installed, run the fullstack command. It will build/install the latest quictls openssl and the latest haproxy dev version, then restart haproxy.
If you haven’t created /etc/haproxy/haproxy.cfg with a good config before running fullstack, then starting the service will fail, and you’ll need to take care of installing a config before trying to start the service. Also be aware that if you ask haproxy to listen on ports that another process is already listening on, the service start will also fail. This can be a problem if you have a webserver like Apache or Nginx installed.
I have included a sample haproxy config and sample certificate list in the repo. These are redacted versions of the config that I use. It is unlikely that they are usable as-is, but they serve to illustrate how haproxy can be used for a few different backends. The sample config achieves a grade of A+ on the Qualys Labs SSL test. Note that if your server has multiple IP addresses, that you must set up UDP bind lines for the IP addresses you’re going to use individually. It will not work properly if you use the 0.0.0.0 address that you’ll find in the sample config. This is a quirk of how UDP works, it is not an indication of a problem.
Updates to quictls are infrequent, so most of the time you just need to upgrade haproxy. The fullstack script will compile and install both quictls and haproxy. I jsut use the fullstack script when I do an update, but you can save a little bit of time on the compile if you only update haproxy with a command like below.
sudo ./new-haproxy git-haproxy-2.8
Installing quictls with these scripts adds a “qssl” script to /usr/local/bin that will run the quictls variant of openssl that it installs. This is done so the alternate openssl is available in a way that doesn’t interfere with the stock openssl.
I have haproxy listening on ports 80 and 443, and Apache listening on port 81 only. I also have backends for Plex, Gitlab, and and a few other things.
For the most part, I have disabled TLS on the back end services. I had to leave TLS enabled on the Plex backend. None of the backends other than Plex are reachable from the Internet, and Plex is only available because that’s what Plex requires to work properly, so they have taken steps to make it secure.
QUIC/HTTP3 will require both UDP and TCP traffic allowed on port 443. QUIC/HTTP3 is a UDP protocol, but the first time the browser makes contact, it will be over TCP, using an earlier HTTP version.
The git repo includes a config file for gitlab that sets up a CI/CD pipeline. It requires a gitlab-runner configured for shell.