Tomcat and TDS Security

Why Is This Important?

Be afraid

Keeping Software Versions Up-To-Date

Rationale

Resources

Tomcat Process User/Group and ${tomcat_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.

Creating a dedicated Tomcat user/group & setting permissions in ${tomcat_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 ${tomcat_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 ${tomcat_home}
  4. Change the user/group ownership ${tomcat_home} to the tomcat user and tomcat group:

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

    Change the user/ownership of the ${tomcat_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 ${tomcat_home}/bin and ${tomcat_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

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 (in the LockOutRealm, right above the Host element) and comment it out:

    <!-- Use the LockOutRealm to prevent attempts to guess user passwords
         via a brute-force attack -->
    <Realm className="org.apache.catalina.realm.LockOutRealm">
      <!-- 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"/>
         -->
    </Realm>
    
    <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true">
    

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

    <!-- Use the LockOutRealm to prevent attempts to guess user passwords
         via a brute-force attack -->
    <Realm className="org.apache.catalina.realm.LockOutRealm">
      <!-- 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"/>
         -->
          <Realm className="org.apache.catalina.realm.MemoryRealm" 
                 digest="SHA" />
    </Realm>
    
    <Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true">
    
  3. Create a SHA encrypted version of your password.
  4. Tomcat provides a script (${tomcat_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/workshop/apache-tomcat-7.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>
    

    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.

  7. Verify digest passwords have been successfully enabled in Tomcat.
  8. 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

  • 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 ${tomcat_home}/conf should we edit to to enable SSL?

    Open ${tomcat_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/workshop/apache-tomcat-7.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/workshop/apache-tomcat-7.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:

    $ ${tomcat_home}/bin/shutdown.sh
    $ ${tomcat_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 :::8443                    :::*                        LISTEN
    

    Troubleshooting

    • 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 ${tomcat_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 ${tomcat_home}/conf/server.xml or ${tomcat_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 ${tomcat_home}/webapps, and view the file:

    $ cd /home/tds/workshop/apache-tomcat-7.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>
        </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 ${tomcat_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 ${tomcat_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 ${tomcat_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

    • 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

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

Blocking Non-Essential Port Access At The Firewall

Rationale

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

Reverse Proxy

Rationale

Resources

Running Tomcat with a Security Manager

Rationale

Resources

Protecting the Tomcat SHUTDOWN Port

SHUTDOWN on port 8005