I am in the process of setting up an new Tomcat deployment, and want it to be as secure as possible.

I have created a 'jakarta' user and have jsvc running Tomcat as a daemon. Any tips on directory permissions and such to limit access to Tomcat's files?

I know I will need to remove the default webapps - docs, examples, etc... are there any best practices I should be using here? What about all the config XML files? Any tips there?

Is it worth enabling the Security manager so that webapps run in a sandbox? Has anyone had experience setting this up?

I have seen examples of people running two instances of Tomcat behind Apache. It seems this can be done using mod_jk or with mod_proxy... any pros/cons of either? Is it worth the trouble?

In case it matters, the OS is Debian lenny. I am not using apt-get because lenny only offers tomcat 5.5 and we require 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:

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
./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:

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

JMX_OPTS="-Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"


# Everything below should be okay

. /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



start() {
  # Start Tomcat
  log_daemon_msg "Starting Apache Tomcat"
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -wait 10 \
    -pidfile $PID_FILE \
    -outfile $CATALINA_BASE/logs/catalina.out \
    -errfile $CATALINA_BASE/logs/catalina.out \
    -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
  if [ 0 -eq $RETVAL ]; then
    touch $LOCK_FILE
    log_end_msg 0
    log_end_msg 1

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

restart() {
  sleep 5

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

exit $?
  • I usually add the chmod and chown stuff to the startup (init) script, as it runs as root. I've been bitten several times by people "helping out" starting tomcat as root, leading to files and directories to belong to root and not writable for the tomcat user once restarted properly. Did you miss "sudo chown tomcat:tomcat temp work" in your list? Or have I missed something? – Olaf Jul 26 '09 at 19:07
  • Since they are created by Tomcat, they will be created with tomcat:tomcat owner/group. – Gene Gotimer Jul 27 '09 at 12:30
  • Any reason for not using the pre-packaged jsvc package? Personally I just install the package even if I download Tomcat from Apache's servers. – tronda Dec 20 '11 at 8:10

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:


  • Thanks, although they are not in a very friendly format – Peter Sankauskas Aug 18 '09 at 19:57
  • The link is broken. They also do not appear to provide a Tomcat-specific checklist any more. – Bob May 21 '13 at 5:50
  • updated to fix the link. There's still some Tomcat-specific stuff in the Application Services guide. – Jim Hunziker May 21 '13 at 15:45
  • That's a great page, however, it's from 2006 so some recommendations may not be up to date for the latest tomcat. Here's the relevant paragraph on directory permissions: B.2 Setup and Startup Tomcat may be configured to run as either a single-user application or as a shared system service or process. A Tomcat service or process does not need host platform administrator or root privileges to operate. To limit the risk of exploits of the Tomcat server, a custom host account dedicated to running the Tomcat service or process will be created and assigned minimal host system privileges. – amos Feb 14 '14 at 18:02

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.


Don't forget to change the default password of the admin role in the tomcat-users.xml It's very important, else malicious person can deploy applications without restricted permission like backdoor to the tomcat server and try to do many bad things.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.