Using Apache to simulate an SSL Load balancer

Last week I needed to duplicate a customer’s OAM 11g environment to help understand and resolve a problem they were having and needed to simulate a config that looks like this:

Screen+shot+2011-04-05+at+2.27.24+PM

The numbers indicate the TCP port used on the server side. All of the red lines are HTTP. The green line (from OHS to the OAM Server) is the OAM NAP protocol.

Unfortunately I don’t have a load balancer (an F5 in this particular case) handy so I needed to be a bit creative. Apache, mod_proxy and a little elbow grease can do much the same thing for simple testing purposes. In case you ever need to do the same thing here’s a quick setup you can copy/paste to get you going.

    SSLProxyEngine on  
    <Proxy *>  
       Order deny,allow  
       Allow from all  
    </Proxy>  

    RewriteEngine on  
    ProxyPreserveHost on  

    NameVirtualHost *:443  

    <VirtualHost *:443>  
      ServerName login.oracledemo.com  

      SSLEngine on  
      SSLProtocol all -SSLv2  
      SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW  
      SSLCertificateFile /home/oracle/simpleCA/login.oracledemo.com.crt  
      SSLCertificateKeyFile /home/oracle/simpleCA/login.oracledemo.com.key  

      ProxyPass / http://localhost:14100/  
      ProxyPassReverse / http://localhost:14100/  
    </VirtualHost>  

    <VirtualHost *:443>  
      ServerName idm11g.oracledemo.com  

      SSLEngine on  
      SSLProtocol all -SSLv2  
      SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW  
      SSLCertificateFile /home/oracle/simpleCA/idm11g.oracledemo.com.crt  
      SSLCertificateKeyFile /home/oracle/simpleCA/idm11g.oracledemo.com.key  

      RequestHeader set IS_SSL ssl  

      ProxyPass / http://localhost:7777/  
      ProxyPassReverse / http://localhost:7777/  
    </VirtualHost>

There are a couple of interesting bits in that configuration…

First is that when you use mod_proxy Apache will use the host name in the URL specified in ProxyPass when it talks to the back end server. In this case that means that the OHS server would see a request with a host header that said “localhost:7777”. Which can confuse the application and isn’t at all what a conventional load balancer would do. Adding “ProxyPreserveHost on” to the configuration makes mod_proxy use the same name when it talks to the backend server (again OHS in my case) as the browser sent in the original request.

The other interesting thing there is that fact that I’m using NameVirtualHosts over SSL. Yeah, wait, wuh?! I can hear you now – I didn’t think you could do that!

I thought the same thing until a few months ago when I stumbled across something called Server Name Indication. When SSL was first created IP addresses were freely available and nobody had invented name-based virtual hosting. As a result the initial SSL design didn’t have the client send the requested host name as part of the initial handshake, and as a result the server had no way to know which certificate to send to the client.

Fast forward a few years and the situation has changed quite a bit. We’re basically out of IPv4 addresses and name-based virtual hosting is practically the norm. The smart folks in charge of protocols and standards decided it was high time to fix that little oversight. RFC 3546 from June of 2003 documents the details.

Anyway, the only reason I go into all of that is to offer a warning: SSL protected Name-based virtual hosts **DO NOT** work with Internet Explorer on Windows XP. I know XP is on the downswing, but it still has something like 50% of the browser market share according to the first few hits I found a quick Google search.

Hope this helps someone else!

Add Your Comment