Hi Friends,
I actually thought about making my tomcat application highly available anyway if one of my servers is down. There were certain challenges in front of me when I started.
1. I have to publish my application through SSL.
2. I have to replicate sessions so that the users will not face any "Session unavailability" scenario.
The environment I choose for my test was Ubuntu 10.04 LTS 64 Bit server and Apache Tomcat 6.0.18.
I started googling and found so many posts saying about using "HAProxy". I tried using that and found that it is worthy in case of HTTP publishing. But, for the SSL (HTTPS), it stucks. Then I found some links which were suggesting to use "Stunnel" on top of HAProxy. I tried that also, but it is really tedious to register SSL Self Signed key and certificate using Stunnel.
So, I gave up and started a complete fresh try. I searched for Apache suggestion and solutions for this scenario. At last I found it really awesome using Apache 2 proxy solution and a couple of small tricks at the Tomcat end.
What you Need :
1. Apache 2 : I installed Apache 2 in my Ubuntu server by using apt-get install apache2.
2. Mod JK : Download from latest releases of Apache Software Foundation.
3. OpenSSL : I simply use apt-get install openssl.
4. Tomcat 6.0.18 : Download from Apache Software Foundation.
Your Steps :
As I was trying this HA and loadbalancing scenario in a single server, I had to run two (at least) instances of Tomcat running on the same box. I configured my Tomcat servers with the following port configurations.
Tomcat 1 & 2 Ports
| Tomcat 1 Ports | Tomcat 2 Ports |
| Shutdown | 8005 | 8105 |
| HTTP Connector | 8080 | 8180 |
| AJP Connector | 8009 | 8109 |
Now, I had to write the following configs in the /etc/apache2/httpd.conf file
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so
LoadModule proxy_ftp_module /usr/lib/apache2/modules/mod_proxy_ftp.so
LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
LoadModule proxy_connect_module /usr/lib/apache2/modules/mod_proxy_connect.so
LoadModule proxy_balancer_module /usr/lib/apache2/modules/mod_proxy_balancer.so
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so
LoadModule proxy_ajp_module /usr/lib/apache2/modules/mod_proxy_ajp.so
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</VirtualHost>
ProxyPass / balancer://wwwCluster/ stickysession=JSESSIONID
<Proxy balancer://wwwCluster/>
BalancerMember ajp://localhost:8009/ route=jvm1
BalancerMember ajp://localhost:8109/ route=jvm2
</Proxy>
NameVirtualHost *:443
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/apache2/ssl.cert/ssl.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/ssl.key
</VirtualHost>
Now, we need to incorporate some changes at our Tomcat server end and our application end.
At the Tomcat end add/comment out the following line in italics ..
<!-- You should set jvmRoute to support load-balancing via AJP ie : <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> --> <Engine name="Catalina" defaultHost="localhost"> <!--For clustering, please take a look at documentation at: /docs/cluster-howto.html (simple how to) /docs/config/cluster.html (reference documentation) --> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
Don't forget to make this change in both the Tomcat servers.
Now before the final step of generating the SSL key and certificates, I had to do this couple of changes at my application end.
- Add <distributable/> tag just before the filter or servlet tag starts in the Web.XML of the application.
- Make all the necessary classes serializable.
After creating the key and crt files using the following steps, just put them in the location, you specified in the httpd.conf file. Now, start Tomcat servers one by one.Then, start apache2 by /etc/init.d/apache2 start and see the magic. You can monitor the two servers by tailing the catalina.out log. [tail -f ...../catalina.out]
Generating a Certificate Signing Request (CSR)
Whether you are getting a certificate from a CA or generating your own self-signed certificate, the first step is to generate a key.
To generate the
keys for the Certificate Signing Request (CSR) run the following command from a terminal prompt:
openssl genrsa -des3 -out server.key 1024
Generating RSA private key, 1024 bit long modulus
.....................++++++
.................++++++
unable to write 'random state'
e is 65537 (0x10001)
Enter pass phrase for server.key:
You can now enter your passphrase. For best security, it should at least contain eight characters. The minimum length when specifying -des3 is four characters. It should include numbers and/or punctuation and not be a word in a dictionary. Also remember that your passphrase is case-sensitive.
Re-type the passphrase to verify. Once you have re-typed it correctly, the server key is generated and stored in the
server.key file.
|
|
| You can also run your secure service without a passphrase. This is convenient because you will not need to enter the passphrase every time you start your secure service. But it is highly insecure and a compromise of the key means a compromise of the server as well. |
In any case, you can choose to run your secure service without a passphrase by leaving out the -des3 switch in the generation phase or by issuing the following command at a terminal prompt:
openssl rsa -in server.key -out server.key.insecure
Once you run the above command, the insecure key will be stored in the
server.key.insecure file. You can use this file to generate the CSR without passphrase.
To create the CSR, run the following command at a terminal prompt:
openssl req -new -key server.key -out server.csr
It will prompt you enter the passphrase. If you enter the correct passphrase, it will prompt you to enter Company Name, Once you enter all these details, your CSR will be created and it will be stored in the
server.csr file. Site Name, Email Id, etc.
You can now submit this CSR file to a CA for processing. The CA will use this CSR file and issue the certificate. On the other hand, you can create self-signed certificate using this CSR.
Creating a Self-Signed Certificate
To create the self-signed certificate, run the following command at a terminal prompt:
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
The above command will prompt you to enter the passphrase. Once you enter the correct passphrase, your certificate will be created and it will be stored in the
server.crt file.
|
|
If your secure server is to be used in a production environment, you probably need a CA-signed certificate. It is not recommended to use self-signed certificate.
|