Search code examples
apachetomcatsslproxyajp

Tomcat behind Apache httpd via SSL (httpd works, tomcat returns error 500)


I have a tomcat, listening on port 8080 and an apache httpd listening on ports 80 and 443.

The httpd proxies the client through to tomcat via ajp. This works like a charm.

The statement I made - quoted above - is wrong. I mistakenly assumed I set the proxy to use ajp-protocol, but I did really use plain http. This also lead to the answer of this question.

But if I try to connect via https, I get a secure connection which displays an error 500 that isn't logged anywhere. My guess is, that the https-connection to the httpd (443) is working, the ajp-proxy also works, but tomcat expects something I do not know about.

I already tried to connect the proxy to ports 8443 and 8080. In my opinion it would suffice for tomcat to be accessed on port 8080, because all traffic is redirected through httpd anyway.

Here is the configuration:

/etc/apache2/sites-available/default-ssl

<IfModule mod_ssl.c>
    ErrorLog /var/log/apache2/ssl_engine.log
    LogLevel error

    NameVirtualHost *:443

    <VirtualHost *:443>
            ServerName www.doma.in
            ServerAlias doma.in

            ServerSignature Off
            SSLEngine on

            SSLCertificateFile /etc/ssl/certs/ssl_certificate.crt
            SSLCertificateKeyFile /etc/ssl/certs/ssl_certificate.key
            SSLCertificateChainFile /etc/ssl/certs/intermediate_ca.crt

            ProxyPass / ajp://localhost:8080/ retry=0 timeout=240
            ProxyPassReverse / ajp://localhost:8080/
    </VirtualHost>
</IfModule>

/etc/tomcat7/server.xml

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
    <Listener className="org.apache.catalina.core.JasperListener" />
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

    <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"                    type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" />
    </GlobalNamingResources>

    <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443" />

        <!-- Define an AJP 1.3 Connector on port 8009 -->
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URLEncoding="UTF-8" />
        <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8080" URLEncoding="UTF-8" /> also tried this, but same result. -->

        <Engine name="Catalina" defaultHost="localhost">
            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
            </Realm>

            <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true"></Host>
        </Engine>
    </Service>
</Server>

Unfortunately I can't provide any logs, because the error does not appear in any of them.

Any ideas on how to make this work?

Sincerely z


Solution

  • The answer was quite easy. I don't use ajp, but do a simple http-proxy on the unencrypted site.

    So in the end the code that worked was:

    <IfModule mod_ssl.c>
        ErrorLog /var/log/apache2/ssl_engine.log
        LogLevel error
    
        NameVirtualHost *:443
    
        <VirtualHost *:443>
                ServerName www.doma.in
                ServerAlias doma.in
    
                SSLEngine on
                SSLCertificateFile /etc/ssl/certs/ssl_certificate.crt
                SSLCertificateKeyFile /etc/ssl/certs/ssl_certificate.key
                SSLCertificateChainFile /etc/ssl/certs/intermediate_ca.crt
    
                ProxyPass / http://127.0.0.1:8080/
                ProxyPassReverse / http://127.0.0.1:8080/
        </VirtualHost>
    </IfModule>
    

    Performance-wise the ajp-protocol would be preferable to this, though.