When setting up Apache as an SSL reverse proxy for Tomcat, a common error encountered is:
Bad Gateway
The proxy server received an invalid response from an upstream server.
For a proper SSL reverse proxy setup, you need:
- Correct SSL certificates configured in Apache
- Proper proxy directives (ProxyPass/ProxyPassReverse)
- Correct Tomcat connector configuration
- Consistent scheme (https) and port settings
The working configuration should include these critical elements:
LoadModule ssl_module modules/mod_ssl.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:443>
SSLEngine On
SSLProxyEngine On
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
SSLCertificateChainFile /path/to/chain.pem
ServerName yourdomain.com
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass / http://localhost:8080/ retry=0 timeout=30
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
The Tomcat server.xml needs these adjustments:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
proxyName="yourdomain.com"
proxyPort="443"
scheme="https"
secure="true"
URIEncoding="UTF-8"/>
If you still encounter the Bad Gateway error:
- Verify Apache can reach Tomcat:
curl http://localhost:8080
- Check Apache error logs:
tail -f /var/log/httpd/error_log
- Ensure all required modules are loaded
- Test SSL connection independently first
- Verify firewall isn't blocking internal connections
For production environments, consider adding:
# Enable SSL session caching
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout 300
# Stronger ciphers
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4
SSLHonorCipherOrder on
Remember to restart both Apache and Tomcat after configuration changes:
sudo service httpd restart
sudo service tomcat restart
When implementing SSL termination with Apache in front of Tomcat, the configuration requires careful coordination between several components:
Apache (SSL Termination) → Proxy → Tomcat (Backend)
Your setup needs to properly handle these aspects:
- SSL certificate chain verification
- Header preservation through proxy
- Port and scheme consistency
- Protocol compatibility
Looking at your provided setup, here's the improved version with critical fixes:
<VirtualHost _default_:443>
SSLEngine On
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLCertificateFile /etc/pki/tls/learn2gether/cert-6090205098829887.pem
SSLCertificateKeyFile /etc/pki/tls/learn2gether/private_key_unlocked.pem
SSLCertificateChainFile /etc/pki/tls/learn2gether/rubca-chain.pem
# Modern SSL configuration
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
ServerName www.learn2gether.rubel.rub.de
ServerAlias learn2gether.rubel.rub.de
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
The key changes that resolve the Bad Gateway error:
- Changed proxy target from HTTPS to HTTP (Tomcat should handle plain HTTP)
- Added forwarding headers to maintain scheme information
- Simplified SSL configuration with modern security standards
- Removed conflicting directives like DocumentRoot in SSL vhost
The corresponding Tomcat connector should look like this:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
proxyPort="443"
proxyName="www.learn2gether.rubel.rub.de"
scheme="https"
secure="true" />
After implementing these changes, verify with:
# Check Apache syntax
apachectl configtest
# Test SSL handshake
openssl s_client -connect www.learn2gether.rubel.rub.de:443 -servername www.learn2gether.rubel.rub.de
# Check headers
curl -v -k -H "Host: www.learn2gether.rubel.rub.de" https://localhost/
- Mismatched proxy protocols (HTTPS vs HTTP)
- Missing or incorrect forwarding headers
- Certificate chain issues
- Port conflicts between services