Zum Ende der Metadaten springen
Zum Anfang der Metadaten

Back to the beginning of this guide

This Guide assumes
  • A fresh, minimal (e.g. netiso) install of Debian 8 ("Jessie") with no "tasks" except openssh-server
    • Ubuntu 16.0.4 LTS ("xenial") works the same, the only difference being not needing the backports repository to get Java 8.
  • Accessed via SSH or the console (no X11 required nor recommended),
  • With outgoing (ports TCP/80 and TCP/443) network access
    • Port 80 for Debian APT updates and for downloading signed eduID.at Metadata
    • Port 443 for downloads of the Shibboleth IDP software (i.e., this could be deactivated after installation)
  • Internally the IDP will also need to connect to your LDAP Directory Servers
    • So either the standard port TCP/389 for LDAP(+STARTTLS),
    • or port TCP/636 for LDAPS (which which no formal specification exists),
    • or maybe the "global catalog" port of your Microsof Active Directory (if you need to access that).
  • And incoming (port TCP/443 and TCP/8443 only, no port 80 necessary nor recommended) network access,
    • also incoming port 22 for access only from a management network, if the server is managed via SSH,
  • All commands in this guide are to be issued by user root (uid=0), unless otherwise noted
  • The shell to use is /bin/bash (you can get fancy after finishing the install/configuration)
Table of contents for step 1

Install pre-requisites

Add the Backports repository for Debian 8 to get Java/OpenJDK version 8 and update the packages index (skip this step for Ubuntu 16.04 TLS):

echo "deb http://http.debian.net/debian jessie-backports main" > /etc/apt/sources.list.d/backports.list
apt-get update

Install required and recommended packages, replacing vim with your $EDITOR of choice (e.g. emacs-nox or nano, both of which also have syntax highlighting, which helps when editing XML files). Only Java will be installed from Backports (-t target release). For Ubuntu 16.04 TLS just leave out the "-t jessie-backports" parameter and install java from the main repository (like all the other packages here):

apt-get install vim less openssl unzip curl expat multitail gnupg # adjust to taste
apt-get install -t jessie-backports openjdk-8-jre-headless
apt-get install tomcat8 libservlet3.1-java
/etc/init.d/tomcat8 stop

Post-install fix-ups

Redirect requests to Tomcat's web root ("/") to a URL of your choice, e.g. your institutions home page, replacing "www.example.edu" belowThe Shibboleth IDP application by default will run at /idp, allowing you to easily add other content to the webserver outside of /idp, e.g. logos or CSS stylesheets without having them to integrate them with the "idp" context/application. The document root for that is in /var/lib/tomcat8/webapps/ROOT/ and nothing in the software (or during use of SAML) by default links to / of the server, so you can use that for locally hosted content without interfering with the IDP itself.

rm /var/lib/tomcat8/webapps/ROOT/index.html
echo '<% response.sendRedirect("http://www.example.edu"); %>' > /var/lib/tomcat8/webapps/ROOT/index.jsp

Activate the pre-configured authbind support for Tomcat, which allows to bind to privileged TCP ports but still run the application (here: Tomcat and the complete Java Virtual Machine) as non-root, i.e. with an unprivileged user account. The default authbind setting ("byuid", listing on "") does not work when IPv6 is enabled on the system, but authbind's "byport" works fine with both IPv4 and IPv6. So we add a file with the HTTPS port TCP/443 and change its owner to the user Tomcat is running as. The line also enabling port 80 is only for the IDP's command line utilities to work and this guide only makes port 80 available on the loopback network interface, i.e., port 80 is not and it should not be accessible from the outside!

sed -i -r 's/^#(AUTHBIND=).*/\1yes/' /etc/default/tomcat8
touch /etc/authbind/byport/443
chmod 500 /etc/authbind/byport/443
chown tomcat8 /etc/authbind/byport/443
cp -a /etc/authbind/byport/443 /etc/authbind/byport/80

You can verify that authbind works as intended using e.g. nc as a TCP server. Having user tomcat8 create a server listening on port 80 fails (first example), but running the same command with authbind should succeed:

su -m tomcat8 -c          "nc -l -p 443" # fails with "Permission denied"
su -m tomcat8 -c "authbind nc -l -p 443" # works, terminate nc with ctrl+c (^C)

Set JAVA_HOME for Tomcat and the shell (current and future ones):

sed -i -r 's|^(#JAVA_HOME.+)|\1\nJAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre|' /etc/default/tomcat8
eval $(echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre" | tee /etc/profile.d/java.sh)

Enable TLS/SSL

Create keypair and certificate chain

Create an RSA private key and CSR for the web server's TLS certificate, e.g.:

openssl req -new -newkey rsa:2048 -nodes -out webserver.csr -keyout webserver.key -new

Request a TLS certificate based on the CSR generated, e.g. from the ACOnet TCS. In the resulting email with the certificate there's also the CA chain file to use (e.g. called DigiCertCA.crt). Copy the certificate and CA file to the server you're installing the IDP on (where the private key should already be, having been generated there).

Convert the TLS/SSL keypair into PKCS12

Create and note down a random password for your PKCS#12 keystore that will hold the above created TLS/SSL keypair plus the CA chain file:

openssl rand -hex 12

Convert the recieved certificate, the locally generated private key and the certificate chain file into one password-protected PKCS#12 keystore file.
When asked for an "export password" set the previously generated (and noted down) password: 

openssl pkcs12 -export -in webserver.crt -inkey webserver.key -certfile DigiCertCA.crt -name "webserver" -out webserver.p12

Move the newly created keystore to its final location (we're chosing Tomcat's config directory) and set strict file system permissions on it:

mv webserver.p12 /etc/tomcat8/
chmod 640 /etc/tomcat8/webserver.p12
chgrp tomcat8 /etc/tomcat8/webserver.p12

Configure Tomcat Connector

Remove or comment out all other Connectors in /etc/tomcat8/server.xml, then add the two Connectors as per below, replacing keystorePass with the PKCS#12 keystore password generated earlier:

Start Tomcat, check for listening ports, and access https://webserver-fqdn/foo which should result in an HTTP Status 404 error (since /foo won't exist) but allows you to confirm a hopefully valid TLS/SSL webserver configuration. Perform the certificate/TLS configuration check with your graphical web browser on your own workstation, checking the green lock symbol in the location bar and verifying that your browser is happy with the HTTPS connection.

/etc/init.d/tomcat8 restart
netstat -lntp | fgrep java  # should show 443, and 80/8005 only on the loopback interface

Verify TLS/SSL

Maybe also validate the TLS/SSL configuration on the system itself with openssl:

openssl s_client -no_ssl2 -no_ssl3 -CApath /etc/ssl/certs/ -connect webserver-fqdn:443

Look for "Certificate chain" in the output from that command and verify that it looks something like the chain presented below. The CN in the subject of cert 0 will obviously differ, depending on your choice of CA or certificate product ("SSL Plus", "Unified Communications", "EV" etc.) the CA may also be different. A correct chain (and therfore PKCS#12 keystore) for TLS usage should contain all the certificates up until and excluding the root CA certificate. I..e, in the example below the certificate with CN=DigiCert Assured ID Root CA is not included in the chain sent from the server.

Certificate chain
 0 s:/C=AT/ST=Vienna/L=Wien/O=ACOnet/CN=webserver-fqdn
   i:/C=NL/ST=Noord-Holland/L=Amsterdam/O=TERENA/CN=TERENA SSL CA 3
 1 s:/C=NL/ST=Noord-Holland/L=Amsterdam/O=TERENA/CN=TERENA SSL CA 3
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Assured ID Root CA

In case of errors check /var/log/tomcat8/catalina.out

Tune log file creation

By default Tomcat logs additional (and duplicate) events to /var/log/tomcat8/catalina.$date.log and /var/log/tomcat8/localhost.$date.log, which we don't care for. So let's create a backup copy of Tomcat's logging.properties and replace its content with the minumum needed to get an access log comparable to Apache httpd in /var/log/tomcat8/access.log, writing Tomcat's stdout/stderr to /var/log/tomcat8/catalina.out (for debugging purposes).

/etc/init.d/tomcat8 stop
cp -a /etc/tomcat8/logging.properties /etc/tomcat8/logging.properties.orig
echo 'handlers = org.apache.juli.FileHandler, java.util.logging.ConsoleHandler
org.apache.juli.FileHandler.level = SEVERE
org.apache.juli.FileHandler.rotatable = false
org.apache.juli.FileHandler.directory = /dev
org.apache.juli.FileHandler.prefix = null
org.apache.juli.FileHandler.suffix =
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = org.apache.juli.FileHandler
' > /etc/tomcat8/logging.properties

Then comment out or delete the whole Valve element at the end of your /etc/tomcat8/server.xml, and replace it with the following one:

Then delete all Tomcat logs now and after a start only catalina.out (which we'll keep for debugging serious IDP startup problems) and (a bit later) access.log should be generated.

rm -f /var/log/tomcat8/*
/etc/init.d/tomcat8 start
multitail /var/log/tomcat8/*

Initial Tomcat server.xml

Example server.xml file

Find attachted to this page a minimal but working server.xml matching the above instructions. (In the next step you'll amend/replace server.xml again with a more complete version). You'll only need to replace the PKCS#12 keystore password (keystorePass attribute) with the "export password" you set previously, when you created the PKCS#12 keystore from the PEM-encoded key, certificate and CA chain certificate files.

  • Keine