Debugging SSL Handshake Failure in Apache Reverse Proxy Setup (502 Error)


4 views

When configuring Apache as an HTTPS reverse proxy to a backend service (localhost:3002 in this case), SSL handshake failures can occur due to several misconfigurations. The error manifests as:

[error] proxy: Error during SSL Handshake with remote server
[error] (502)Unknown error: 502: proxy: pass request body failed

First, verify your certificate chain is properly configured. The current setup uses:

SSLCertificateFile "/private/etc/apache2/certs/newcert.pem"
SSLCACertificateFile "/private/etc/apache2/certs/demoCA/cacert.pem"

Run this diagnostic command:

openssl verify -CAfile /private/etc/apache2/certs/demoCA/cacert.pem \
/private/etc/apache2/certs/newcert.pem

The critical missing piece is configuring Apache to properly handle SSL to the backend. Add these directives:

SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off

The current cipher suite configuration is outdated and potentially problematic:

SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

Modernize it with:

SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
SSLProxyCipherSuite HIGH:!aNULL:!MD5:!RC4
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

Here's the corrected virtual host configuration:

<VirtualHost *:443>
    SSLEngine on
    SSLProxyEngine On
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    RequestHeader set Front-End-Https "On"
    CacheDisable *
    
    # Modern cipher configuration
    SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
    SSLProxyCipherSuite HIGH:!aNULL:!MD5:!RC4
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    
    DocumentRoot "/Users/me/projects/myproject/public"
    ServerName ssl.mydomain.com
    ServerAlias *.ssl.mydomain.com
    
    # Certificate paths
    SSLCertificateKeyFile "/private/etc/apache2/certs/webserver.nopass.key"
    SSLCertificateFile "/private/etc/apache2/certs/newcert.pem"
    SSLCACertificateFile "/private/etc/apache2/certs/demoCA/cacert.pem"
    SSLCARevocationPath "/private/etc/apache2/certs/demoCA/crl"
    
    ErrorLog "/Users/me/Desktop/ssl.log"
    
    # Proxy configuration
    ProxyPass / https://localhost:3002/
    ProxyPassReverse / https://localhost:3002
    ProxyPreserveHost on
    
    # Important for Node.js backend
    ProxyRequests off
    ProxyVia on
</VirtualHost>

1. Test backend connectivity directly:

curl -vk https://localhost:3002

2. Verify Apache SSL configuration:

apachectl configtest
apachectl -t -D DUMP_VHOSTS

3. Check SSL handshake details:

openssl s_client -connect localhost:3002 -showcerts -debug
  • Mismatched SSL protocols between Apache and backend
  • Self-signed certificates without proper trust chain
  • Missing SSLProxyEngine directives
  • Firewall blocking port 3002
  • Backend service not actually running HTTPS

When setting up an HTTPS reverse proxy with Apache, the "SSL Handshake Failed" error typically occurs during communication between your Apache server and the backend service (in this case, running on localhost:3002). The error logs show:

[error] proxy: Error during SSL Handshake with remote server
[error] proxy: pass request body failed to 127.0.0.1:3002

Your current VirtualHost configuration has several potential problems:

<VirtualHost *:443>
    SSLEngine on
    SSLProxyEngine On
    # ... existing configuration ...
    ProxyPass / https://localhost:3002/
    ProxyPassReverse / https://localhost:3002
</VirtualHost>

The main issues are:

  • Missing SSLProxyVerify directive for backend verification
  • No SSLProxyCheckPeerCN/Expire configuration
  • Potentially mismatched SSL protocols between Apache and backend

Here's an improved configuration that should resolve the handshake issues:

<VirtualHost *:443>
    SSLEngine on
    SSLProxyEngine On
    
    # Frontend SSL configuration
    SSLCertificateFile "/private/etc/apache2/certs/newcert.pem"
    SSLCertificateKeyFile "/private/etc/apache2/certs/webserver.nopass.key"
    SSLCACertificateFile "/private/etc/apache2/certs/demoCA/cacert.pem"
    
    # Modern SSL configuration
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
    SSLHonorCipherOrder on
    
    # Backend proxy SSL configuration
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerExpire off
    
    # Proxy settings
    RequestHeader set Front-End-Https "On"
    ProxyPass / https://localhost:3002/ retry=0 timeout=30
    ProxyPassReverse / https://localhost:3002
    ProxyPreserveHost on
    
    # Logging
    ErrorLog "/Users/me/Desktop/ssl.log"
    LogLevel info proxy:trace5 ssl:warn
</VirtualHost>

If the problem persists, try these debugging techniques:

# Test backend SSL directly:
openssl s_client -connect localhost:3002 -showcerts

# Check Apache SSL configuration:
apachectl configtest
apachectl -S

# Enable detailed logging:
LogLevel debug ssl:trace2 proxy:trace5
  • Backend service not properly configured for HTTPS
  • Certificate chain issues (missing intermediate certificates)
  • Mismatched TLS versions between Apache and backend
  • Firewall blocking localhost SSL connections

If you're proxying to a local service, consider using HTTP instead of HTTPS for the backend connection:

ProxyPass / http://localhost:3002/
ProxyPassReverse / http://localhost:3002

This eliminates the SSL handshake complexity while still maintaining frontend HTTPS security.