We believe Tomcat to be secure enough for typical scientific uses. There are no known security exploits or weaknesses. However, the Internet is a wild place, and we are not security experts so caveat emptor. These are best practices for running Tomcat.
Alos see:
By default, Tomcat runs on port 8080 and therefore does not require root to run. Its 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, requiring instead that you log in as yourself, then switch to being the tomcat user.
Make sure that everything under ${tomcat_home}/conf/ can be read only by the tomcat user. Typically you would also give write access to the tomcat user.
Unless you are on a private network, you need a firewall. A firewall restricts who is allowed to access network ports. Make the default setting to disallow all accesses, then enable just the ones that are needed.
Tomcat ships with several default web applications, found in the ${tomcat_home}/webapps directory. These defaults depend on the version of Tomcat and which installer you use.
The file ${tomcat_home}/conf/tomcat-users.xml stores user names and passwords. By default the passwords are in clear text, e.g.:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tdsConfig"/>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="sysadmin" password="yrPassword" roles="manager,admin"/> <user username="cataloger" password="myPassword" roles="tdsConfig"/>
</tomcat-users>
Store them instead in digested form. First generate the digest (do this for each user):
> cd ${tomcat_home}/bin > ./digest.sh -a SHA yrPassword > yrPassword:aa01ea2afaae56c2b7da5e25ec18c505e58f12d7
If you are using DIGEST authentication, (only needed if you arent using SSL), then use {username}:{realm}:{yrPassword}
instead
of {yrPassword}
in calculating the digest, for example sysadmin:THREDDS Data Server:yrPassword
.
See this for more details.
Then cut and paste the digested passwords into the tomcat-users.xml:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tdsConfig"/>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="sysadmin" password="aa01ea2afaae56c2b7da5e25ec18c505e58f12d7" roles="manager,admin"/> <user username="cataloger" password="5413ee24723bba2c5a6ba2d0196c78b3ee4628d1" roles="tdsConfig"/>
</tomcat-users>
Then change the server.xml file to tell it to use digested passwords, by adding this <Realm> element to the <Host> element named localhost:
<Host name="localhost" debug="0" appBase="/opt/tomcat/webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Realm className="org.apache.catalina.realm.MemoryRealm" digest="SHA" /> ... </Host>
The tdsConfig, manager and admin roles allow access to secure parts of Tomcat and TDS. These can only be accessed using HTTPS (TLS), and so
are considered secure. If you are restricting access to datasets, you will also add other users who will have the restrictedDatasetUser role.
Do not give any of these users (including yourself!) any of the tdsConfig, manager or admin roles - keep them strictly separate.
This is because restrictedDatasetUser usage can also use non-HTTPS URLs, and so is vulnerable to
session hijacking. By keeping the roles separate, you make sure that the worst that can happen is
that someone can download some scientific data they shouldn't have access to.
The best way to secure the Tomcat manager and administration webapps is to restrict the set of IP addresses that can access them. This can be accomplished by including a RemoteAddrValve (Tomcat docs) in the Context element of these applications. For instance, to only allows connections from the localhost (127.0.0.1), i.e., the machine on which the Tomcat server is running, do the following:
<Context antiResourceLocking="false" privileged="true" />Change it to include the highlighted line here:
<Context antiResourceLocking="false" privileged="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/> </Context>
<Context antiResourceLocking="false" privileged="true"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/> </Context>
NOTE: The value of the allow attribute must be a comma separated list of regular expressions used to match against the remote client's IP address. Here are several examples:
allow="128\.117\.140\.62"
allow="128\.117\.140\.62,128\.117\.140\.63,128\.117\.140\.99"
Similarly, you can use the RemoteHostValve to filter by host name. Again, the value of the allow and deny attributes must be a comma separated list of regular expressions which will be used to match against the remote client's host name. For instance:
<Valve className="org.apache.catalina.valves.RemoteHostValve" allow=".*\.ucar\.edu"/>
An additional level of security can be provided by running Tomcat with the Java Security Manager turned on. This can provide fine-grained security policies, at the cost of complexity in understanding what rights are needed to do any useful work, and how to grant them. This is needed if you allow untrusted servlets or JSPs to execute on your machine. If you are running just the THREDDS Data Server, you probably don't need to deal with this.