Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Note that while Jetty 9.x theoretically allowed for configuration directly within its distribution directory, Jetty 10 requires the recommended home/base split; the distribution itself is always considered read-only.

The examples on this page are based
Info
Note

Do NOT skip the Getting Started section. All of the example material depends on the use of a number of files that are not included in the Jetty distribution but are part of a project we store in our Git repositor, cloneable from https://git.shibboleth.net/git/java-idp-jetty-base. The examples won't work as is without starting from that complete set of example files. The “10” branch contains the files used in this material.

We may publish it in a more "official" capacity in the future, but for now it's simply an example to build on. It includes some custom Jetty "modules" that help support a simpler configuration.

Version Notes

The latest stable version of Jetty should be used.

Jetty 10 requires Java 11 or later, and also supports Java 17.

...

have to be downloaded and installed to create an initial jetty-base directory tree.

Version Notes

The latest stable version of Jetty should be used.

Jetty 10 requires Java 11 or later, and also supports Java 17.

Starting from scratch is advisable if upgrading from 9.x, although the changes from 9.4 are not all that extensive except in the area of logging.

Getting Started

The examples on this page are based on the use of a number of files that are not included in the Jetty distribution but are part of the java-idp-jetty-base project we store in our Git repository. The examples won't work as is without starting from that complete set of example files. The 10 branch contains the files used in this material.

The following commands (Linux-style) will get you to the starting point assumed from the examples in this page:

Code Block
$ git clone https://git.shibboleth.net/git/java-idp-jetty-base
$ cd java-idp-jetty-base
$ git checkout 10
$ cp -r src/main/resources/jetty-base /my/desired/location/

Required Configuration

The bulk of the configuration is established by setting properties in "ini" files that are combined in the start.d directory. Some of the properties are defined by Jetty and configure built-in modules and others are specific to the IdP and configure the custom modules we created.

The start.d/idp.ini file that configures the “idp” module contains not only the bulk of the basic settiings settings needed but is a place you can add your own settings to control JVM startup, change which logging module is used, etc.

Configure Jetty Modules and JVM Settings

File(s): start.d/idpstart.ini

...

start.ini
Code Block
languagetext
# Any other required Jetty modules...
 
# Allows setting Java system properties (-Dname=value)
# and JVM flags (-X, -XX) in this file
# NOTE: spawns child Java process
--exec

# Uncomment if IdP is installed somewhere other than /opt/shibboleth-idp
#-Didp.home=/path/to/shibboleth-idp

# 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. If MDQ metadata on demand is used,
# requirements may be much lower.
-Xmx1500m

# Prevent blocking for entropy.
-Djava.security.egd=file:/dev/urandom

# Set Java tmp location
-Djava.io.tmpdir=tmp

...

One challenge remains that if you want to use standard ports, you would need to pick one of these options to avoid running as root:

  1. Use the setuid extension to support listening on the privileged ports as a non-root user.

  2. Use a port forwarding approach (load balancer, iptables rules, etc).

  3. Use POSIX capabilities to allow use of priviledged ports by an unpriviledged process, e.g. when using systemd by setting AmbientCapabilities=CAP_NET_BIND_SERVICE 

idp.ini
Code Block
# --------------------------------------- 
# Module: idp
# Shibboleth IdP
# --------------------------------------- 
--module=idp

## Keystore file path (relative to $jetty.base)
jetty.sslContext.keyStorePath=../credentials/idp-userfacing.p12
## Truststore file path (relative to $jetty.base)
jetty.sslContext.trustStorePath=../credentials/idp-userfacing.p12

## Keystore type
jetty.sslContext.keyStoreType=PKCS12
## Truststore type and provider
jetty.sslContext.trustStoreType=PKCS12

## Keystore password
jetty.sslContext.keyStorePassword=changeit
## Truststore password
jetty.sslContext.trustStorePassword=changeit
## KeyManager password
jetty.sslContext.keyManagerPassword=changeit

## Deny SSL renegotiation
jetty.sslContext.renegotiationAllowed=false

## Connector host/address to bind to
# jetty.ssl.host=0.0.0.0

## Connector port to listen on
jetty.ssl.port=443

# Allows use of default IdP command line tools.
jetty.http.host=127.0.0.1
jetty.http.port=80

...

Note

Of course, this is completely insecure. If you want to be appropriately careful, you can compare the 2 jars it downloads to the signed copies available from Maven Central and check their signatures.Note also that Jetty relies on (at time of writing) alpha versions. In theory it is possible to override Jetty’s use of slf4j and logback 2.x and use the 1.x versions. Supposedly the only changes to 2.x involve the JPMS, which the IdP does not support and does not require.available from Maven Central and check their signatures.

If you find that Jetty isn’t locating the proper logging configuration or producing the expected output, you may need to add this to your startup:

Code Block
-Dlogback.configurationFile=resources/logback.xml

The next step is to instruct Jetty to produce its access/request log using the same logging APIs it uses for everything else. This is not a Jetty module at this point, so requires the etc/jetty-requestlog.xml file we provide:

etc/jetty-requestlog.xml
Code Block
languagexml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">

<!-- =============================================================== -->
<!-- Configure the Jetty Request Log                                 -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <!-- =========================================================== -->
  <!-- Configure Request Log for Server                            -->
  <!-- Use RequestLogHandler for a context specific RequestLog     -->
  <!-- =========================================================== -->
  <Set name="RequestLog">
    <New id="RequestLog" class="org.eclipse.jetty.server.CustomRequestLog">
      <!-- Writer -->
      <Arg>
        <New class="org.eclipse.jetty.server.Slf4jRequestLogWriter" />
      </Arg>

      <!-- Format String -->
      <Arg>
        <Property name="jetty.requestlog.formatString" deprecated="jetty.customrequestlog.formatString">
          <Default>
            <Get class="org.eclipse.jetty.server.CustomRequestLog" name="EXTENDED_NCSA_FORMAT"/>
          </Default>
        </Property>
      </Arg>
    </New>
  </Set>
</Configure>

...

Note

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. You very likely don’t, and if you do, it’s worth exploring steps you might take to get out of needing it. The IdP fully supports all of the necessary features to secure requests made to the regular port using signed messages.

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.

  1. The jetty94-dta-ssl-1.0.0.jar (asc) plugin (the name hasn’t changed because Jetty 10 supports the same extension API) can be placed in JETTY_BASE/lib/ext

  2. We provide a backchannel module to control the feature and turn it on or off.

  3. Adjust JETTY_BASE/start.d/idp-backchannel.ini as required:

    Code Block
    # --------------------------------------- 
    # Module: idp-backchannel
    # Shibboleth IdP Dedicated SOAP Connector
    # --------------------------------------- 
    --module=idp-backchannel
    
    ## Backchannel connector port to listen on
    # idp.backchannel.port=8443
    
    ## Backchannel keystore file path (relative to $jetty.base)
    # idp.backchannel.keyStorePath=../credentials/idp-backchannel.p12
    
    ## Backchannel keystore password
    # idp.backchannel.keyStorePassword=changeit
    
    ## Backchannel keystore type
    # idp.backchannel.keyStoreType=PKCS12
    
  4. Modify JETTY_BASE/etc/idp-backchannel.xml if desired. You get more control over the TLS settings if you need them, but normally this file is just used to plug in the properties we support from the ini file.

Other Modules

Jetty has a ton of advanced and optional functionality available in the form of modules that can be enabled selectively. They don't function in the way Apache modules do, but they're basically packaged "example" configuration files that will get copied from JETTY_HOME into JETTY_BASE when you need them and you get "just" the minimum files needed to support the feature but keep future upgrades simple.

...

If you are running the Jetty engine behind a proxy or load balancer Jetty has built-in support for forwarding the client address and other details via headers using its http-forwarded module, and after enabling it as above you can edit the resulting properties file to configure it.

Note that this example applies the forwarding rule to all ports, so if you also operate the server on other ports, those must also be proxied/protected or this will lead to exposures due to clients having the ability to smuggle in a false client address.

If your IdP is behind Apache, you probably only need it to listen for HTTP traffic locally. At present, this involves commenting out or removing two lines from the [depend] section of idp.mod: the lines containing https and ssl.

...