Hi all,
First of all, sorry for the long post, but the reasoning and architecture requires explanation to get the full understanding of the situation.
We are currently migrating our website from Oracle 10g to Apache 2/Tomcat 6.0.29. The site itself is a set of pages where customers select what they want to purchase, then once they're happy, it switches to SSL to gather their customer details and take payments.
The current setup involves two intelligent load-balancers that terminates SSL then hands over to Oracle 10g. The 10g stack has custom Oracle versions of Apache which have configuration options not found in standard Apache and appear to have made configuration simpler. For instance, there is a "simulateHttps" directive that you can give to a virtual host in Oracle Apache which does not exist in the standard version. Using that option, we simply have 2 virtual hosts defined in Apache, one for http traffic and one for https traffic (with simulateHttps set to on). They both forward to OC4J and it works fine.
With the new architecture we have two load-balancer which round-robin to two Apache servers. These servers connect to two
Tomcat servers which are configured with a mod_jk loadbalancer using session affinity. Through config we have separated HTTP & HTTPS traffic. We have done this because the application needs to identify when it is secure, which we do by simulating HTTP using settings in the connector in the Tomcat server.xml. This is detailed further down.
Obviously we want to keep the same functionality on the Apache/Tomcat stack, and also retain the termination of SSL at the load-balancer, but are having trouble when the application switches to HTTPS. It works fine if we have a single Tomcat instance running, but once the 2nd Tomcat instance is enabled, moving to HTTPS fails because a new session is created.
Our configuration is as follows:
Apache
We have 2 Apache servers running - they are served in a round-robin style by the load-balancer. They recieve 2 types of traffic, non-secure and secure, but the secure traffic is NOT encrypted (SSL terminated at the load-balancer).
httpd.conf:
We are using mod_jk to connect to Tomcat
workers.properties
As you can see, Apache can receive on either 5555 or 6666 dependant on the source of the traffic. If it's non-secure, it uses the loadbalancer called "loadbalancer" which uses two Tomcats listening on port 8009 - this is a connector in Tomcat that is not secure. For traffic on 6666, "loadbalancerSSL" is used. This is the same two Tomcats but on port 8010 - this is a connector that believes it is secure. Tomcat config is detailed below.
Tomcat
We have 2 Tomcat servers. They too recieve two types of traffic, non-secure and secure, as passed on from Apache.
server.xml Tomcat 1:
server.xml Tomcat 2:
As can be seen, the only difference between the two Tomcat configs is the jvmRoute parameter on the Engine config.
The connector on 8009 is a vanilla connector configuration. On 8010, SSL related parameters are set so that it believes it is secure.
What's happening
If I have a single Tomcat running, I can progress all the way through the site, go secure, retain the session and get to the end of the process. As soon as the 2nd Tomcat in introduced, when it goes secure, the site returns to the first page. I believe this is because sticky sessions fails and the requests ends up on a separate server, hence creating a new session. The application detects this and sends the user back to the first page in the process (it needs the data in the session at this point and as there is none, redirects to the start).
I think that sticky sessions fails because the process behind it uses the jvmRoute value from the Tomcat server.xml to append to the end of the JSESSIONID cookie. When the app goes secure and Apache receives traffic on 6666, it starts to look for tomcatSSL[1/2] but none of the tomcats use that jvmRoute and hence it will not be part of the JSESSIONID, so it will not stick to the same server. The reason that it works with one server is because it only has a single server to send it to, therefore will always find the session.
If this is the case, we may have approached this incorrectly. Separating non-SSL and SSL traffic all the way down to Tomcat may not be the answer and we may need to use something in Apache to modify request and response, in the same way that I assume "simulateHttps" worked.
Has anyone else setup a site using this sort of architecture? I can't imagine that this is uncommon in the enterprise?
Any help is greatly appreciated!
Many thanks
Rich