Simple Tomcat-SSL integration and DN-based authentication

From EGEE-see WIki

Jump to: navigation, search

This is a simple description of tomcat-SSL integration and DN-based authentication without installing any of middleware components. It can be very useful to those who want to create web applications under tomcat which will be used by different users that should have different access permissions to varioous structural parts of the application (just the specific roles or users can see/change parts of the application).

The described setup uses JDK 5.0 update 12 and tomcat 5.0.28, but it should work with other versions as well. Also, I installed it on SL3 and SL4 without problems. In this example I will be using tomcat tarball from Apache web site, but everything also works well if tomcat is installed by RPM from a repository. In the description I will use $CATALINA_HOME to refer to directory into which you have installed tomcat 5.

Contents

Java installation

Java JDK 5.0 is available on http://java.sun.com/javase/downloads/index_jdk5.jsp (I have used JDK 5.0 update 12). After rpm installation

  $ rpm -ivh jdk-1_5_0_12-linux-i586.rpm

JAVA variables should be set. I prefer to put the following variables in /etc/bashrc file, to be available host-wide (adapt accordingly if you plan to use shell other than bash):

  export JAVA_BINDIR=/usr/java/jdk1.5.0_12/bin
  export JAVA_HOME=/usr/java/jdk1.5.0_12
  export JDK_HOME=/usr/java/jdk1.5.0_12
  export JRE_HOME=/usr/java/jdk1.5.0_12
  export PATH=$PATH:/usr/java/jdk1.5.0_12/bin

Tomcat installation

From tomcat web page http://tomcat.apache.org/ you can download the tomcat tarball. I prefer to untar it in /usr/local directory:

  $ cd /usr/local/
  $ tar zxvf /root/jakarta-tomcat-5.0.28.tar.gz

After this, tomcat user and group should be created (RPM installation would do this through the postinstall script - check to be sure):

  $ groupadd tomcat
  $ useradd -g tomcat -c "Tomcat User" -d /usr/local/tomcat tomcat

Do not forget to disable login for the tomcat account. The easiest way to do it is to change * to x in the second field of tomcat line in /etc/passwd file, e.g. to change the line similar to the one below

  tomcat:*:507:501:Tomcat User:/usr/local/tomcat:/bin/bash 

to be

  tomcat:x:507:501:Tomcat User:/usr/local/tomcat:/bin/bash

It is convenient to create a symbolical link for tomcat without a reference to its precise version:

  $ ln -s /usr/local/jakarta-tomcat-5.0.28 /usr/local/tomcat/tomcat5

It is also necessary to change the ownership of the tomcat directory

  $ chown -R tomcat:tomcat /usr/local/tomcat/
  $ chown -R tomcat:tomcat /usr/local/jakarta-tomcat-5.0.28/

In addition to this, some shell variables and aliases should be defined for tomcat user in its .bashrc file:

  $ su – tomcat
  $ cat .bashrc
  …
  export CATALINA_HOME=/usr/local/tomcat/tomcat5
  alias tomcat-start='$CATALINA_HOME/bin/startup.sh'
  alias tomcat-stop='$CATALINA_HOME/bin/shutdown.sh'
  …

Now using tomcat-start and tomcat-stop aliases the service can be started and stopped.

If tomcat is installed in this way value of $CATALINA_HOME variable is /usr/local/tomcat/tomcat5. If it is installed by RPM probably the value of this variable will be /var/lib/tomcat5 but this should be checked.

Tomcat-SSL integration

First you should install RPMs of all Certification Authorities accredited by the EUGridPMA. Installation instructions are available at http://grid-deployment.web.cern.ch/grid-deployment/lcg2CAlist.html. Now you should copy your host's private key and its certificate (files hostkey.pem and hostcert.pem from /etc/grid-security) in tomcat folder and change their ownership so that the tomcat user is able to read them. As root you can copy the files in $CATALINA_HOME/conf/ folder or create other for this purpose

  $ cp /etc/grid-security/hostkey.pem $CATALINA_HOME/conf/
  $ cp /etc/grid-security/hostcert.pem $CATALINA_HOME/conf/
  $ chown tomcat.tomcat $CATALINA_HOME/conf/*.pem

The next step is to copy several libraries from your local UI machine (or any other Grid-enabled machine) to $CATALINA_HOME/server/lib folder in order to integrate tomcat and SSL:

  /opt/glite/share/java/glite-security-trustmanager.jar 
  /opt/glite/share/java/glite-security-util-java.jar
  /opt/glite/share/glite-security-trustmanager/log4j-1.2.8.jar
  /opt/glite/share/glite-security-trustmanager/bcprov-jdk14-122.jar

(Another possibility is to install glite-security-trustmanager and glite-security-util-java RPM from the appropriate gLite repository: either gLite-3.0 repository, which is appropriate for SL3 and 2.4 Linux kernels, or gLite-3.1 WN repository, which is appropriate for SL4 and 2.6 Linux kernels.)

The optional step is to customize what will be logged by the tomcat. In order to do this, $CATALINA_HOME/conf/log4j-trustmanager.properties file should be adjusted. I suggest the following setup:

  $ cat $CATALINA_HOME/conf/log4j-trustmanager.properties
  # the default logger level is set to INFO
  # possible values are: DEBUG, INFO, WARN, ERROR and FATAL
  # (DEBUG shows the maximum information, FATAL least)
  log4j.logger.org.glite.security=INFO, fileout
  log4j.appender.fileout=org.apache.log4j.RollingFileAppender
  # the OUTPUT FILE for the logging messages
  log4j.appender.fileout.File=${catalina.base}/logs/glite-securitytrustmanager.log
  # define max file size for the debug file
  log4j.appender.fileout.MaxFileSize=100KB
  # Keep one backup file
  log4j.appender.fileout.MaxBackupIndex=1       
  log4j.appender.fileout.layout=org.apache.log4j.PatternLayout
  # define the pattern of the messages
  log4j.appender.fileout.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2} %x - %m%n
  # this also outputs the method name, but is very slow
  #log4j.appender.fileout.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2} %M %x - %m%n

In the tomcat configuration file $CATALINA_HOME/conf/server.xml that you will use, in order to enable tomcat-SSL integration and DN-based authentication the <Connector> element should look similar to the following:

  <Connector port="8443"
     maxThreads="150"
     minSpareThreads="25"
     maxSpareThreads="75"
     enableLookups="false"
     disableUploadTimeout="true"
     acceptCount="100"
     debug="0"
     scheme="https"
     secure="true"
     clientAuth="true"
     sslProtocol="TLS"
     log4jConfFile="/usr/local/tomcat/tomcat5/conf/log4j-trustmanager.properties"
     sslCAFiles="/etc/grid-security/certificates/*.0"
     crlFiles="/etc/grid-security/certificates/*.r0"
     sslKey="/usr/local/tomcat/tomcat5/conf/hostkey.pem"
     sslCertFile="/usr/local/tomcat/tomcat5/conf/hostcert.pem"
     sSLImplementation="org.glite.security.trustmanager.tomcat.TMSSLImplementation" />

Here you should change paths of log4jConfFile, sslKey and sslCertFile to point to the appropriate files.

Tomcat-SSL authentication

In order for this to work, tomcat should be configured to support container-managed security, by connecting to an existing "database" of DNs and user roles. For that I will use Realm (MemoryRealm). A Realm is a "database" of usernames and passwords that identify valid users of a web application (or a set of web applications), plus an enumeration of the list of roles associated with each valid user. You can think of roles to be similar to groups in Unix-like operating systems, because access to specific web application resources is granted to all users possessing a particular role (rather than enumerating the list of associated usernames). A particular user/DN can have any number of roles associated with its username. In the tomcat configuration file $CATALINA_HOME/conf/server.xml Realm element should be included in the following way:

  <Realm className="org.apache.catalina.realm.MemoryRealm" />

At the startup time, Realm (MemoryRealm) loads information about all users and their corresponding roles from an XML document (by default, this document is loaded from $CATALINA_HOME/conf/tomcat-users.xml). Be aware that the changes to the data in this file are not recognized until tomcat is restarted. Users and their roles in $CATALINA_HOME/conf/tomcat-config.xml can be added like it is done in the following example:

  <?xml version='1.0' encoding='utf-8'?>
  <tomcat-users>
     <role rolename="MyRole"/>
     <user username="CN=Dusan Vudragovic, O=Institute of Physics Belgrade, 
                       O=People, DC=SEE-GRID, DC=ORG" password="" roles="MyRole"/>
  </tomcat-users>

After the change to this file, as already mentioned, it is necessary to restart tomcat.

To restrict access to specified resources (servlets, JSPs, or HTML pages) in your web application, security constraints to those resources must be applied. You should define to which resources in your web application the security constraints should be applied. This is done in web.xml (web.xml is deployment descriptor file; it is held in the application's WEB-INF directory and it defines a number of parameters that are used when the web application is deployed into the Tomcat Servlet/JSP container) file by using the <url-pattern> element that is nested inside the <web-resource-collection> element. The <url-pattern> can refer to directory, filename, or <servlet-mapping>. Alternatively, to apply the security constraints to the entire web application, use the entry <url-pattern>/</url-pattern>. Then, define the HTTP method(s) (GET or POST) that the security constraints apply to by defining the <http-method> element that is nested inside the <web-resource-collection> element. Use separate <http-method> elements for each HTTP method. At the end you should define which roles should have an access. You can use the following example as a template

  <security-constraint>
     <web-resource-collection>
        <web-resource-name>
           Protected area
        </web-resource-name>
        <!-- This would protect the entire site -->
        <url-pattern>
           /
        </url-pattern>
        <!-- If you list http methods, only those methods are protected -->
        <http-method>
           DELETE
        </http-method>
        <http-method>
           GET
        </http-method>
        <http-method>
           POST
        </http-method>
        <http-method>
           PUT
        </http-method>
     </web-resource-collection>
     <auth-constraint>
        <!-- Roles that have access -->
        <role-name>
           MyGroup
        </role-name>
     </auth-constraint>
  </security-constraint>
  <!-- BASIC authentication -->
  <login-config>
     <auth-method>
        CLIENT-CERT
     </auth-method>
     <realm-name>
        tomcat-users
     </realm-name>
  </login-config>
  <!-- Define security roles -->
  <security-role>
     <description>
        MyRole role
     </description>
     <role-name>
        MyRole
     </role-name>
  </security-role>

At the end, of course, restart of tomcat is necessary.

Suggestions and comments can be sent to Dusan Vudragovic (dusan at cern.ch).

Personal tools