Apache VirtualHost with mod-proxy and SSL
I am trying to set up a server with multiple web applications which will all be served through apache VirtualHost (apache running on the same server). My main constraint is that each web application must use SSL encryption. After googling for a while and looking at other questions on stackoverflow, I wrote the following configuration for the VirtualHost:
<VirtualHost 1.2.3.4:443>
ServerName host.example.org
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / https://localhost:8443/
ProxyPassReverse / https://localhost:8443/
</VirtualHost>
Even though https://host.example.org:8443 is accessible, https://host.example.org is not, which defeats the purpose of my virtual host configuration. Firefox complains that, even though it successfully connected to the server, the connection was interrupted. I also get the following warning in apache's error.log:
proxy: no HTTP 0.9 request (with no host line) on incoming request and preserve host set forcing hostname to be host.example.org for uri
On the web application (a Tomcat server) the access log shows a strange access request:
"?O^A^C / HTTP/1.1" 302
Following is the correct access resquest I get when I connect directly to https://host.example.org:8443:
"GET / HTTP/1.1" 302
Finally I should also mention that the virtual host works perfectly fine when I do not use SSL.
How can I make this work?
Solution 1:
At last I found a way to make it work. First I tried Dave Cheney suggestion, so I installed an other certificate for the apache server redirected to Tomcat non SSL port (so the proxy was redirecting to http://localhost:8080/). Unfortunately it did not fully work as in the web browser the https was transformed to http immediately upon connection. So I reverted to using https://localhost:8443/ and the final touch to make it work was to add again SSLProxyEngine.
Here is the resulting VirtualHost configuration:
<VirtualHost 1.2.3.4:443>
ServerName host.domain.org
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLEngine on
SSLProxyEngine On
SSLCertificateFile /etc/apache2/ssl/certificate.crt
SSLCertificateKeyFile /etc/apache2/ssl/certificate.key
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / https://localhost:8443/
ProxyPassReverse / https://localhost:8443/
</VirtualHost>
Solution 2:
Try this config
<VirtualHost 1.2.3.4:443>
ServerName host.domain.org
SSLEngine On
# include other ssl options, like cert and key here
ProxyRequests Off
ProxyPreserveHost On
<Location />
ProxyPass http://localhost:8443/
</Location>
</VirtualHost>
If your application needs to have access to the SSL information from the proxied connection, you should consider using mod_proxy_ajp, and the tomcat ajp1.3 connector.
Solution 3:
But if you goal is to run multiple ssl enabled web applications on the same server. adding apache in front isnt going to balance them using your above config, you would still need a load balancer or you could use apache's proxy balancer module with something like the following:
ProxyRequests Off
<Proxy balancer://someapplication>
BalancerMember http://127.0.0.1:18443 keepalive=on max=2 retry=30
BalancerMember http://127.0.0.1:18444 keepalive=on max=2 retry=30
BalancerMember http://127.0.0.1:18445 keepalive=on max=2 retry=30
</Proxy>
<VirtualHost 1.2.3.4:443>
SSLEngine on
SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile //path/to/key.pem
SSLVerifyClient optional
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
<Location />
SetHandler balancer-manager
Order allow,deny
Allow from all
</Location>
ProxyPass / balancer://someapplication:443/
ProxyPassReverse / balancer://someapplication:443/
ProxyPreserveHost on