Configuring Apache mod_proxy to Handle Both HTTP and HTTPS ProxyPass Requests to Tomcat


2 views

When setting up Apache HTTP Server as a reverse proxy for Tomcat with both HTTP and HTTPS endpoints, we often need to route requests differently based on the incoming protocol. The core issue emerges when we want:

  • HTTP requests to /tomcat/ → Tomcat's HTTP port (8080)
  • HTTPS requests to /tomcat/ → Tomcat's HTTPS port (8443)

The key is using separate blocks for each protocol. Here's the complete working configuration:

NameVirtualHost *:443
NameVirtualHost *:80

# HTTP VirtualHost

    ServerName myserver
    
    ProxyPreserveHost On
    ProxyPass /tomcat/ http://localhost:8080/
    ProxyPassReverse /tomcat/ http://localhost:8080/
    
    # Optional: Redirect all HTTP to HTTPS
    #RewriteEngine On
    #RewriteCond %{HTTPS} off
    #RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}


# HTTPS VirtualHost

    ServerName myserver
    
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
    
    ProxyPreserveHost On
    ProxyPass /tomcat/ https://localhost:8443/
    ProxyPassReverse /tomcat/ https://localhost:8443/
    
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off

Several elements are essential for proper functionality:

# Enable these modules (Debian/Ubuntu example)
a2enmod proxy proxy_http proxy_connect ssl rewrite

# Required for HTTPS proxying
SSLProxyEngine on

# Disable strict certificate validation if using self-signed certs
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off

If you encounter the "Page not found" error, check these:

  1. Verify mod_proxy and mod_ssl are enabled
  2. Ensure the VirtualHost blocks are properly separated
  3. Check Apache error logs for specific proxy errors
  4. Test connectivity to Tomcat ports directly
  5. Confirm SELinux/apparmor isn't blocking connections

For more complex setups, consider:

# Path-specific routing
ProxyPass /tomcat/app1 http://backend1:8080/app1
ProxyPass /tomcat/app2 http://backend2:8080/app2

# Load balancing across multiple Tomcat instances

    BalancerMember http://tomcat1:8080
    BalancerMember http://tomcat2:8080

ProxyPass /tomcat balancer://tomcat-cluster

Many developers face challenges when configuring Apache's mod_proxy to handle both HTTP and HTTPS traffic differently. The core issue emerges when you need to:

  • Proxy HTTP requests to backend HTTP (Tomcat on port 8080)
  • Proxy HTTPS requests to backend HTTPS (Tomcat on port 8443)

The solution lies in proper VirtualHost separation. Your initial approach was correct but needed some adjustments:

# HTTP VirtualHost
<VirtualHost *:80>
    ServerName myserver
    ProxyPass /tomcat/ http://myserver:8080/
    ProxyPassReverse /tomcat/ http://myserver:8080/
</VirtualHost>

# HTTPS VirtualHost
<VirtualHost *:443>
    ServerName myserver
    SSLEngine on
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile /path/to/key.pem
    ProxyPass /tomcat/ https://myserver:8443/
    ProxyPassReverse /tomcat/ https://myserver:8443/
</VirtualHost>

The "page not found" error typically occurs because:

  1. Missing ServerName directive in VirtualHost
  2. SSL configuration not properly set up
  3. mod_proxy modules not enabled

Ensure you've enabled the required modules:

a2enmod proxy
a2enmod proxy_http
a2enmod ssl

For more complex scenarios, consider these additions:

# Preserve original protocol in headers
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"

Always verify your setup:

apachectl configtest
systemctl restart apache2

Test both endpoints:

curl -v http://myserver/tomcat/
curl -vk https://myserver/tomcat/