Cookbook Secure Failover for Tomcat Application Server Use Apache, mod_proxy, mod_security, mod_ssl to offer secure application delivery [vijay.sarvepalli@ericavijay.net] Vijay Sarvepalli
Introduction There is number of applications today written to be delivered over the web. These applications are written in.net, JAVA and PHP in the backend. The challenge has been securing these applications from popular attacks such as Cross Site Scripting, SQL Injection and Session Hijacking. These attacks are mitigated first level by providing a secure architecture for delivering such services. Here I have chosen Tomcat and Apache most popular application and web server platforms to illustrate how security and high availability can be combined for an application. This design document covers how to build a web application tier that is both secure and scalable. The example here shows building 1. An SSL offloader using Apache 2. A secure reverse proxy using mod_security 3. A load balancer using mod_proxy_balancer and ajp based balance manager. High Availability design for Web servers (Network level failover between webservers is not covered here) Technology: Apache + Mod_Security + Balancer with Active/Active setup using rules in the LoadBalancer. milky1 milky2 Apache configured with reverse proxy MOD Security Apache module Balancer modules (primary to andromeda2) Apache configured with reverse proxy MOD Security Apache module Balancer modules (Primary andromeda2) andromeda1 andromeda2 1. Configure modsecurity and virtualhost on milky1 server. (Package add apache2, gcc and libgcc and then from source modsecurity www.modsecurity.org ) # httpd.conf LoadModule security2_module modules/mod_security2.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so # Include modsecurity configuration Include conf/modsec_rules/*.conf #All of modules #Virtualhost configuration on milky1 <VirtualHost *:443> # Turn on SSL engine SSLEngine on # Primary servername for https://securefailover.example.com/myapp ServerName securefailover.example.com # These are just references so you can troubleshoot with other hostnames ServerAlias milky1.example.com Serveralias milky2.example.com # Enforce SSL with minimum SSLv3 or TLSv1 SSLProtocol -All +SSLv3 +TLSv1 # Do not accept ciphers that are not encrypted SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM # Server certificate related files SSLCertificateFile certs/server_public.crt # Protect access to this file. SSLCertificateKeyFile certs/server_private.key SSLCACertificateFile certs/trustedroot_full.crt #ProxyPass decides all the request for /myapp will be forwarded to a virtual worker #with name mycluster. #Sticky sessions are enabled and implemented using cookie JSESSIONID. ProxyPass /myapp balancer://mycluster stickysession=jsessionid <Proxy balancer://mycluster> # Make both server as participants of this load balancingusing Apache Jserv # Protocl AJP, a name and a loadfactor is given to each member of the # Balancer BalancerMember ajp://andromeda1:8009/myapp route=andromeda1 BalancerMember ajp://andromeda2:8009/myapp route= andromeda2 </Proxy> # This /balance-manager is a self healing part of Apache which allows you to # check and retire the system that are removed or not active. <Location /balancer-manager> SetHandler balancer-manager </Location> ### End Balancer </VirtualHost> 2. Configure modsecurity and virtualhost on milky2 server. (Package add apache2, gcc and libgcc and then from source modsecurity www.modsecurity.org )
# httpd.conf LoadModule security2_module modules/mod_security2.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so LoadModule proxy_connect_module modules/mod_proxy_connect.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so # Include modsecurity configuration Include conf/modsec_rules/*.conf #All of modules #Virtualhost configuration on milky1 <VirtualHost *:443> # Turn on SSL engine SSLEngine on # Primary servername for https://securefailover.example.com/myapp ServerName securefailover.example.com # These are just references so you can troubleshoot with other hostnames ServerAlias milky2.example.com Serveralias milky1.example.com # Enforce SSL with minimum SSLv3 or TLSv1 SSLProtocol -All +SSLv3 +TLSv1 # Do not accept ciphers that are not encrypted SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM # Server certificate related files SSLCertificateFile certs/server_public.crt # Protect access to this file. SSLCertificateKeyFile certs/server_private.key SSLCACertificateFile certs/trustedroot_full.crt #ProxyPass decides all the request for /myapp will be forwarded to a virtual worker #with name mycluster. #Sticky sessions are enabled and implemented using cookie JSESSIONID. ProxyPass /myapp balancer://mycluster stickysession=jsessionid <Proxy balancer://mycluster> # Make both server as participants of this load balancingusing Apache Jserv # Protocl AJP, a name and a loadfactor is given to each member of the # Balancer. Note: the order is reversed from milky1 BalancerMember ajp://andromeda2:8009/myapp route=andromeda1 BalancerMember ajp://andromeda3:8009/myapp route= andromeda2 </Proxy> # This /balance-manager is a self healing part of Apache which allows you to # check and retire the system that are removed or not active. <Location /balancer-manager> SetHandler balancer-manager </Location> ### End Balancer </VirtualHost>
4. Configure jvmroute on andromeda1 server, tomcat configuration. Define the tomcat engine name in the Tomcat server.xml. The loadfactor can be a number between 1 and 100. The tomcat server.xml in conf/ folder should have this configuration: <Engine name="catalina" defaulthost="localhost" jvmroute=" andromeda1"> 5. Configure jvmroute on andromeda2 server. Define the tomcat engine name in the Tomcat server.xml. The loadfactor can be a number between 1 and 100. The tomcat server.xml in conf/ folder should have this configuration: <Engine name="catalina" defaulthost="localhost" jvmroute=" andromeda2"> 6. Configure Logging for access log in tomcat to catch remote IP address that access your applications. The configuration in `server.xml, enables logging and extends logging of the additional X-Forwarded-For header submitted by Apache <Valve classname="org.apache.catalina.valves.accesslogvalve" directory= logs" prefix="localhost_access_log." suffix=".txt" pattern="%{x- Forwarded-For}i %l %u %t %r %s %b %{Referer}i %{User-agent}i " resolvehosts="false"/> Now allow your browser to go to http://milky1.example.com/myapp, you should see the application. Now go to Apache logs and tomcat logs to make sure the application logs that help you track the access to web application Apache Logs 127.0.0.1 - - [14/Jul/2009:12:36:07-0400] "GET /myapp HTTP/1.1" 200 2324 Tomcat Logs 10.203.11.94 - - [14/Jul/2009:12:36:07-0400] GET /myapp HTTP/1.1 200 2324 http://localhost/demo/ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-us; rv:1. 9.0.5) Gecko/2008120122 Firefox/3.0.5 In this example, apache logs are saving only Common format; whereas tomcat logs extensively log details. Other advanced topics such as cookie logging, enhanced monitoring of this solution using balance-manager, integration of this availability and security monitoring to NOC and SOC are not covered in this article. Enjoy tomcat and apache development platform with security and scalability.