How to Configure HAproxy 1.5 to Trust All System CAs for Backend Certificate Verification


2 views

When working with HAproxy 1.5's SSL/TLS backend verification, many administrators face a common pain point: the ca-file parameter only accepts a single certificate authority file, while modern systems typically maintain a whole directory of trusted CAs (usually in /etc/ssl/certs). This becomes problematic when:

  • Backend servers use certificates issued by different CAs
  • Certificate chains need to be validated against multiple root certificates
  • You want to leverage the system's existing trust store

The ca-base parameter might seem like a solution at first glance, but it's actually just a path prefix helper. Consider this configuration snippet:

backend secure_app
    server app1 192.168.1.10:443 check ssl verify required ca-file /etc/ssl/certs/GlobalSign_Root_CA.pem

This works fine until your backend switches to a certificate signed by DigiCert instead of GlobalSign. You'd then need to manually update the CA file reference.

Most Linux systems provide a consolidated CA bundle that contains all trusted root certificates. On Debian/Ubuntu systems, this is typically:

/etc/ssl/certs/ca-certificates.crt

And on RHEL/CentOS:

/etc/pki/tls/certs/ca-bundle.crt

Here's how to configure HAproxy 1.5 to use the system CA bundle:

global
    # Set the base directory for SSL certificates
    ca-base /etc/ssl/certs

backend api_backend
    mode http
    balance roundrobin
    option ssl-hello-chk
    server api1 api.example.com:443 check ssl verify required ca-file /etc/ssl/certs/ca-certificates.crt

After implementing this configuration, test your setup with:

openssl s_client -connect backend.example.com:443 -showcerts < /dev/null

Verify that HAproxy properly validates certificates against your system's trust store by checking the logs:

tail -f /var/log/haproxy.log | grep SSL

If your system doesn't have a pre-bundled CA file, you can create one manually:

# For Debian/Ubuntu:
sudo find /etc/ssl/certs -name '*.pem' -exec cat {} \; > /etc/ssl/certs/ca-bundle.crt

# Then reference it in HAproxy:
server node1 10.0.0.1:443 ssl verify required ca-file /etc/ssl/certs/ca-bundle.crt

Note that newer versions of HAproxy (1.6+) have improved CA handling capabilities, including:

  • Support for multiple CA files
  • Built-in certificate chain verification
  • More flexible SSL configuration options

However, if you're constrained to version 1.5, the system CA bundle approach remains the most reliable method.

Here's a complete backend configuration example:

backend secure_backend
    mode http
    balance leastconn
    option httpchk GET /health
    http-check expect status 200
    server web1 192.168.1.100:8443 check ssl verify required ca-file /etc/ssl/certs/ca-certificates.crt
    server web2 192.168.1.101:8443 check ssl verify required ca-file /etc/ssl/certs/ca-certificates.crt
    timeout connect 5s
    timeout server 30s

When working with HAproxy 1.5.x, many administrators face the limitation of only being able to specify individual CA certificates through the ca-file parameter in backend server definitions. This becomes problematic when:

  • Backend servers use certificates issued by different CAs
  • New CAs need to be added without HAproxy restart
  • You want to leverage the system's existing trust store

The ca-file parameter expects a single file containing one or more concatenated CA certificates. While you can combine multiple CAs into one file, this requires manual maintenance when system CAs change.

The ca-base parameter only helps with path resolution - it doesn't solve the dynamic CA trust problem:


# Example of traditional approach (limited)
backend https_servers
    server srv1 192.168.1.10:443 check ssl verify required ca-file /etc/ssl/certs/specific_ca.pem

Here's how to make HAproxy 1.5 use your system's CA certificates:

  1. Create a combined CA file from your system store:
  2. 
    sudo cat /etc/ssl/certs/*.pem > /etc/haproxy/ca-certs.pem
    # Set appropriate permissions
    chmod 644 /etc/haproxy/ca-certs.pem
    
  3. Configure HAproxy to use this combined file:
  4. 
    global
        # Base directory for CA certificates
        ca-base /etc/haproxy
    
    backend https_servers
        server srv1 192.168.1.10:443 check ssl verify required ca-file ca-certs.pem
        server srv2 192.168.1.11:443 check ssl verify required ca-file ca-certs.pem
    

To handle CA updates automatically, create a cron job or systemd timer:


# Example cron job (runs weekly)
0 3 * * 0 cat /etc/ssl/certs/*.pem > /etc/haproxy/ca-certs.pem && systemctl reload haproxy

Test your configuration with:


haproxy -c -f /etc/haproxy/haproxy.cfg

Common issues to check:

  • File permissions on the combined CA file
  • Certificate formats (must be PEM)
  • HAproxy worker process ownership

If you can upgrade, HAproxy 1.6+ supports dynamic CA loading:


server srv1 192.168.1.10:443 check ssl verify required crt-base /etc/ssl/certs