TDS Tutorial: Tomcat and TDS Security

Best practices and recommendations on securing a production TDS/Tomcat server.

Why Is This Important?

Be afraid

  • Misconfiguration of Tomcat can introduce vulnerabilities in security.
  • The following recommendations should be considered "layers" of security: not completely effective by themselves, but more potent when combined.
  • This is not a complete laundry list of security fixes! Please use it as a starting point when securing your server.
  • Suggestions below listed in random order (section ordering is not a representation of the section importance).

Keeping Software Versions Up-To-Date

Rationale

  • Running the most current versions of software keeps your environment protected against known security vulnerabilities. This includes the JDK, Tomcat, the TDS and any other third-party libraries or software you run.
  • Stay Informed! Subscribe to announcement lists for Tomcat, the TDS and any other software you deploy, to stay abreast of new versions released due to security issues.
  • As soon as a security issue is disclosed, potential attackers will begin trying to exploit that vulnerability. It is important that you upgrade your software before an attacker uses the vulnerability against you.

Resources

  • Tomcat security reports
    A complete list of known and documented security vulnerabilities associated with each Tomcat release.
  • tomcat-users mailing list
    A high-traffic mailing list made up of Tomcat users. New releases of Tomcat are likely to be announced here.
  • Java SE Security
    Sun's Java security page which includes a chronology of Java security issues and user forums.
  • thredds mailing list
    The THREDDS mailing list where announcements of new releases will be made.
  • Buqtraq vunerability database
    SecurityFocus' database of all known vulnerabilities for all different types of software from different vendors.

Tomcat Process User/Group and $CATALINA_HOME Permissions

Rationale

Background info

The JVM doesn't fork at all, nor does it support setuid() calls. The JVM (and therefore Tomcat) is one process. The JVM is a virtual machine with many threads under the same process.

  • Because of OS constraints, all threads in the same JVM process must run under the same user id. No thread may run as the root user unless they are all are run as the root user. Hence, any programs run in Tomcat (TDS, manager application, other JSPs and servlets) will run as the root user.
  • If you choose to run the Tomcat process as the root user, and an attacker manages to exploit a weakness in Tomcat or something running in webapps/ to run arbitrary commands, those commands will be run as the superuser!
  • We strongly discourage running Tomcat as the root user and recommend creating an unprivileged, dedicated user and group for running the Tomcat process.
  • We also recommend restricting the permissions of the Tomcat user/group within $CATALINA_HOME.

Creating a dedicated Tomcat user/group & setting permissions in $CATALINA_HOME

  1. Create a dedicated user and group for running Tomcat.
  2. In this example, both the user and group names will be names tomcat, and the user's home directory, aka $CATALINA_HOME, is /opt/tomcat (notice the symlink below). The groupadd and useradd commands were run as the root:

    # groupadd tomcat
    # useradd -g tomcat -d /opt/tomcat tomcat
    # passwd tomcat
    
  3. Tighten the permissions in $CATALINA_HOME
  4. Change the user/group ownership $CATALINA_HOME to the tomcat user and tomcat group:

    # cd /opt
    # chown -R tomcat:tomcat apache-tomcat-6.0.32
    # ls -ld  *tomcat*
    drwxr-xr-x  9 tomcat  tomcat  4096 Jul 15 16:03 apache-tomcat-6.0.32
    lrwxrwxrwx  1 root    other     20 Jul 15 19:00 tomcat -> apache-tomcat-6.0.32
    

    Change the user/ownership of the $CATALINA_HOME/conf directory to be owned by the root user, have a group of tomcat and have a permission of user/group read only:

    # cd /opt/tomcat
    # ls -l
    total 92
    drwxr-xr-x 2 tomcat  tomcat  4096 Jul 15 16:05 bin
    drwxr-xr-x 2 tomcat  tomcat  4096 Jul 18 12:18 conf
    drwxr-xr-x 2 tomcat  tomcat  4096 Jul 15 16:03 lib
    drwxr-xr-x 2 tomcat  tomcat  4096 Feb  2 12:04 logs
    drwxr-xr-x 2 tomcat  tomcat  4096 Jul 15 16:03 temp
    drwxr-xr-x 7 tomcat  tomcat  4096 Jul 15 16:04 webapps
    drwxr-xr-x 2 tomcat  tomcat  4096 Feb  2 12:04 work
    
    # chown -R root:tomcat conf
    # chmod -R 440 conf/*
    # ls -l conf
    total 92
    -r--r----- 1 root    tomcat  9978 Feb  2 12:06 catalina.policy
    -r--r----- 1 root    tomcat  3713 Feb  2 12:06 catalina.properties
    -r--r----- 1 root    tomcat  1395 Feb  2 12:06 context.xml
    -r--r----- 1 root    tomcat  1353 Jul 18 12:14 keystore
    -r--r----- 1 root    tomcat  3257 Feb  2 12:06 logging.properties
    -r--r----- 1 root    tomcat  6814 Jul 18 12:18 server.xml
    -r--r----- 1 root    tomcat   210 Jul 18 12:10 tomcat-users.xml
    -r--r----- 1 root    tomcat 51835 Feb  2 12:06 web.xml
    

    Change the user/ownership of the $CATALINA_HOME/bin and $CATALINA_HOME/lib directories to be owned by the root user and have a group of tomcat:

    # chown -R root:tomcat lib
    # chown -R root:tomcat bin
    # ls -l
    total 92
    drwxr-xr-x 2 root    tomcat  4096 Jul 15 16:05 bin
    drwxr-xr-x 2 root    tomcat  4096 Jul 18 12:18 conf
    drwxr-xr-x 2 root    tomcat  4096 Jul 15 16:03 lib
    drwxr-xr-x 2 tomcat  tomcat  4096 Feb  2 12:04 logs
    drwxr-xr-x 2 tomcat  tomcat  4096 Jul 15 16:03 temp
    drwxr-xr-x 7 tomcat  tomcat  4096 Jul 15 16:04 webapps
    drwxr-xr-x 2 tomcat  tomcat  4096 Feb  2 12:04 work
    

Resources

Removing Unused Web Applications

Rationale

  • It is generally good practice to remove any un-used web applications out of $CATALINA_HOME/webapps.
  • Tomcat "ships" with several default web applications you may want to consider removing if they are not being utilized:
    • The ROOT application is Tomcat's DocumentRoot and contains the server's main web page. Give thought to the content that is placed in ROOT/, as it will be readily available. (Note: if you want to utilize a robots.txt file to restrict crawler activity, ROOT/ is the place it will go.)
    • The manager application is used for remote management of web applications. To use this application, you must add a user with role of manager-gui in tomcat-users.xml. Obviously, if you are not planning to use the manager application, it should be removed.
    • The host-manager application is used for management of virtual hosts. To use this application, you must add a user with role of admin-gui in tomcat-users.xml. If you are not planning to do a lot of virtual hosting in Tomcat this application should be removed.
    • The examples application should probably be removed from a production server to minimize security exposure.
    • The docs are a copy of the Tomcat documentation found online. Unless you have need for a local copy, removing docs would help to tidy-up $CATALINA_HOME/webapps.

Using Digested Passwords

Rationale

Tomcat Realms

A realm element represents a "database" of usernames, passwords, and roles (similar to Unix groups) assigned to those users.

Configure Tomcat to use digested passwords

  1. First we need to enable digest passwords support in Tomcat by modifying a couple of Tomcat Realms in the server.xml file in the Tomcat conf/ directory.
  2. A Tomcat Realm represents a "database" of usernames, passwords, and roles assigned to tomcat users.

    Realm Name Purpose
    UserDatabaseRealm The UserDatabaseRealm is enabled by default and reads clear text user password information stored in tomcat-users.xml.
    MemoryRealm The MemoryRealm reads the user password information stored in the tomcat-users.xml in a specified encrypted format.

    Open the server.xml with your favorite editor:

    $ vi server.xml
    

    Locate the UserDatabaseRealm (right above the Host element) and comment it out:

    <!-- This Realm uses the UserDatabase configured in the global JNDI
         resources under the key "UserDatabase".  Any edits
         that are performed against this UserDatabase are immediately
         available for use by the Realm.  -->
    <!-- 
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
           resourceName="UserDatabase"/>
    -->
    <!-- Define the default virtual host
         Note: XML Schema validation will not work with Xerces 2.2.
    -->
    <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true"
          xmlValidation="false" xmlNamespaceAware="false">
    

    Now add the following MemoryRealm information below the commented out UserDatabaseRealm:

    <!-- This Realm uses the UserDatabase configured in the global JNDI
         resources under the key "UserDatabase".  Any edits
         that are performed against this UserDatabase are immediately
         available for use by the Realm.  -->
    <!-- 
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
           resourceName="UserDatabase"/>
    -->
    <!-- Define the default virtual host
         Note: XML Schema validation will not work with Xerces 2.2.
    -->
    
     <Realm className="org.apache.catalina.realm.MemoryRealm" 
                     digest="SHA" />
    
    <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true"
          xmlValidation="false" xmlNamespaceAware="false">
    
       
    
  3. Create a SHA encrypted version of your password.
  4. Tomcat provides a script ($CATALINA_HOME/bin/digest.sh) that will encrypt a password string according to the algorithm specified. Use this script as follows with the password you made for yourself previously:

    $ /home/tds/apache-tomcat-6.0.32/bin/digest.sh -a SHA secret
    secret:e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4
    
  5. Update tomcat-users.xml.
  6. Replace your clear-text password in tomcat-users.xml with the encrypted version:

    <tomcat-users>
        <role rolename="manager-gui"/>
        <user username="admin" password="e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4" roles="manager-gui"/>
    </tomcat-users>
    
  7. Verify digest passwords have been successfully enabled in Tomcat.
  8. BASIC authentication

    Since we are using BASIC authentication, you will need to clear any authenticated sessions in your browser to test whether digested passwords have been enabled.

    Restart Tomcat and verify digest passwords have been successfully enabled by logging into the Tomcat manager application using your password in clear text: http://localhost:8080/manager/html/

    Troubleshooting tips

    • Check the XML syntax in tomcat-users.xml and server.xml to make sure it is well-formed and without error.
    • Did you restart Tomcat after you made your changes to tomcat-users.xml and server.xml ?
    • Any errors will be reported in the catalina.out file in the Tomcat logs/ directory.
    • You do not need to type the encrypted version of your password into the browser (the browser auto-magically encrypts your password for you before it transmits it to the server).

Enabling SSL Encryption

How SSL works

For more information on how SSL works, Wikipedia details the steps involved during an SSL transaction.

Rationale

CA-signed Certificates

A self-signed certificate says to your users "Trust me - I am who I say I am."

A certificate signed by a CA says, "Trust me - the CA agrees I am who I say I am."

SSL certificates

Certificate keystore file

Accessing the TDS remote management tool

Other than the compelling security reasons, you will want to enable SSL to take advantage of the TDS remote management tool which (out-of-the-box) requires SSL in order to access: http://localhost:8080/thredds/admin/debug

  1. Configure Tomcat to enable SSL and use the self-signed certificate.
  2. Based on what we know about Tomcat configuration, which file in $CATALINA_HOME/conf should we edit to to enable SSL?

    Open $CATALINA_HOME/conf/server.xml with your favorite editor:

    $ vi server.xml
    

    Locate the Java HTTP/1.1 Connector listening on port 8080 and verify it is redirecting SSL traffic to port 8443:

    <Connector port="8080" protocol="HTTP/1.1"
                  connectionTimeout="20000"
                  redirectPort="8443" />
    

    Find and uncomment the SSL HTTP/1.1 Connector listening on port 8443 to activate this connector:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                  maxThreads="150" scheme="https" secure="true"
                  clientAuth="false" sslProtocol="TLS" />
    

    Add a keystoreFile attribute to the SSL HTTP/1.1 Connector to tell Tomcat where to find your keystore:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                  maxThreads="150" scheme="https" secure="true"
                  clientAuth="false" sslProtocol="TLS" keystoreFile="/home/tds/tds/apache-tomcat-6.0.32/conf/keystore" />
    

    Since we opted to not use the default keystore password, we need to specify the new password so Tomcat can open the file:

    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                  maxThreads="150" scheme="https" secure="true"
                  clientAuth="false" sslProtocol="TLS" keystoreFile="/home/tds/tds/apache-tomcat-6.0.32/conf/keystore" keystorePass="foobar" />
    

    Finally, verify the AprLifecycleListener is uncommented (found near the top of the file):

    <!--APR library loader. Documentation at /docs/apr.html -->
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    
  3. Verify SSL has been enabled.
  4. Restart Tomcat:

    $ $CATALINA_HOME/bin/shutdown.sh
    $ $CATALINA_HOME/bin/startup.sh
    

    Verify Tomcat is listening on port 8443 by running the netstat command:

    $ netstat -an | grep tcp | grep 8443
    

    man netstat

    Run man netstat in your terminal window to learn more about this command.

    netstat (short for network statistics) is available on Unix, Unix-like, and Windows NT-based operating systems. It is a command-line tool that displays:

    • network connections (both incoming and outgoing)
    • routing tables
    • and a number of network interface statistics

    Look for the following in the output:

    tcp        0      0 0.0.0.0:8443               0.0.0.0:*                   LISTEN
    

    Troubleshooting tips

    • Check the XML syntax in server.xml to make sure it is well-formed and without error.
    • When generating the self-signed certificate, the last password (the key password) and keystore password should be the same (changeit). If they differ, Tomcat cannot open the keystore and you will get this error: java.io.IOException: Cannot recover key.
    • Did you restart Tomcat after you made your changes to server.xml?
    • Did you specify the full path to the keystore file in server.xml?
  5. Modify $CATALINA_HOME/conf/tomcat-users.xml to add a new role with the rolename attribute of tdsConfig, and add this role to your list of roles:
  6. <tomcat-users>
        <role rolename="manager-gui"/>
        <role rolename="tdsConfig"/>
        <user username="admin" password="e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4" roles="manager-gui,tdsConfig"/>
    </tomcat-users>
    
  7. Restart Tomcat and try to access the TDS remote management tool: http://localhost:8080/thredds/admin/debug/
  8. SSL warning for self-signed certificate

Configuring web applications for SSL

How did Tomcat know to use SSL for the TDS remote management tool?

Where, in any of the configuration changes you made to $CATALINA_HOME/conf/server.xml or $CATALINA_HOME/conf/tomcat-users.xml, did you explicitly specify that TDS remote management tool must be accessed via SSL?

The missing piece: /WEB-INF/web.xml

Looking at the TDS deployment descriptor

  1. Have a look at the deployment descriptor that comes with the TDS.
  2. Navigate to the unpacked thredds directory in $CATALINA_HOME/webapps, and view the file:

    $ cd /home/tds/tds/apache-tomcat-6.0.32/webapps/thredds
    $ less WEB-INF/web.xml
    
  3. Look for a reference to the TDS remote management tool's URL (/admin/debug).
  4. Near the bottom of the deployment descriptor you will find this entry:

      <!-- This allows "remote configuration":
        /thredds/admin/debug gives access to various debug and status info.
        /thredds/admin/content/ -> "{tomcat_home}/content/thredds/"
        /thredds/admin/root/ -> "{tomcat_home}/webapps/thredds/" DISABLED
        /thredds/admin/dataDir/path -> "{dataRoot(path)}/webapps/thredds/"  DISABLED
       -->
      <security-constraint>
        <web-resource-collection>
          <web-resource-name>sensitive read access</web-resource-name>
          <url-pattern>/admin/*</url-pattern>
          <http-method>GET</http-method>
          <!-- http-method>PUT</http-method -->
        </web-resource-collection>
        <auth-constraint>
          <role-name>tdsConfig</role-name>
        </auth-constraint>
        <user-data-constraint>
          <transport-guarantee>CONFIDENTIAL</transport-guarantee>
        </user-data-constraint>
      </security-constraint>
    

    Configuration help

    For more information on how to configure security requirements for a web application in a deployment descriptor, see: Defining Security Requirements for Web Applications.

    • The <user-data-constraint> establishes a requirement that the constrained requests be received over a protected transport layer connection. This guarantees how the data will be transported between client and server.
    • <transport-guarantee> choices for type of transport guarantee include NONE, INTEGRAL, and CONFIDENTIAL:
      1. Specify CONFIDENTIAL when the application requires that data be transmitted so as to prevent other entities from observing the contents of the transmission. (E.g., via SSL.)
      2. Specify INTEGRAL when the application requires that the data be sent between client and server in such a way that it cannot be changed in transit.
      3. Specify NONE to indicate that the container must accept the constrained requests on any connection, including an unprotected one.

Changes to the manager application

The manager application URLs and roles has been re-structured. See the Tomcat Migration guide for more information.

Enabling SSL for the Tomcat manager application

  1. Modify the deployment descriptor of the Tomcat manager application.
    • If you are using Tomcat version 6.0.29 or older:
    • Using your favorite editor, open the deployment descriptor for the Tomcat manager application:

      $ vi $CATALINA_HOME/webapps/manager/WEB-INF/web.xml
      

      Locate the <security-constraint> element (near the bottom of the file):

        <!-- Define a Security Constraint on this Application -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTMLManger and Manager command</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
            <url-pattern>/html/*</url-pattern>
            <url-pattern>/list</url-pattern>
            <url-pattern>/expire</url-pattern>
            <url-pattern>/sessions</url-pattern>
            <url-pattern>/start</url-pattern>
            <url-pattern>/stop</url-pattern>
            <url-pattern>/install</url-pattern>
            <url-pattern>/remove</url-pattern>
            <url-pattern>/deploy</url-pattern>
            <url-pattern>/undeploy</url-pattern>
            <url-pattern>/reload</url-pattern>
            <url-pattern>/save</url-pattern>
            <url-pattern>/serverinfo</url-pattern>
            <url-pattern>/status/*</url-pattern>
            <url-pattern>/roles</url-pattern>
            <url-pattern>/resources</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE:  This role is not present in the default users file -->
             <role-name>manager</role-name>
          </auth-constraint>
        </security-constraint>
      

      Add a <user-data-constraint> with a <transport-guarantee> of CONFIDENTIAL to enable port-forwarding to port 8443:

        <!-- Define a Security Constraint on this Application -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTMLManger and Manager command</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
            <url-pattern>/html/*</url-pattern>
            <url-pattern>/list</url-pattern>
            <url-pattern>/expire</url-pattern>
            <url-pattern>/sessions</url-pattern>
            <url-pattern>/start</url-pattern>
            <url-pattern>/stop</url-pattern>
            <url-pattern>/install</url-pattern>
            <url-pattern>/remove</url-pattern>
            <url-pattern>/deploy</url-pattern>
            <url-pattern>/undeploy</url-pattern>
            <url-pattern>/reload</url-pattern>
            <url-pattern>/save</url-pattern>
            <url-pattern>/serverinfo</url-pattern>
            <url-pattern>/status/*</url-pattern>
            <url-pattern>/roles</url-pattern>
            <url-pattern>/resources</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager</role-name>
          </auth-constraint>
          <user-data-constraint>
             <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
      
    • If you are using Tomcat version 6.0.30 or 6.0.32:
    • Using your favorite editor, open the deployment descriptor for the Tomcat manager application:

      $ vi $CATALINA_HOME/webapps/manager/WEB-INF/web.xml
      

      Locate the <security-constraint> element (near the bottom of the file):

        <!-- Define a Security Constraint on this Application -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Manager commands</web-resource-name>
            <url-pattern>/list</url-pattern>
            <url-pattern>/expire</url-pattern>
            <url-pattern>/sessions</url-pattern>
            <url-pattern>/start</url-pattern>
            <url-pattern>/stop</url-pattern>
            <url-pattern>/install</url-pattern>
            <url-pattern>/remove</url-pattern>
            <url-pattern>/deploy</url-pattern>
            <url-pattern>/undeploy</url-pattern>
            <url-pattern>/reload</url-pattern>
            <url-pattern>/save</url-pattern>
            <url-pattern>/serverinfo</url-pattern>
            <url-pattern>/roles</url-pattern>
            <url-pattern>/resources</url-pattern>
            <url-pattern>/findleaks</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use the manager-script role to take advantage of the new
                           CSRF protection. Using the manager role or assigning both
                           the manager-script and manager-gui roles to the same user
                           will bypass the CSRF protection. -->
             <role-name>manager-script</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTML Manager commands</web-resource-name>
            <url-pattern>/html/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use just the manager-gui role to take advantage of the new
                           CSRF protection. Assigning the manager role or manager-gui
                           role along with either the manager-script or manager-jmx
                           roles to the same user will bypass the CSRF protection. -->
             <role-name>manager-gui</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
        </security-constraint>
      
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>JMX proxy</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use the manager-jmx role to take advantage of the new
                           CSRF protection. Using the manager role or assigning both
                           the manager-jmx and manager-gui roles to the same user
                           will bypass the CSRF protection. -->
             <role-name>manager-jmx</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Status</web-resource-name>
            <url-pattern>/status/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7. -->
             <role-name>manager-status</role-name>
             <role-name>manager-gui</role-name>
             <role-name>manager-script</role-name>
             <role-name>manager-jmx</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
        </security-constraint>
      
      

      The manager application deployment descriptor for these later versions of Tomcat 6 has been modified to be similar to the configuration the manager application as it appears in Tomcat 7. The deployment descriptor contains a <security-constraint> section for three of the ContactPaths (as per Manager Application section of the Tomcat Migration Guide), as well as a 'catch all' <security-constraint> to handle the various script-oriented manager commands found in earlier versions of Tomcat 6.

      Add a <user-data-constraint> with a <transport-guarantee> of CONFIDENTIAL for the desired ContactPaths to to enable port-forwarding to port 8443:

        <!-- Define a Security Constraint on this Application -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Manager commands</web-resource-name>
            <url-pattern>/list</url-pattern>
            <url-pattern>/expire</url-pattern>
            <url-pattern>/sessions</url-pattern>
            <url-pattern>/start</url-pattern>
            <url-pattern>/stop</url-pattern>
            <url-pattern>/install</url-pattern>
            <url-pattern>/remove</url-pattern>
            <url-pattern>/deploy</url-pattern>
            <url-pattern>/undeploy</url-pattern>
            <url-pattern>/reload</url-pattern>
            <url-pattern>/save</url-pattern>
            <url-pattern>/serverinfo</url-pattern>
            <url-pattern>/roles</url-pattern>
            <url-pattern>/resources</url-pattern>
            <url-pattern>/findleaks</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use the manager-script role to take advantage of the new
                           CSRF protection. Using the manager role or assigning both
                           the manager-script and manager-gui roles to the same user
                           will bypass the CSRF protection. -->
             <role-name>manager-script</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTML Manager commands</web-resource-name>
            <url-pattern>/html/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use just the manager-gui role to take advantage of the new
                           CSRF protection. Assigning the manager role or manager-gui
                           role along with either the manager-script or manager-jmx
                           roles to the same user will bypass the CSRF protection. -->
             <role-name>manager-gui</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
      
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>JMX proxy</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7.
                        3. Use the manager-jmx role to take advantage of the new
                           CSRF protection. Using the manager role or assigning both
                           the manager-jmx and manager-gui roles to the same user
                           will bypass the CSRF protection. -->
             <role-name>manager-jmx</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Status</web-resource-name>
            <url-pattern>/status/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <!-- NOTE: 1. These roles are not present in the default users file
                        2. The manager role is deprecated, it will be removed in
                           Tomcat 7. -->
             <role-name>manager-status</role-name>
             <role-name>manager-gui</role-name>
             <role-name>manager-script</role-name>
             <role-name>manager-jmx</role-name>
             <role-name>manager</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
      
      
    • If you are using Tomcat 7:
    • Using your favorite editor, open the deployment descriptor for the Tomcat manager application:

      $ vi $CATALINA_HOME/webapps/manager/WEB-INF/web.xml
      

      Locate the <security-constraint> elements (near the bottom of the file):

        <!-- Define a Security Constraint on this Application -->
        <!-- NOTE:  None of these roles are present in the default users file -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTML Manager interface (for humans)</web-resource-name>
            <url-pattern>/html/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-gui</role-name>
          </auth-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Text Manager interface (for scripts)</web-resource-name>
            <url-pattern>/text/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-script</role-name>
          </auth-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>JMX Proxy interface</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-jmx</role-name>
          </auth-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Status interface</web-resource-name>
            <url-pattern>/status/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-gui</role-name>
             <role-name>manager-script</role-name>
             <role-name>manager-jmx</role-name>
             <role-name>manager-status</role-name>
          </auth-constraint>
        </security-constraint>
      
      

      The Tomcat 7 version of the manager application deployment descriptor contains a <security-constraint> section for each of the four possible ContactPaths (as per Manager Application section of the Tomcat Migration Guide).

      Add a <user-data-constraint> with a <transport-guarantee> of CONFIDENTIAL for the desired ContactPaths to to enable port-forwarding to port 8443:

        <!-- Define a Security Constraint on this Application -->
        <!-- NOTE:  None of these roles are present in the default users file -->
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>HTML Manager interface (for humans)</web-resource-name>
            <url-pattern>/html/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-gui</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Text Manager interface (for scripts)</web-resource-name>
            <url-pattern>/text/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-script</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>JMX Proxy interface</web-resource-name>
            <url-pattern>/jmxproxy/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-jmx</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Status interface</web-resource-name>
            <url-pattern>/status/*</url-pattern>
          </web-resource-collection>
          <auth-constraint>
             <role-name>manager-gui</role-name>
             <role-name>manager-script</role-name>
             <role-name>manager-jmx</role-name>
             <role-name>manager-status</role-name>
          </auth-constraint>
          <user-data-constraint>
              <transport-guarantee>CONFIDENTIAL</transport-guarantee>
          </user-data-constraint>
        </security-constraint>
      
      
  2. Verify SSL has been enabled for the Tomcat manager application.
  3. Restart Tomcat and verify SSL has been enabled for the Tomcat manager application: http://localhost:8080/manager/html/

    Tomcat manager authentication prompt

    Troubleshooting tips

    • Check the XML syntax in web.xml to make sure it is well-formed and without error.
    • Did you specify a <transport-guarantee> of CONFIDENTIAL?
    • Did you restart Tomcat after you made your changes to web.xml?

Resources

Blocking Non-Essential Port Access At The Firewall

Rationale

Port Tinkering

  1. Shutdown Tomcat without using the $CATALINA_HOME/bin/shutdown.sh script.
  2. Make sure Tomcat is running and then type the following in your terminal window:

    $ telnet localhost 8005
    

    When prompted, issue Tomcat the shutdown command by typing SHUTDOWN:

    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    SHUTDOWN
    

    What happened when you issued the SHUTDOWN command via telnet? Is this what you expected?

For running the TDS, keep in mind the following:

Resources

Restricting Access To The TDS By Remote IP Address Or Host

Tomcat Valves

A valve element represents a component that will be inserted into the request processing pipeline for the associated Catalina container.

Rationale

Examples

  1. Using the RemoteAddrValve to restrict access based on IP addresses.
  2. <!-- This example denies access based on IP addresses -->
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
           deny="128\.117\.47\.201,128\.107\.157\.210,96\.33\.56\.215" />
    
  3. Using the RemoteHostValve to restrict access based on resolved host names.
  4. <!-- This example denies access based on host names -->
    <Valve className="org.apache.catalina.valves.RemoteHostValve"
               deny="www\.badguys\.com,www\.bandwidthhog\.net" />
    
  5. Using wildcard characters.
  6. <!-- Wildcard characters can with the both valves -->
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
           deny="128\.117\.47\..*" />
    
  7. Using the RemoteAddrValve to limit access to a specific range of IP addresses.
  8. <!-- This example only allows the specified IPs to access  -->
    <Valve className="org.apache.catalina.valves.RemoteAddrValve"
              allow="128\.117\.140\..*" />
    

Resources

Securing the Tomcat manager Application

Changes to the manager application

The manager application URLs and roles has been re-structured. See the Tomcat Migration guide for more information.

Rationale

Resources

Reverse Proxy

Rationale

Resources

Running Tomcat with a Security Manager

Rationale

Resources

Protecting the Tomcat SHUTDOWN Port

SHUTDOWN on port 8005

Remove Tomcat Version String From HTTP Error Messages

Tomcat Version Information

  1. Unpack catalina.jar
  2. $ cd $CATALINA_HOME/lib
    $ jar xf catalina.jar org/apache/catalina/util/ServerInfo.properties
    
  3. Update ServerInfo.properties by changing server.info line to server.info=Apache Tomcat. Repackage catalina.jar
  4. $ jar uf catalina.jar org/apache/catalina/util/ServerInfo.properties
    
  5. Remove the $CATALINA_HOME/lib/org directory created when extracting the ServerInfo.properties file)
  6. $ rm -r org
    

THREDDS This document is maintained by Unidata. Send comments to THREDDS support.