Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Configuring Apache for forced SSL with Virtual Hosts on a multi-homed box

Posted on 2010-08-12
9
Medium Priority
?
1,460 Views
Last Modified: 2013-12-02
Okay, I am incredibly frustrated.  While I can get individual aspects of this working beautifully, I can't seem to put it all together.   I have a box -- dmz.app.com -- that will host an instance of Apache that is intended to sit in front of three distinct sites -- call them a.app.com, b.app.com and c.app.com.  dmz.app.com is multi-homed, with three public IP addresses (outside.100, outside.101 and outside.102), each of which maps to a unique internal IP address (inside.10, inside.11, inside.12).  The distinct sites are configured through DNS so that a.app.com = outside.100, b.app.com = outside.101 and c.app.com = outside.102.  For each site, there is a dedicated Tomcat server -- call them a-tomcat, b-tomcat and c-tomcat.  The idea is simple; for any request on any of the three *.app.com domains, force the request to use SSL (HTTPS over port 443) and route it to the appropriate *-tomcat server.

Forcing SSL seemed to work with the following rules:

RewriteCond %{SERVER_PORT} !^443$
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Open in new window


Mapping the requests to the appropriate Tomcat seems to sort of work with the following approach:

# This was needed because Apache couldn't resolve the host uniquely due to the triple-homing
ServerName dmz.app.com

NameVirtualHost inside.11
NameVirtualHost inside.12
NameVirtualHost inside.13

<VirtualHost inside.11>
RewriteEngine On
RewriteOptions Inherit

DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs/a"
ServerName a.app.com
ErrorLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/error.log"
TransferLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/access.log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.crt"
SSLCertificateKeyFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.key"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/ssl_request.log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Location "/*/WEB-INF/*">
     deny from all
</Location>

JkMount /* a-worker

JkMount /myapp/ a-worker
JkMount /myapp/* a-worker
JkMount /myapp* a-worker
</VirtualHost>                                  

<VirtualHost inside.12>
RewriteEngine On
RewriteOptions Inherit

DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs/b"
ServerName b.app.com
ErrorLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/error.log"
TransferLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/access.log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.crt"
SSLCertificateKeyFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.key"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/ssl_request.log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Location "/*/WEB-INF/*">
     deny from all
</Location>

JkMount /* b-worker

JkMount /myapp/ b-worker
JkMount /myapp/* b-worker
JkMount /myapp* b-worker
</VirtualHost>                                  

<VirtualHost inside.13>
RewriteEngine On
RewriteOptions Inherit

DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs/c"
ServerName c.app.com
ErrorLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/error.log"
TransferLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/access.log"
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.crt"
SSLCertificateKeyFile "C:/Program Files/Apache Software Foundation/Apache2.2/conf/my.key"
<FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
</FilesMatch>
<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>
BrowserMatch ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0
CustomLog "C:/Program Files/Apache Software Foundation/Apache2.2/logs/ssl_request.log" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
<Location "/*/WEB-INF/*">
     deny from all
</Location>

JkMount /* c-worker

JkMount /myapp/ c-worker
JkMount /myapp/* c-worker
JkMount /myapp* c-worker
</VirtualHost>                                  

Open in new window


The worker.properties file looks like:

workers.java_home="/Program Files/Java/jdk1.6.0_21"

# The advanced router LB worker
worker.list=a-worker, b-worker, c-worker

# Define workers using ajp13
worker.a-worker.port=8009
worker.a-worker.host=a-tomcat
worker.a-worker.type=ajp13

worker.b-worker.port=8009
worker.b-worker.host=b-tomcat
worker.b-worker.type=ajp13

worker.c-worker.port=8009
worker.c-worker.host=c-tomcat
worker.c-worker.type=ajp13

Open in new window


Putting all of these pieces together yields really inconsistent, funky results.  When I point my browser to https://b.app.com/myapp/ or https://b.app.com/myapp, life is wonderful and happy.  When I point my browser to http://b.app.com/myapp/ or http://b.app.com/myapp, I get a 400 Bad Request (Your browser sent a request that this server could not understand.  Reason: You're speaking plain HTTP to an SSL-enabled server port.  Instead use the HTTPS scheme to access this URL, please.).  But if I point my browser to http://b.app.com or http://b.app.com/ or https://b.app.com or https://b.app.com/, I wind up at https://a.app.com/myapp/!

This cannot possibly be as hard as I seem to have made it.  Can somebody please point me in the direction toward sanity?  Thank you!
0
Comment
Question by:arktech
  • 5
  • 2
  • 2
9 Comments
 

Author Comment

by:arktech
ID: 33433795
To clarify what I mean by "point me in the direction toward sanity", answers to the following will be awarded points:

* The outside.10x -> inside.1x -> y.app.com structure was somewhat unintentional.  Originally, I thought unique external IP addresses were required to support SSL; our hosting provider thought we needed unique internal IP addresses.  Are we overcomplicating this?  Is there a better way?  Would we sacrifice any scalability/flexibility by using a different approach?

* What mod_rewrite techniques have you successfully used to force SSL with multiple virtual hosts?

Thanks!
0
 
LVL 51

Expert Comment

by:Steve Bink
ID: 33435505
0
 

Author Comment

by:arktech
ID: 33435983
I did play with SSLRequireSSL, but it's not really the behavior I was after.  In our current configuration (in which Apache is only sitting in front of one of the three environments), attempts to connect via http: are automatically redirected to the https: URL.  We managed that by including a simple redirect index.html in .htdocs.  Unfortunately, that's where the multi-domain/multi-homed complications are causing problems.  I set up a separate subdirectory for each domain (.htdocs/a, .htdocs/b, .htdocs/c) with an index.html in each that redirects to the https: URL for http: connections.  Unfortunately, attempts to connect to b.app.com get redirected to https://a.app.com, no doubt due to some misconfiguration, but I can't seem to figure it out.
0
Ready for your healthcare security check-up?

In the past few years, healthcare organizations have become a prime target for advanced attacks. Does your organization have what it needs to defend itself? Schedule your healthcare security check-up today and download our free Healthcare Security Resource Kit today!

 
LVL 26

Accepted Solution

by:
arober11 earned 2000 total points
ID: 33436912
Hi, for a start change the "SERVER_NAME", what you get from a "uname -n"  to "HTTP_HOST", the site name passed in the URL, in you Rewrite, and make the re-direct permanent e.g.

RewriteCond %{SERVER_PORT} !^443$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

I take it the rules are in the body of the httpd.conf, as they don't appear your Virtualhost definitions.

Once tweaked let us know what's not working.
0
 
LVL 51

Expert Comment

by:Steve Bink
ID: 33439240
The normal rule I use:

RewriteCond %{HTTPS} off
# or
# RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
0
 

Author Comment

by:arktech
ID: 33440719
arober11, you are a shining example of why I love Experts Exchange!  Everything is working perfectly now for all four flavors of https: URLs (https://b.app.com, https://b.app.com/, https://b.app.com/myapp and https://b.app.com/myapp/).  Using the http: form of all four yields the same result as before:

---------------------------------------------------
Bad Request

Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.

    Hint: https://b.app.com/
---------------------------------------------------

Now, given that this response includes a hyperlink to a valid URL, I can live with this.  That said, if you know of an easy fix for it, I'm all ears!
0
 

Author Comment

by:arktech
ID: 33441107
Found it; fixed it!  I changed my NameVirtualHost and VirtualHost directives to explicitly specify a.app.com:443 etc. instead of just a.app.com.  Now all eight permutations are working as intended!  Thank you again for the help!  It's amazing how such a little oversight -- HTTP_HOST vs. SERVER_NAME -- can cause so much hair-pulling.
0
 

Author Closing Comment

by:arktech
ID: 33441113
Fantastic!  Exactly the tip I needed.  Once I had this in place, the rest came together quickly.  Thank you, arober11, for spotting the subtle little mistake that was causing me so much frustration!
0
 
LVL 26

Expert Comment

by:arober11
ID: 33447610
Thanks
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This exercise is about for the following scenario: Dmgr and One node with 2 application server. Each application server contains it owns application. Application server name as follows server1 contains app1 server2 contains app1 Prereq…
Over the last year I have answered a couple of basic URL rewriting questions several times so I thought I might as well have a stab at: explaining the basics, providing a few useful links and consolidating some of the most common queries into a sing…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …

916 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question