Tomcat Production Installation Advanced

A production installation limits the exposure to security risks and makes Tomcat run more efficiently. At this time there are no known security risks in the Tomcat architecture but that doesn't mean that there will not be any in the future, so it's better to tighten the installation now so if a security break-in does occur then the damage will be minimum. Why do you think Tomcat has security risks? The following installation conventions limit security risks by restricting the tomcat permissions, the machine ports open to the internet, and the IPs accessing the TDS. UCAR break in example.

The production installation requires root privileges for many of the operations so the use of sudo command is needed or the root passwd. Because many of the configurations are complex, it is advised to have your system administrator do them for you. Also, if a configuration mistake is made then the responsibility is on the system administrator's shoulders, not yours.

Create unprivileged user tomcat & Tomcat Install Location

By default, Tomcat runs on port 8080 and therefore does not require root to run. It's important not to run as root. Create a special user, e.g. named "tomcat", which owns everything under ${tomcat_home}, and change to that user to run Tomcat. This special user will need read/write access to ${tomcat_home} and its subdirectories, and read access to your data directories. Don't give the tomcat user any rights in any other directories. If your operating system allows it (e.g. Unix, Linux), you might also not allow the tomcat user to log in directly. You would log in as yourself, and then switch to being the tomcat user using the sudo command. One should create a tomcat group when using the adduser command to make the user tomcat.

% adduser tomcat -u 91 -d /opt/tomcat -g tomcat
 

The default home for tomcat is /opt/tomcat but in reality, it's a link to the current tomcat distribution. This is done so one can switch which tomcat is running by making the tomcat link point to a different distribution. More on that later.

 
% cd /opt
- Get the latest tomcat installation from web
ie.   apache-tomcat-6.0.13.tar.gz
% mkdir   apache-tomcat-6.0.13
% chown tomcat:tomcat apache-tomcat-6.0.13
% ln -s apache-tomcat-6.0.13 tomcat   Why make the tomcat link?
 
% su tomcat
% tar zxvf apache-tomcat-6.0.13.tar.gz
 

The tomcat installation is now encapsulated under one directory tree, so if a break-in does occurs the hacker cannot modify files outside the tomcat directory structure. If the installation was done under your personal login, the hacker would gain all the permissions that you have and he could possibility do much more damage.

Tomcat upgrade

Tomcat makes new releases every couple of months to fix bugs and security leaks, also new version features are released periodically that are beneficial to install. As a backup measure, always create a new tomcat installation so if the new installation doesn't go well, one can move the tomcat link back to the old installation. Basically follow the steps above but skip the creation of the tomcat link until one is ready to start the new installation. After the new installation is unpacked as user tomcat, one has to copy the entire TDS configuration from the old installation to the new installation.

What are the TDS configurations: thredds.war, the content directory, exec directory, and conf directory. It's possible that some of the configurations in the conf directory might have to be redone. What ones?

At this time, it's time to stop the current tomcat, remove the tomcat link and then make another tomcat link pointing to the new distribution, then start the new tomcat installation. This process seems like a lot of work but when you need some backup information, it's a life saver.

Use a Firewall

Unless you are on a private network, you need a firewall. A firewall restricts who is allowed to access network ports. Since most production systems are on Linux boxes, this will be the firewall configuration that we will cover. At first the firewalls were implemented as ipchains, but now iptables. An useful feature of iptables is that it can remember some previous traffic and use that information in determining the acceptability of future packets; e.g. when you contact a web site and the web server sends information back to you, iptables can determine the information sent back to you was in response to your initial web request, and accept it as part of your web request. This allows for fairly tight firewall rules to be constructed that still do not interfere with what you want to do.

         Port 8080 should have unrestricted access.

         If you are allowing remote management, you must also open up port 8443. (recommended)

         Tomcat also uses port 8005 to enable shutdown. However, shutdown can only be run from the same machine as Tomcat is running. As long as untrusted users aren't running on your server machine, you shouldn't have to worry about this port being open. However, you might want to restrict public access to it so hackers aren't tempted.

         If you are also using Tomcat in conjunction with another web server like Apache to handle servlet/JSP requests, you need to allow that server access to port 8009, but typically that can be restricted to accesses on the same machine or at least on your subnet. If you are running Tomcat only standalone (e.g. only running the THREDDS data server) then disable port 8009 in ${tomcat_home}/conf/server.xml file.

Firewall file: /etc/sysconfig/iptables
 
 
*filter
:INPUT ACCEPT [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:EXTERNAL - [0:0]
:UNIDATA - [0:0]
#
# Route INPUT to appropriate bins
#
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type any -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -s 128.117.47.200/32 -j UNIDATA
-A INPUT -s 128.117.140.0/24 -j UNIDATA
-A INPUT -s 128.117.156.0/24 -j UNIDATA
-A INPUT -j EXTERNAL
#
# Handle external connections
#
-A EXTERNAL -j REJECT
# Handle internal connections
#
-A UNIDATA -m state --state NEW -p tcp --dport 22 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 112 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 388 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 500 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 503 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 5900 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 8080 -j ACCEPT
-A UNIDATA -m state --state NEW -p tcp --dport 8443 -j ACCEPT
-A UNIDATA -j REJECT
#
# Mark outgoing packets for keeping state
#
-A OUTPUT -d 127.0.0.1 -j ACCEPT
-A OUTPUT -m state --state NEW -p tcp -j ACCEPT
-A OUTPUT -m state --state NEW -p udp -j ACCEPT
COMMIT

Resources:

Linux Firewall Tips

HOWTO Firewall

 

Steps done as user tomcat

 

- Configure Tomcat file conf/server.xml for IP filtering

Sometimes known users abuse your TDS service by hammering your TDS with constant requests or hackers hammering your server. Tomcat provides a valve to allow one to filter the request and to deny service to those IPs. A valve is a component to be inserted into the request processing pipeline for a Catalina container in the tomcat conf/server.xml configuration file.

<Engine name="Catalina" defaultHost="localhost">

    <Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="18.83.0.150,69.25.71.12" />
    ...
    ...

valve Documentation

engine Documentation

Are there any other ways to do IP filtering?

How about this.

-A INPUT -s 18.83.0.150 -j DROP

- Disable Web Indexers

The TDS installation comes with a robots.txt file to disable robots from indexing your data repository, this is especially important if you are storing real time data for a short period of time. If the robots index your site having the possibility over load your cpu/disk and making information that is most likely out of date.

% cp /opt/tomcat/webapps/thredds/WEB-INF/initialContent/root/robots.txt /opt/tomcat/webapps/ROOT

- Installing a Certificate from a Certificate Authority

The use of SSL in this way prevents a network sniffer from getting your password. A more sophisticated (and more difficult to perform) attack is the so called man-in-the-middle attack where someone pretends to be your server, and induces your client to send the password to it.

Earlier we used self-signed certificates, and your browser will give you a warning each time you access a web page that uses self-signed certificates. It will allow you to choose to continue however, and so a clever enough attacker might induce you to accept their self-signed certificate. To prevent this, you can obtain a certificate signed by a Certificate Authority (CA). The browser will see that its a valid certificate, and so you will never accept self-signed certificates and you will preclude man-in-the-middle attacks.

Obtaining and installing a CA signed certificate is a fair amount of work, but not really all that difficult. We recommend it if you plan on leaving remote management enabled in production mode.

 

 

 

 

 

 

 

Configuration

 

 

 

Installing a Certificate from a Certificate Authority

To obtain and install a Certificate from a Certificate Authority (like verisign.com, thawte.com or trustcenter.de) you should have read the previous section and then follow these instructions:

Create a local Certificate Signing Request (CSR)

In order to obtain a Certificate from the Certificate Authority of your choice you have to create a so called Certificate Signing Request (CSR). That CSR will be used by the Certificate Authority to create a Certificate that will identify your website as "secure". To create a CSR follow these steps:

         Create a local Certificate (as described in the previous section):

keytool -genkey -alias tomcat -keyalg RSA \
               -keystore <your_keystore_filename>

         Note: In some cases you will have to enter the domain of your website (i.e. www.myside.org) in the field "first- and last name" in order to create a working Certificate.

         The CSR is then created with:

keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr \
               -keystore <your_keystore_filename>

Now you have a file called certreq.csr that you can submit to the Certificate Authority (look at the documentation of the Certificate Authority website on how to do this). In return you get a Certificate.

 

Importing the Certificate

Now that you have your Certificate you can import it into you local keystore. First of all you have to import a so called Chain Certificate or Root Certificate into your keystore. After that you can proceed with importing your Certificate.

         Download a Chain Certificate from the Certificate Authority you obtained the Certificate from.
For RapdidSSL certificates go to:
http://www.rapidssl.com/index_ssl.htm
For Verisign.com commercial certificates go to: http://www.verisign.com/support/install/intermediate.html
For Verisign.com trial certificates go to: http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.html For Trustcenter.de go to: http://www.trustcenter.de/certservices/cacerts/en/en.htm#server
For Thawte.com go to: http://www.thawte.com/certs/trustmap.html

         Import the Chain Certificate into you keystore

         And finally import your new Certificate

keytool -import -alias tomcat -keystore <your_keystore_filename> \
               -file <your_certificate_filename>

 

Troubleshooting

Here is a list of common problems that you may encounter when setting up SSL communications, and what to do about them.

         When Tomcat starts up, I get an exception like "java.io.FileNotFoundException: {some-directory}/{some-file} not found".

A likely explanation is that Tomcat cannot find the keystore file where it is looking. By default, Tomcat expects the keystore file to be named .keystore in the user home directory under which Tomcat is running (which may or may not be the same as yours :-). If the keystore file is anywhere else, you will need to add a keystoreFile attribute to the <Factory> element in the Tomcat configuration file.

         When Tomcat starts up, I get an exception like "java.io.FileNotFoundException: Keystore was tampered with, or password was incorrect".

Assuming that someone has not actually tampered with your keystore file, the most likely cause is that Tomcat is using a different password than the one you used when you created the keystore file. To fix this, you can either go back and recreate the keystore file, or you can add or update the keystorePass attribute on the <Connector> element in the Tomcat configuration file. REMINDER - Passwords are case sensitive!

         When Tomcat starts up, I get an exception like "java.net.SocketException: SSL handshake errorjavax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled."

A likely explanation is that Tomcat cannot find the alias for the server key within the specified keystore. Check that the correct keystoreFile and keyAlias are specified in the <Connector> element in the Tomcat configuration file. REMINDER - keyAlias values may be case sensitive!

If you are still having problems, a good source of information is the TOMCAT-USER mailing list. You can find pointers to archives of previous messages on this list, as well as subscription and unsubscription information, at http://tomcat.apache.org/lists.html.

 

Resources:

SSL HOWTO

keytool

- Configure Tomcat start/stop scripts

- Go to bin directory   
% cd /opt/tomcat/bin
 
% edit catalina.sh
 
- enter the following environment variables. 
#     CATALINA_HOME     Points at your ${tomcat-home} directory.
#     JAVA_HOME             Must point at your Java Development Kit installation.
#     JAVA_OPTS             Java runtime options used when the "start",
#
 
 
#!/bin/sh
# -----------------------------------------------------------------------------
# Start/Stop Script for the CATALINA Server
#
# $Id: catalina.sh 385888 2006-03-14 21:04:40Z keith $
# -----------------------------------------------------------------------------
 
CATALINA_HOME="/opt/tomcat"
export CATALINA_HOME
JAVA_HOME="/opt/jdk1.6.0"
export JAVA_HOME
JAVA_OPTS"-Xmx2048m -Xms512m -server"
export JAVA_OPTS
 
...
...
               

- Remove Default Tomcat Applications

Tomcat ships with several default web applications, found in the /opt/tomcat/webapps directory.

- Configure Apache/Tomcat architecture

It use to be that the Apache server was much faster at serving up static html pages then tomcat, so tomcat was installed inside Apache as a proxy. This isn t the case anymore, so it's better to install tomcat as a standalone process especially since Apache runs on port 80 which requires root to run. Tomcat runs on port 8080, so it doesn t require root privileges at all. Some administrators still require tomcat to run as a proxy so tomcat needs to be configured to be an Apache proxy.

Proxy configuration.

Here are the steps to set up a proxy configuration.