What steps should I take to secure Tomcat 6.x?

You can install Tomcat 6 to run under jsvc as user tomcat (not as root). Here's what I did last time I set it up:

I installed the Tomcat application under /usr/java/tomcat (CATALINA_HOME) and an instance under /var/lib/tomcat (CATALINA_BASE):

cd /usr/java
sudo tar xzvf ~/downloads/apache-tomcat-6.0.18.tar.gz
sudo ln -s apache-tomcat-6.0.18 tomcat
sudo /usr/sbin/useradd -d /var/lib/tomcat -c "Apache Tomcat" -m -s /sbin/nologin tomcat
cd /var/lib/tomcat
sudo mkdir logs work temp
sudo chown tomcat:tomcat logs temp work
(cd /usr/java/tomcat && sudo tar cvf - conf webapps) | sudo tar xvf -
sudo chmod -R g+rw webapps conf
sudo chown -R tomcat:tomcat webapps conf
cd webapps/
sudo rm -rf docs examples manager host-manager
cd ../conf
sudo chmod g+r *

Then I built the jsvc wrapper:

cd
tar xzvf downloads/apache-tomcat-6.0.18.tar.gz
tar xzvf apache-tomcat-6.0.18/bin/jsvc.tar.gz
cd jsvc-src
chmod +x configure
./configure --with-java=$JAVA_HOME
make
./jsvc --help
sudo cp jsvc /usr/local/sbin/ 

Finally, I tightened the permissions on the instance directories:

cd /var/lib/tomcat
sudo chmod -R 0700 conf
sudo chmod -R 0750 logs
sudo chmod -R 0700 temp
sudo chmod -R 0700 work
sudo chmod -R 0770 webapps/
sudo chown -R tomcat:tomcat conf
sudo chown -R tomcat:tomcat logs

When you run Tomcat now, you'll need to start it using jsvc, so add this script as /etc/init.d/tomcat and symlink it appropriately:

#!/bin/sh
#
# tomcat       Startup script for the Apache Tomcat Server running under jsvc
#
# chkconfig: 345 85 15
# description: Apache Tomcat
# pidfile: /var/run/jsvc.pid

JAVA_HOME=/usr/java/jdk1.6.0_13
CATALINA_HOME=/usr/java/apache-tomcat-6.0.18
CATALINA_BASE=/var/lib/tomcat
JAVA_OPTS="-Djava.awt.headless=true"
JMX_OPTS="-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

DAEMON_APP=/usr/local/sbin/jsvc
TOMCAT_USER=tomcat

# Everything below should be okay
PID_FILE=/var/run/jsvc.pid
LOCK_FILE=/var/lock/tomcat

PATH=/sbin:/bin:/usr/bin
. /lib/init/vars.sh

. /lib/lsb/init-functions

[ -x $JAVA_HOME/bin/java ] || exit 0
[ -x $DAEMON_APP ] || exit 0
[ -d $CATALINA_HOME/bin ] || exit 0
[ -d $CATALINA_BASE ] || exit 0

RETVAL=0
prog="jsvc"

CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar

start() {
  # Start Tomcat
  log_daemon_msg "Starting Apache Tomcat"
  $DAEMON_APP \
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -wait 10 \
    -pidfile $PID_FILE \
    -outfile $CATALINA_BASE/logs/catalina.out \
    -errfile $CATALINA_BASE/logs/catalina.out \
    $JAVA_OPTS $JMX_OPTS \
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
    -Djava.util.logging.config.file=$CATALINA_BASE/conf/logging.properties \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.io.tmpdir=$CATALINA_BASE/temp \
    -cp $CLASSPATH \
    org.apache.catalina.startup.Bootstrap start 2>/dev/null 1>&2
  RETVAL=$?
  if [ 0 -eq $RETVAL ]; then
    touch $LOCK_FILE
    log_end_msg 0
  else
    log_end_msg 1
  fi
}

stop() {
  # Stop tomcat
  log_daemon_msg "Stopping Apache Tomcat"
  $DAEMON_APP \
    -stop \
    -pidfile $PID_FILE \
    org.apache.catalina.startup.Bootstrap 2>/dev/null 1>&2
  RETVAL=$?
  if [ 0 -eq $RETVAL ]; then
    rm -rf $LOCK_FILE
    log_end_msg 0
  else
    log_end_msg 1
  fi
}

restart() {
  stop
  sleep 5
  start
}

# See how we were called.
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    restart
    ;;
  status)
    status $prog
    ;;
  condrestart)
    [ -f $LOCK_FILE ] && restart || :
    ;;
  *)
    log_action_msg "Usage: $0 {start|stop|restart|status|condrestart}"
    exit 1
esac

exit $?

The US Department of Defense has a good guide that has combined Tomcat security guidance into an overall Web Server Security Guide (SRG). You can find more security guides here:

http://iase.disa.mil/stigs/srgs/Pages/index.aspx


The Open Web Application Security Project (OWASP) offers a wiki page on securing Tomcat, which you might find useful. At the time of writing, it seems more focused on Tomcat 5.x, but hopefully will be updated as time passes.


I'd seriously consider backporting the tomcat6 packages from testing. You can subscribe to the package to get notifications of new versions being uploaded to the archive. (I'm slightly biased as I have worked on the debian packaging).

I have not tried running webapps under a security manager, as no application comes with a policy and it's frankly a time consuming operation to create one yourself. If you are paranoid, you can certainly do so. It mostly involves running tomcat, waiting for something to bitch and then adding an exception to the policy and restarting tomcat again. Rinse, repeat, etc.

Obviously, don't run tomcat as root. The tomcat user shouldn't be able to write to anything outside the log directory or the work directory. You should make sure that your webapps directory only contains the webapps you want to run.

I always run tomcat behind apache. This is partly because I'd like to think that more people use apache, so bugs would be found quicker. This is pretty much wishful thinking and you shouldn't rely on this being a security improvement. What Apache does bring you is configurability. There are lots of modules that tomcat just doesn't have, or can't do as efficiently. mod_cache, mod_ssl, mod_security all spring to mind. You have the choice of mod_jk, mod_proxy (and either mod_proxy_http or mod_proxy_ajp). mod_jk (and mod_proxy_ajp) use the binary AJP protocol rather than the less efficient http protocol. I'd recommend using mod_jk.