When deploying Comodo SSL certificates with HAProxy 1.5.3 on Ubuntu AWS instances, we encountered a peculiar situation where browsers validated the certificate correctly while network proxies and SSL checkers reported an incomplete chain. This is a common pitfall in HAProxy SSL configuration that deserves careful examination.
The openssl s_client
output reveals crucial details about the verification failure:
CONNECTED(00000003) depth=0 OU = Domain Control Validated, OU = COMODO SSL, CN = www.domainname.com verify error:num=20:unable to get local issuer certificate verify return:1
This indicates HAProxy isn't properly sending the intermediate certificate chain to clients during the TLS handshake.
The correct PEM file format for HAProxy should contain:
# Server certificate -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- # Intermediate certificate (must come immediately after) -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- # Private key (can be at beginning or end) -----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY-----
Common mistakes include:
- Wrong certificate order
- Missing intermediate certificates
- Incorrect line endings
The correct haproxy.cfg
SSL binding should look like:
frontend https-in bind *:443 ssl crt /etc/ssl/domainname.com.pem ca-file /etc/ssl/certs/comodo-intermediates.pem mode http option forwardfor http-request set-header X-Forwarded-Proto https
Key configuration notes:
- The
ca-file
directive helps HAProxy validate client certificates - Intermediate certificates should be in a separate file for client-auth scenarios
- HAProxy 1.5.3 requires explicit intermediate certificate inclusion
To validate your configuration:
openssl s_client -connect yourdomain.com:443 -showcerts -CApath /etc/ssl/certs/
Look for these indicators of success:
- Certificate chain shows 2+ certificates
- Verify return code: 0 (ok)
- No "unable to get local issuer certificate" errors
If issues persist:
- Verify certificate permissions (haproxy user needs read access)
- Check system clock synchronization (AWS instances should use NTP)
- Test with different SSL checkers (SSL Labs, CheckTLS.com)
- Consider upgrading to HAProxy 1.6+ for better SSL support
For production environments, consider these additional parameters:
bind *:443 ssl crt /etc/ssl/domainname.com.pem \ ca-file /etc/ssl/certs/comodo-intermediates.pem \ no-sslv3 no-tls-tickets ciphers HIGH:!aNULL:!MD5
This enhances security while maintaining chain verification.
When your HAProxy server shows certificate chain issues despite browsers working fine, this typically indicates missing intermediate certificates. The openssl output showing "unable to verify the first certificate" confirms this diagnosis.
Your current configuration shows:
bind *:443 ssl crt /etc/ssl/domainaname.com.pem
While the .pem file contains both certificate and private key, the chain verification failure suggests the intermediate certificates aren't being properly served.
The correct .pem file should contain components in this exact order:
-----BEGIN PRIVATE KEY-----
[Your private key]
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
[Your domain certificate]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Intermediate CA certificate]
-----END CERTIFICATE-----
For Comodo SSL certificates, you typically need to include two intermediate certificates:
- COMODO SSL CA
- COMODO RSA Certification Authority
Here's a working configuration example:
frontend https-in
bind *:443 ssl crt /etc/ssl/domain.com.pem ca-file /etc/ssl/comodo-intermediates.pem
mode http
default_backend servers
backend servers
server web1 10.0.0.1:80 check
Create a combined file with:
cat domain.key domain.crt COMODOSSLCA.crt COMODORSACA.crt > /etc/ssl/domain.com.pem
Verify the chain with:
openssl s_client -connect yourdomain.com:443 -showcerts
- Verify certificate order: Run
openssl x509 -in yourfile.pem -text -noout
to check each cert's subject/issuer - Test with SSL labs: https://www.ssllabs.com/ssltest/
- Check HAProxy logs:
journalctl -u haproxy
When using multiple intermediate certificates:
- Enable OCSP stapling:
ssl crt /path/to/pem ocsp
- Consider using separate files for better management