Setting up HAProxy with Comodo PositiveSSL certificates

This post outlines my experience with setting up HAProxy to use Comodo PositiveSSL certificates. I've come across this when setting up HAProxy to distribute incoming requests to different Docker containers on my server and I've written this because I could not find the information on how to do this in one place.

This is not a tutorial or a definitive guide, it's just what worked for my setup. Your results might vary.

Comodo Positive SSL and HAProxy

I've decided to use HAProxy as a reverse proxy for my Docker-ized server for HTTPS requests and after a little searching, I've found that SSL support has been added to HAProxy since version 1.5.0 and basic usage seems very simple and straightforward.

I had already set up HAProxy to handle plain HTTP requests, so all I had to do was to duplicate my HTTP frontend entry and change the bind and reqadd parameters for that frontend. In my particular case, the statements look like this:

bind *:443 ssl crt /etc/haproxy/certs/lucianpantelimon.info.pem
reqadd X-Forwarded-Proto:\ https

In order to be able to use my certificate, I needed to find a way to combine the certificate files that I had in order to make the .pem file accepted by HAProxy.

After a bit of digging on the Internet, I've come across this post which said that in order for a certificate to be used by HAProxy, it has to be stored as a .pem file that contains all the certificate information in this order:

  1. lucianpantelimon.info.key - the certificate private key that was generated with the certificate signing request
  2. lucianpantelimon_info.crt - the signed certificate that you want to use
  3. intermediate.bundle - the intermediary certificates bundle (or certificate chain)

When looking at the files received from Comodo, I've noticed that I had three files instead of a single bundle file that I was supposed to use. I figured that the next step should be combining the files received from Comodo into the certificate chain bundle file mentioned above.

A bit more digging and this article came up with the solution - join all the files together in a specific order to form the desired bundle:

  1. COMODORSADomainValidationSecureServerCA.crt
  2. COMODORSAAddTrusCA.crt
  3. AddTrustExternalCARoot.crt

After generating the .bundle file and then the .pem file, I've started HAProxy, pointing it to the container hosting this site and did a few tests: this setup seems to be working well on Firefox, Chrome and Safari. I have not tested this with other browsers, but, if and when I do, I'll update this article to include them.

Last, but not least, here is the complete list of commands that I've issued to create the .pem file used by HAProxy:

    cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > intermediate.bundle
    cat lucianpantelimon.info.key >> lucianpantelimon.info.pem
    cat lucianpantelimon_info.crt >> lucianpantelimon.info.pem
    cat intermediate.bundle >> lucianpantelimon.info.pem

I hope that this article helped you if you had a similar issue.

If you have any questions or suggestions, please use the comment section below.


Update:
After testing this setup for multiple domains on an Android 2.3 browser, I've noticed that the certificates were not served correctly for some of the domains.

This happens because HAProxy uses Server Name Indication (SNI) to figure out which certificate to send to the browser and, thus, the browser must support SNI.

If the browser does not provide SNI, the first certificate in the list is served by HAProxy, regardless of the domain the request belongs to. This means that if you want to set up a HAProxy instance for multiple domains, your certificates might not be served correctly for some of the domains.

I will look around for a way to work around this when dealing with browsers that do not support SNI (while keeping SSL termination at HAProxy level) and will post an update with the solution. If you are looking to use HAProxy for a single domain, reproducing the steps above should be sufficient. Otherwise, stay tuned for an update on this issue.


Want to receive updates about new articles? Add me on Twitter or Google+