How to secure Tomcat
Apache Tomcat has a relatively low number of vulnerabilities compared to other web technologies, but to maintain a stable and secure environment you must pay attention to every application server and servlet container, including Tomcat. Here are some tips and tricks to help you improve the security of your organization's Tomcat deployment.
Secure Tomcat installation
Tomcat's installation is simple and straightforward – you just need to extract the installation package, and the only prerequisite is to have Java (JRE or JDK) installed. However, you should be aware of a few important security points for the installation.
First, ensure that you always have the latest Java version. Even if you are using an older Java branch, you should make sure that you use its corresponding latest version. Many developers prefer to use Oracle's proprietary JDK for compatibility reasons, even though it is not supported by any distribution's repository. If you do that you have to check for updates and download and install them manually. Alternatively, OpenJDK is included in most Linux distributions repositories, including CentOS, which makes it easier and faster to update Java through package managers such as yum.
Second, ensure that Tomcat runs under its own unprivileged user. You can create a suitable user with a command like
groupadd tomcat && useradd -s /sbin/nologin -g tomcat tomcat. Not only is this user is unprivileged but it is also not allowed to log in to the system, so its password cannot be compromised, nor can the account do much harm on your system unless a hacker finds a vulnerability that escalates its privileges. To start Tomcat with this user you can use the command
/bin/su -s /bin/sh tomcat $ CATALINA_HOME/startup.sh, where $ CATALINA_HOME is the path to Tomcat's startup script.
One peculiarity about having Tomcat running with an unprivileged user is that Tomcat will not be able to bind to the standard HTTP port, port 80, because ports below the first 1024 ports are reserved for privileged users. That's why by default Tomcat is configured to listen on TCP port 8080. You can easily redirect requests from port 80 to port 8080 with iptables or your firewall or router, but it's better to place a web server such as Apache in front to proxy requests. Integrating Tomcat and Apache not only allows you to serve traffic on the standard HTTP port but also adds another layer of security.
Secure Tomcat configuration
Once you have Tomcat installed, the first thing you should do is remove its default web applications, which are not needed in a production environment. You can safely delete all contents inside the directory webapps in Tomcat's root, including the hostmanager, test applications, and documentation, because they could pose a security risk and disclose information about your setup.
The next thing to consider is connectivity from outside. In an ideal world your firewall should not allow any direct connection to Tomcat. Access from outside should be possible only through a reverse proxy. If you cannot limit external access then you should leave open only the connector you need. By default connectors are defined for ports 8080 (HTTP) and 8009 (AJP). You should comment out the one you don't need in the server.xml configuration file in Tomcat's conf directory.
While you're tweaking the connector settings, adjust the
connectionTimeout value, which defines how long Tomcat waits for the URI line to be presented after accepting a connection. The default value is 20000 miliseconds, or 20 seconds. If you run Tomcat behind a proxy this value is fine, but if you allow external access to the HTTP connector you should consider the threat this number could pose by allowing an attacker to open a large number of connections which are to be closed only after 20 seconds. Even if you are not able to decrease the timeout because of slow connectivity concerns or other reasons, you should note this option and consider decreasing it in times of problems and overloads.
The last important option to change for the connector is the server value. By default, Tomcat shows
Server Apache-Coyote/1.1 in the HTTP headers. This information could be used by an attacker, so instead specify
server="IIS" in the connector settings to make your Tomcat pretend it's an ISS server, at least in the HTTP headers.
You should also remove jsessionid from URLs. The value of jsessionid in a URL is meant to provide session support for browsers that do not support cookies. However, an attacker can create a link with a specific jsessionid and send it to a potential victim. If the victim logs in the site with this jsessionid, then the attacker is also logged in. To avoid this kind of threat, edit the web.xml file inside Tomcat's conf directory and ensure that only cookies are supported for session tracking by specifying:
<session-config> <tracking-mode>COOKIE</tracking-mode> </session-config>
Encryption and SSL
Enabling encryption can also help with security. By enabling SSL encryption in Tomcat connectors you can secure the traffic either between end users and Tomcat or between a reverse web proxy and Tomcat. For internal use (for example between Tomcat and a reverse proxy) you can use a free self-signed certificate with the command
keytool -genkey -alias tomcat -keyalg RSA -validity 1826 -keysize 2048 -keystore tomcat.jks. This creates a new self-signed certificate under the alias tomcat in a new keystore called tomcat.jks. This new certficate will be valid for five years (1826 days) and uses a strong private key (2048 bit) for encryption.
To install and configure your new certificate in Tomcat, edit server.xml and create a connector similar to this one:
<Connector protocol="HTTP/1.1" port="8888" scheme="https" secure="true" SSLEnabled="true" keystoreFile="/srv/tomcat/conf/tomcat.jks" keystorePass="changeit" clientAuth="false" sslProtocol="TLS"/>
Then configure your reverse proxy to use this Tomcat connector by pointing it to port 8888 of your Tomcat server's IP address, as with the commands
ProxyPass / https://tomcat_ip:8888/ and
ProxyPassReverse / https://tomcat_ip:8888/ in Apache's configuration file (/etc/httpd/conf/httpd.conf in CentOS). If you're using Apache, don't forget to add
SSLProxyEngine On to its configuration in the same file when changing from an HTTP to HTTPS back-end server to enable SSL support in the proxy functionality.
Once you restart Tomcat, traffic between your reverse proxy and Tomcat will be encrypted. This server-to-server encryption is especially important if you have your reverse proxy and Tomcat running on different servers, as is recommended by many best practices and security standards, such as the PCI SSC Data Security Standards.
The foregoing are the most important steps you can take to help run Tomcat securely. All it takes is a little bit of work and a few minor reconfigurations.