The Shibboleth IdP V3 software has reached its End of Life and is no longer supported. This documentation is available for historical purposes only. See the IDP4 wiki space for current documentation on the supported version.
Jetty93
Using Jetty 9.3
These pages are examples and do not reflect any normative requirements or assumptions on the part of the IdP software and may be a mix of suggestions from both the project team and deployers. You should take any of this advice with a grain of local salt and consider general security/deployment considerations appropriate to the use of web software in your local environment.
The official information about containers and versions we support is solely maintained on the SystemRequirements page. If you wish to operate without complete responsibility for your Java servlet container, you may consider the Windows package we provide that includes an embedded container.
The following conventions are used this document:
- /opt/shibboleth-idp is used to indicate that an absolute path to the IdP installation directory is required
idp.home
refers to the IdP installation directory (as specified during the installation process)JETTY_HOME
refers to the location of the Jetty installation (jetty-dist-$VERSION)JETTY_BASE
refers to the directory containing your deployment-specific Jetty configuration files- All paths are relative to
JETTY_BASE
unless otherwise noted
We strongly recommend placing all IdP-specific Jetty configuration under JETTY_BASE
to facilitate Jetty upgrades.
Version Notes
The latest stable version should be used.
Note that Java 8 is required for this version.
A bug was found, reported, and fixed that requires a workaround when changing the TLS keystore type to PKCS12. Our documentation accounts for this bug.
This release includes a number of configuration changes from earlier releases, mostly refactoring and property renaming. Starting from scratch is advisable if upgrading from 9.2.
JETTY_BASE Layout
A typical JETTY_BASE
directory for the IdP webapp contains the following files, each of which will be described in the following sections.
- start.ini
- start.d/http.ini
- start.d/https.ini
- start.d/ssl.ini
- etc/jetty-ssl-context.xml
- etc/jetty-requestlog.xml (optional)
- etc/jetty-rewrite.xml (optional)
- lib/ext/jetty9-dta-ssl-1.0.0.jar (optional)
lib/logging/jcl-over-slf4j-1.7.7.jar (optional)
lib/logging/logback-access-1.1.2.jar (optional)
lib/logging/logback-classic-1.1.2.jar (optional)
lib/logging/logback-core-1.1.2.jar (optional)
- lib/logging/slf4j-api-1.7.12.jar (optional)
- resources/logback.xml (optional)
resources/logback-access.xml (optional)
- webapps/idp.xml
- tmp (optional)
Required Configuration
Configure Jetty Modules and JVM Settings
File(s): start.ini
Create a JETTY_BASE/start.ini file with the following contents.
# Required Jetty modules --module=server --module=deploy --module=annotations --module=resources --module=logging --module=requestlog --module=servlets --module=jsp --module=jstl --module=ext --module=plus --module=rewrite # Allows setting Java system properties (-Dname=value) # and JVM flags (-X, -XX) in this file # NOTE: spawns child Java process --exec # Bypass file validation for the SSL module, to work around a bug in Jetty 9.3.X --skip-file-validation=ssl # Uncomment if IdP is installed somewhere other than /opt/shibboleth-idp #-Didp.home=/path/to/shibboleth-idp # Alternate garbage collector that reduces memory needed for larger metadata files -XX:+UseG1GC # Maximum amount of memory that Jetty may use, at least 1.5G is recommended # for handling larger (> 25M) metadata files but you will need to test on # your particular metadata configuration -Xmx1500m # Maximum amount of memory allowed for the JVM permanent generation (Java 7 only) -XX:MaxPermSize=128m
Configure HTTP Connectors
File(s): /opt/shibboleth-idp/credentials/idp-browser.p12, etc/jetty-ssl-context.xml, start.d/http.ini, start.d/https.ini, start.d/ssl.ini
Jetty listens on ports 8080 and 8443 for user-facing web traffic by default. In order to serve requests at the default HTTP/HTTPS ports one of the following is required.
- Change the ports to 80/443 in the jetty property files and use the setuid extension to support listening on the privileged ports as a non-root user.
- Use a port forwarding approach (load balancer, iptables rules, etc).
Copy the following files from JETTY_HOME/demo-base/start.d
to JETTY_BASE/start.d
:
- http.ini
- https.ini
- ssl.ini
If you elect to change the default listening ports, modify the jetty.http.port
property in http.ini and jetty.ssl.port
in https.ini accordingly.
Modify ssl.ini so that it contains the following properties. Note that these are named differently from the equivalent properties used in 9.2.
jetty.sslContext.keyStorePath=/opt/shibboleth-idp/credentials/idp-browser.p12 jetty.sslContext.keyStoreType=PKCS12 jetty.sslContext.keyStorePassword=thepasswordgoeshere
If you have deployed the IdP to an alternate location, change the keystore path accordingly. The idp-browser.p12 file is a PKCS12 file containing the X.509 certificate and private key used to secure the HTTPS channel that users access during authentication and other browser-based message exchanges involving the IdP. This is generally the one you get from a browser-compatible CA.
Create the following file using the example below (it's based on the version that comes with Jetty):
- JETTY_BASE/etc/jetty-ssl-context.xml
Configure IdP Context Descriptor
File(s): webapps/idp.xml
In order to deploy the IdP, Jetty must be informed of the location of the IdP war file. This file is called a context descriptor and the recommended content is provided below. Since the following example relies upon the idp.home System Property being set, it must either be defined in start.ini, or included in the command line string used to start Jetty.
Note this file controls the context path to which the application is deployed, which is /idp in the following configuration block.
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="war"><SystemProperty name="idp.home"/>/war/idp.war</Set> <Set name="contextPath">/idp</Set> <Set name="extractWAR">false</Set> <Set name="copyWebDir">false</Set> <Set name="copyWebInf">true</Set> </Configure>
Recommended Configuration
Jetty Logging
File(s): etc/jetty-requestlog.xml, resources/logback.xml, resources/logback-access.xml
The recommended approach is to use logback for all Jetty logging. The logback and slf4j libraries are needed to support this configuration and must be copied into JETTY_BASE/lib/logging
.
- From the slf4j distribution, copy in slf4j-api-version.jar
- From the logback distribution, copy in logback-classic-version.jar, logback-core-version.jar, and logback-access-version.jar
Configure Jetty to use logback for request logging by creating JETTY_BASE/etc/jetty-requestlog.xml with the following content:
Configure logging policy for Jetty internals logging and request logging. Sample logback configuration files are provided for convenience.
Temporary Files
Jetty will use /tmp
as a staging area for unpacking the warfile, and if you have cron jobs sweeping that for old files, your IdP can be disrupted. You will probably want to create JETTY_BASE/tmp
, and add the following configuration directive to JETTY_BASE/start.ini:
-Djava.io.tmpdir=tmp
Disable Directory Indexing
Jetty has vulnerabilities related to directory indexing (sigh) so we suggest disabling that feature at this point. There are a few different ways this can be done (see https://webtide.com/indexing-listing-vulnerability-in-jetty/), but one method that's fairly self-contained within the IdP footprint is to modify web.xml (i.e. copy the original version from idp.home/dist/webapp/WEB-INF/web.xml to idp.home/edit-webapp/WEB-INF/web.xml) and then rebuild the war file.
You can place it above the existing <servlet>
elements in the file.
Optional Configuration
Supporting SOAP Endpoints
File(s): /opt/shibboleth-idp/credentials/idp-backchannel.p12, etc/jetty-backchannel.xml, modules/backchannel.mod, start.d/backchannel.ini
The use of the back-channel is discussed in the SecurityAndNetworking topic, and you should review that to understand whether or not you need to support this feature.
If you do need this support, these connections generally require special security properties that are not appropriate for user-facing/browser use. Therefore an additional endpoint must be configured.
- Copy the jetty9-dta-ssl-1.0.0.jar (asc) plugin to
JETTY_BASE/lib/ext
Create JETTY_BASE/modules/backchannel.mod:
[name] backchannel [depend] server [xml] etc/jetty-backchannel.xml
Create JETTY_BASE/start.d/backchannel.ini:
--module=backchannel jetty.backchannel.port=8443 jetty.backchannel.sslContext.keyStorePath=/opt/shibboleth-idp/credentials/idp-backchannel.p12 jetty.backchannel.sslContext.keyStoreType=PKCS12 jetty.backchannel.sslContext.keyStorePassword=passwordgoeshere
Create JETTY_BASE/etc/jetty-backchannel.xml:
Offloading TLS
There may be situations where you wish to "offload" TLS to a load balancer or http proxy, a setup looking something like:
---(https)---> Apache/LB ---(http)---> Jetty/Shibboleth IdP
Attempting a user login service request with the default Jetty configuration may result in an error similar to "SAML message intended destination endpoint https://hostname... did not match the recipient endpoint http://hostname...".
Jetty can be configured to consume the 'x-forwarded-proto' HTTP header to override the connection protocol originating at the load balancer, instead respecting the protocol being used between the client and the load balancer, communicated in the x-forwarded-proto header. The Proxy / Load Balancer Configuration section of the Jetty documentation provides instruction on the required configuration.
The following example achieves that using Apache httpd's mod_proxy
and mod_headers
. The last line allows passing of REMOTE_USER
through to the IdP, useful for external authentication in a browser or ECP.
RequestHeader set X-Forwarded-Proto "https" env=HTTPS ProxyPass /idp http://localhost:8080/idp connectiontimeout=5 timeout=15 RequestHeader set REMOTE-USER %{REMOTE_USER}s
Supporting X-Forwarded-For
If you are running the Jetty engine behind a proxy or load balancer Jetty 9.3 has built-in support for forwarding the client address and other details via headers.
As with any proxied deployment, you MUST take care to lock down the path between the proxy and the Jetty server, and the proxy MUST have support for sanitizing and preventing any client attempt to smuggle and hijack those headers. Failure to do so will result in a variety of security compromises. There are many other considerations to proxying far beyond the scope of this document.
- Copy the file JETTY_BASE/etc/jetty.xml to JETTY_HOME/etc/jetty.xml
- Edit the file in JETTY_HOME/etc/jetty.xml, locate the:
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
section and add:
<Set name="outputBufferSize">32768</Set> <Set name="requestHeaderSize">8192</Set> <Set name="responseHeaderSize">8192</Set> <Call name="addCustomizer"> <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer" /></Arg> </Call>
<Call name="addCustomizer"> <Arg> <New class="org.eclipse.jetty.server.ForwardedRequestCustomizer" > <Set name="forwardedForHeader">X-MyCustom-Header</Set> </New> </Arg> </Call>