Sunday, April 24, 2011

SSL offloading and WebLogic server

A couple of weeks ago I wrote about using Apache to simulate an SSL load balancer and showed this diagram:

One of the important things to note is that by default in this architecture WebLogic and any J2EE applications won't know that the user is using SSL to access the server because any calls to HttpServletRequest.isSecure() will return false!

There is a solution though - two configuration directives in the Weblogic web server plug-ins (mod_wl in Apache and OHS) allow you to tweak the behavior. Those directives are WLProxySSL and WLProxySSLPassThrough.

Before you change your web server plug-ins you need to tell WebLogic that it is running behind a proxy server by changing a setting in your WebLogic domain's configuration. To do that open the WebLogic console (http://adminserverhost:port/console/), click on the domain name on the left hand nav and then click on the Web Applications tab:

then scroll down toward the bottom and check the WebLogic Plugin Enabled:
then scroll down to the bottom of the page and hit "Save". You shouldn't have to restart anything once you make this change.

Checking that box tweaks WebLogic's behavior so that it looks for certain HTTP headers from the web server plug-in, among them WL-Proxy-SSL. If that checkbox is checked and the incoming HTTP request contains WL-Proxy-SSL then WebLogic will pretend that the request came in over SSL and request.isSecure() will return true. The checkbox has some other important impacts on WLS' behavior so take a quick look through the documentation to see what else it does.

When you install and enable the WebLogic plug-ins for your web server the configuration defaults to doing things "safely", meaning that any existing WL-Proxy-SSL header will be removed and no WL-Proxy-SSL header will ever be sent to the WebLogic Server. This protects you from a malicious user sending in a request and tricking WebLogic into thinking it's secure when it wasn't.

If you want to have the web server plugin populate WL-Proxy-SSL if the original request came into your web server over SSL then you need to add a setting called WLProxySSL and set it to ON. More information about this setting is available in the plug-in documentation.

This works great when your web server is doing the SSL work. But if you scroll back to my diagram you'll see that in my environment I have SSL being terminated by a load balancer. And since mod_wl will remove any incoming WL-Proxy-SSL and the request will reach OHS over HTTP this means that the WebLogic server won't ever get that header and so request.isSecure() will always return false.

Naturally we've got you covered in that case too!

There's an additional configuration directive for the web server plug-ins which, though not discussed in the documentation I linked to above, does what we want and IS supported. That directive is WLProxySSLPassThrough and defaults to OFF. If you add that directive and set it to ON then the WebLogic plug-in will not remove any incoming WL-Proxy-SSL header.

So my OHS configuration looks like this:

<IfModule weblogic_module>
    WebLogicHost localhost
    WebLogicPort 7070

    WLProxySSLPassThrough ON
</IfModule>

<Location /SimpleTestApp>
    AuthType Oblix
    require valid-user
    SetHandler weblogic-handler
</Location>

In my environment I'm using Apache to simulate a VIP. My Apache config looks like this:

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

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

  RequestHeader set IS_SSL ssl
  RequestHeader set WL-Proxy-SSL true

  ProxyPass / http://localhost:7777/
  ProxyPassReverse / http://localhost:7777/
</VirtualHost>
The IS_SSL HTTP header tells the OAM WebGate that the original request was over SSL and WL-Proxy-SSL does the same for WebLogic Server.

One really, really important note:
If you also have HTTP coming into your load balancer you will want to make sure that you remove any incoming WL-Proxy-SSL header. In my Apache config that looks like this:

<VirtualHost *:80>
  ServerName app.oracledemo.com

  RequestHeader unset IS_SSL
  RequestHeader unset WL-Proxy-SSL

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

Update Feb 23, 2012 if you need to do client certificate authentication check out this other post

4 comments:

  1. Hi Chris,
    Thanks for the informational blog. I have followed the configuration to setup the rev proxy in our env. I have run into a issue in our integration after adding a webgate into the picture, the whole setup works fine without a webgate.

    User -https-> LB -http-> Apache(webgate) -http-> weblogic(oim)
    this is the setup we are trying to acheive with SSL offloading.

    The problem currently I face in acheiving this is after the login page, the protocol changes to http and getting a timed out or 404.

    https://oim.example.com/oim/faces/pages/Self.jspx (Protected app)

    -->

    https://oam.example.com:4443/oam/server/obrareq.cgi%3Fwh%253Dzdoim4_wg%2520wu%253D%252Foim%252Ffaces%252Fpages%252FSelf.jspx%2520wo%253D1%2520rh%253Dhttp%253A%252F%252Foim.example.com%2520ru%253D%25252Foim%25252Ffaces%25252Fpages%25252FSelf.jspx

    -->

    https://oam.example.com/ssologin/login.jsp (Login Page)

    -->

    https://oam.example.com:4443/oam/server/auth_cred_submit

    -->

    http://oim.example.com/obrar.cgi?cookie=ERE+2Fh9SyO4roKMHA20To%252B8x5KjnQ%252FeihUX9dvWSXUSZ2HXt77YDqsvN6Gs2NYgpAtgPHvUkxPxMgIbd4El0JS1LBOD330yHm0jgkS6KKEffGlc58ujSgzM0MYzOZSlLuGBRNEZQM0hpT65dRhJJ7sllZZr6aPzOYGHjqDm%252B8icbtkntE5yQ4jKNDkMPDRim8MGGCY4%252FsN3%wrmUmnJGo4cS2kmGs7GoS05CyK1bWdbn%252F5lnflHsEgsd%252BKNA%253D%2520redirectto%3D%25252Foim%25252Ffaces%25252Fpages%25252FSelf.jspx%2520ssoCookie%3Dhttponly
    (timed out)

    I believe you could throw some light with a reverse proxy working with a webgate on apache. A little help with be greatly appreciated.

    Thanks,
    Vikram

    ReplyDelete
  2. The WebGate looks for a different header. The name is configurable, but by default it's IS_SSL with the value "ssl". You'll want the proxy to add that header to the inbound traffic. If you do that the WebGate will know that it's HTTPS instead of HTTP and the redirects back and forth to the OAM server should work properly.

    ReplyDelete
  3. Hi Chris, This article and a few other articles of yours are very useful. Overall, the solutions are imbued with simplicity, that is quite rare these days.

    Just to discuss on this article, in a real time scenario an OHS web server (with 11g webgate) resides separately on a separate WL server, while the application resides (secured by an OAM Identity Asserter)in a separate cluster environment.

    Assuming the application WLS is open only on HTTPS, can the OHS, which is on HTTP, reverse proxy to the WL server?

    ReplyDelete
  4. You could go HTTP into OHS and then HTTPS from OHS to WebLogic (though why would you want to?).

    Just configure mod_wl to use SSL - it's really that easy.

    But this post was talking about using Apache to simulate an SSL offloading reverse proxy. In other words something like an SSL accelerator. I do this on my VMs on my laptop because nobody wants to buy me an actual load balancer.

    This definitely is NOT something you'd use in a real world environment!

    ReplyDelete

Note: Only a member of this blog may post a comment.