When configuring Apache (2.4+) as a load balancer with HTTPS backends, you might encounter SSL handshake failures even with proper SSLProxyEngine settings. Here's a deep dive into solving this common infrastructure challenge.
The error typically manifests in Apache logs with messages like:
[proxy:error] AH01084: pass request body failed to backend:443
[proxy:error] AH00898: Error during SSL Handshake with remote server
Browser responses show:
Proxy Error
Reason: Error during SSL Handshake with remote server
For modern Apache versions (2.4.5+), these directives are essential:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off # Crucial for newer Apache versions
Here's a production-tested configuration for a load-balanced cluster:
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
<Proxy balancer://secure-cluster>
BalancerMember https://backend1.example.com:443 route=node1
BalancerMember https://backend2.example.com:443 route=node2
ProxySet stickysession=ROUTEID
</Proxy>
ProxyPass / balancer://secure-cluster/
ProxyPassReverse / balancer://secure-cluster/
</VirtualHost>
While the solution works with self-signed certificates, consider these practices:
- Ensure consistent DNS naming in your infrastructure
- For production, use properly signed certificates or internal CA
- Test with OpenSSL directly:
openssl s_client -connect backend:443 -servername backend.example.com
If issues persist:
- Verify backend SSL configuration independently
- Check Apache error logs with
LogLevel debug
temporarily - Test with curl:
curl -v -k https://backend/test.jsp
- Verify TCP connectivity:
telnet backend 443
Terminating SSL at both layers adds overhead. Consider:
- HTTP/2 between load balancer and backends if supported
- Session resumption configuration
- OCSP stapling implementation
When configuring Apache 2.4 as a load balancer with HTTPS backends, you might encounter this frustrating scenario: HTTP backends work perfectly, but HTTPS connections fail with mysterious 502 errors and SSL handshake failures. Let's dissect this common issue that many sysadmins face when dealing with self-signed certificates in backend servers.
The error logs typically show these telltale signs:
[proxy:error] AH01084: pass request body failed to backend:443
[proxy:error] AH00898: Error during SSL Handshake with remote server
[proxy_http:error] AH01097: pass request body failed to backend:443
While the browser displays the unhelpful but accurate "Proxy Error" message indicating SSL Handshake failure with the remote server.
After extensive troubleshooting, the core issue emerges: certificate name verification. Even with SSLProxyVerify none
configured, Apache 2.4.5+ performs additional checks:
- Certificate Common Name (CN) must match the backend server name
- Subject Alternative Names (SANs) are also verified
For Apache 2.4.7+ configurations, you need these critical directives:
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
<Proxy balancer://securecluster>
BalancerMember https://backend1:443/test
BalancerMember https://backend2:443/test
ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass /test balancer://securecluster
ProxyPassReverse /test balancer://securecluster
When working with self-signed certificates:
- Always test direct connections to backends first using
openssl s_client -connect backend:443
- For production environments, consider proper certificates or configure
SSLProxyCACertificateFile
- Monitor connection states with
server-status
module
For complex setups with sticky sessions:
<Proxy balancer://stickycluster>
BalancerMember https://backend1:443/test route=node1
BalancerMember https://backend2:443/test route=node2
ProxySet stickysession=ROUTEID lbmethod=byrequests
</Proxy>
ProxyPass /test balancer://stickycluster
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
Remember to restart Apache after configuration changes and always check apachectl configtest
before applying changes to production environments.