33

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?

7 Answers 7

40

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>
2
  • 1
    Avoid ProxyPreserveHost On it is almost always wrong, useless and almost always breaks ProxyPassReverse. As a side note ProxyRequests off is the default, thus redundant.
    – kubanczyk
    Dec 6, 2016 at 16:55
  • When we use external IP instead of localhostit's not working. Jan 23, 2019 at 3:12
4

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.

2
  • I will generate the certificate with let's encrypt on the server where the application for host.domain.org is running. Then I have to reuse the same certificate on the proxy server?
    – Giox
    Nov 6, 2018 at 14:25
  • Note that the point is to have https://localhost:8443 (with an "s" in "https") since OP wants to use SSL between both servers. Nov 1, 2023 at 4:36
2

Well, what I don't understand here is why you need to have an SSL connection from your apache to your application which seems to be on the same machine (http://localhost:8443/).

I guess the usual way to set up things like this is to have apache providing SSL encryption to the "customer"-side, e.g. internet, and have an unencrypted connection to the application. This also gives you more freedom to debug your application responses.

The other thing Dave Cheney mentioned is to use the native tomcat connector in order to have load balancing and other features.

1
  • Well I have two reason for choosing such a setup. The first on is that the Tomcat server is already up and running in SSL and I thought it would be simple to use apache VirtualHost with it. The second one is that the provider of the application (JIRA) provides some guidelines for apache integration (atlassian.com/software/jira/docs/v3.13/apacheintegration.html) and I based my configuration on it by adding VirtualHost support. Guess that was more complex than I thought, besides making it work I really want to understant what is the problem.
    – JMD
    Jun 14, 2009 at 13:51
2

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
1
  • Currently I do not really need to use load balancing, but that could be heplful in the future. Thanks for the insight.
    – JMD
    Jun 15, 2009 at 8:20
0

Do you really need to proxy to a HTTPS service? You might want to proxy to the non-ssl service in localhost, e.g.

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
1
  • Indeed using SSL is mandatory for me. I also tested to proxy without using SSL just to check and it works fine. SSL support is the real issue.
    – JMD
    Jun 14, 2009 at 8:51
0

Check your SSL error log and make sure you have no errors about being unable to verify the CA certificate chain.

1
  • If there are indeed verification errors, what would be the solution? Feb 10, 2017 at 1:24
0

First, I would look at whether you can do a request from localhost to localhost:8443 and see if that's successful (i.e. do a GET or wget http://localhost:8443).

I'm not quite sure why your having a virtual host listening on port 443 then proxying it to another SSL host.

Why can't the application just use 443 natively?
If you can't change it you could just use iptables to redirect the port.

2
  • The reason is that I need install more web applications on the same server, all using SSL and they cannot all listen on port 443. So I am using IP based VirtualHosts to make it look like each web application is hosted on its own server. I tested the following wget command and it works fine: wget localhost:8443 --no-check-certificate
    – JMD
    Jun 14, 2009 at 8:42
  • 2
    Note - it is a simple matter to add additional IP addresses to your server, and thus have several applications listening on port 443 - all on separate IP addresses.
    – Brent
    Jun 14, 2009 at 13:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .