Page tree
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 20 Next »

Using Jetty 9.2

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

There are no known issues with any specific Jetty 9.2 release. The latest stable version should be used.

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
  • etc/jetty-requestlog.xml (optional)
  • etc/jetty-ssl.xml
  • etc/jetty-https.xml
  • modules/http.mod (optional)
  • modules/https.mod
  • modules/ssl.mod
  • 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)

  • 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.

start.ini
# Required Jetty modules
--module=server
--module=deploy
--module=annotations
--module=resources
--module=logging
--module=requestlog
--module=https
--module=ssl
--module=servlets
--module=jsp
--module=jstl
--module=ext
--module=plus
 
# 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 512M is recommended
-Xmx512m
 
# Maximum amount of memory allowed for the JVM permanent generation
-XX:MaxPermSize=128m

Configure HTTP Connectors

File(s): /opt/shibboleth-idp/credentials/idp-browser.p12etc/jetty-ssl.xml, etc/jetty-https.xml, modules/http.mod (optional), modules/https.mod, modules/ssl.mod

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.

  1. Change the ports to 80/443 in jetty configuration files and 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).

Copy the following files from JETTY_HOME to JETTY_BASE:

  1. modules/https.mod
  2. modules/ssl.mod
  3. modules/http.mod (optional; needed if listening on "cleartext" HTTP port other than default 8080)

If you elect to change the default listening ports, modify the http.port property in http.mod and https.port in https.mod accordingly.

Add/update ssl.mod so that it contains the following lines.

jetty.keystore=/opt/shibboleth-idp/credentials/idp-browser.p12
jetty.keystore.type=PKCS12
jetty.keystore.password=thepasswordgoeshere

If you have deployed the IdP to an alternate location, change the path of jetty.keystore 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 files using the sample configurations that follow as a starting point.

  1. JETTY_BASE/etc/jetty-ssl.xml
  2. JETTY_BASE/etc/jetty-https.xml

jetty-ssl.xml
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <!-- ============================================================= -->
  <!-- TLS context factory without client auth                       -->
  <!-- ============================================================= -->
  <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
    <Set name="KeyStorePath"><Property name="jetty.keystore" /></Set>
    <Set name="KeyStoreType"><Property name="jetty.keystore.type" /></Set>
    <Set name="KeyStorePassword"><Property name="jetty.keystore.password" /></Set>
    <Set name="EndpointIdentificationAlgorithm"></Set>
    <Set name="NeedClientAuth">false</Set>
    <Set name="WantClientAuth">false</Set>
    <Set name="excludeProtocols">
      <Array type="String">
        <Item>SSLv3</Item>
      </Array>
    </Set>
    <Set name="IncludeCipherSuites">
      <Array type="String">
        <Item>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</Item>
        <Item>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</Item>
        <Item>TLS_RSA_WITH_AES_128_GCM_SHA256</Item>
        <Item>TLS_RSA_WITH_AES_256_GCM_SHA256</Item>
        <Item>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</Item>
        <Item>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</Item>
        <Item>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</Item>
        <Item>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</Item>
        <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</Item>
        <Item>TLS_RSA_WITH_AES_128_CBC_SHA256</Item>
        <Item>TLS_RSA_WITH_AES_256_CBC_SHA384</Item>
        <Item>TLS_RSA_WITH_AES_128_CBC_SHA</Item>
        <Item>TLS_RSA_WITH_AES_256_CBC_SHA</Item>
      </Array>
    </Set>
  </New>
 
  <!-- =========================================================== -->
  <!-- Create a TLS specific HttpConfiguration based on the        -->
  <!-- common HttpConfiguration defined in jetty.xml               -->
  <!-- Add a SecureRequestCustomizer to extract certificate and    -->
  <!-- session information                                         -->
  <!-- =========================================================== -->
  <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
    <Arg><Ref refid="httpConfig"/></Arg>
    <Call name="addCustomizer">
      <Arg><New class="org.eclipse.jetty.server.SecureRequestCustomizer"/></Arg>
    </Call>
  </New>
</Configure>
jetty-https.xml
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">

<!-- ============================================================= -->
<!-- Configure HTTPS connectors.                                   -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml.                                            -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
  <!-- ============================================================= -->
  <!-- Anonymous (no client TLS) HTTPS connector                     -->
  <!-- ============================================================= -->
  <Call id="httpsConnector" name="addConnector">
    <Arg>
      <New class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg>
        <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <Item>
              <New class="org.eclipse.jetty.server.SslConnectionFactory">
                <Arg name="next">http/1.1</Arg>
                <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
              </New>
            </Item>
            <Item>
              <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
              </New>
            </Item>
          </Array>
        </Arg>
        <Set name="host"><Property name="jetty.host" /></Set>
        <Set name="port"><Property name="https.port" /></Set>
        <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
        <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
        <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set>
        <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set>
        <Set name="acceptQueueSize"><Property name="https.acceptQueueSize" default="0"/></Set>
      </New>
    </Arg>
  </Call>
</Configure>

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. Note this file controls the context path to which the application is deployed, which is /idp in the following configuration block.

idp.xml
<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 logack for all Jetty logging. The logback and slf4j libraries are needed to support this configuration and must be copied into  JETTY_BASE/lib/logging.

  1. From the slf4j distribution, copy in slf4j-api-version.jar
  2. From the logback distribution, copy in logback-classic-version.jar, logback-core-version.jar, and logback-access-version.jar
  3. Configure Jetty to use logback for request logging by creating JETTY_BASE/etc/jetty-requestlog.xml with the following content:

    jetty-requestlog.xml
    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
    
    <!-- =============================================================== -->
    <!-- Configure the Jetty Request Log                                 -->
    <!-- =============================================================== -->
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
      <!-- =========================================================== -->
      <!-- Configure Request Log -->
      <!-- =========================================================== -->
      <Ref refid="Handlers">
        <Call name="addHandler">
          <Arg>
            <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler">
              <Set name="requestLog">
                <New id="RequestLogImpl" class="ch.qos.logback.access.jetty.RequestLogImpl">
                  <Set name="fileName"><Property name="jetty.base" default="." />/resources/logback-access.xml</Set>
                </New>
              </Set>
            </New>
          </Arg>
        </Call>
      </Ref>
    </Configure>
    
  4. Configure logging policy for Jetty internals logging and request logging. Sample logback configuration files are provided for convenience.

    logback.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration scan="true">
        <appender name="jetty" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <File>${jetty.base}/logs/jetty.log</File>
            
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${jetty.base}/logs/jetty-%d{yyyy-MM-dd}.log.gz</FileNamePattern>
            </rollingPolicy>
    
            <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
                <charset>UTF-8</charset>
                <Pattern>%date{HH:mm:ss.SSS} - %level [%logger:%line] - %msg%n</Pattern>
            </encoder>
        </appender>
      
        <root level="INFO">
            <appender-ref ref="jetty" />
        </root>
        <logger name="org.springframework" level="OFF" />
        <logger name="ch.qos.logback" level="WARN" />
    </configuration>
    logback-access.xml
    <configuration>
      <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />  
      <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${jetty.base}/logs/access.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          <fileNamePattern>${jetty.base}/logs/access-%d{yyyy-MM-dd}.log.gz</fileNamePattern>
        </rollingPolicy>
        <encoder>
          <pattern>combined</pattern>
        </encoder>
      </appender>
     
      <appender-ref ref="FILE" />
    </configuration>

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

Optional Configuration

Supporting SOAP Endpoints

File(s): /opt/shibboleth-idp/credentials/idp-backchannel.p12etc/jetty-ssl.xml, etc/jetty-https.xml, modules/ssl.mod

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.

  1. Copy the jetty9-dta-ssl-1.0.0.jar (asc) plugin to JETTY_BASE/lib/ext
  2. Add the following properties to JETTY_BASE/modules/ssl.mod:

    jetty.backchannel.keystore=/opt/shibboleth-idp/credentials/idp-backchannel.p12
    jetty.backchannel.keystore.type=PKCS12
    jetty.backchannel.keystore.password=passwordgoeshere
  3. Add the following content to JETTY_BASE/etc/jetty-ssl.xml:

    jetty-ssl.xml
      <!-- ============================================================= -->
      <!-- TLS context factory with optional client auth                 -->
      <!-- and no container trust (delegate to application)              -->
      <!-- for backchannel (SOAP) communication to IdP                   -->
      <!-- ============================================================= -->
      <New id="shibContextFactory" class="net.shibboleth.utilities.jetty9.DelegateToApplicationSslContextFactory">
        <Set name="KeyStorePath"><Property name="jetty.backchannel.keystore" /></Set>
        <Set name="KeyStoreType"><Property name="jetty.backchannel.keystore.type" /></Set>
        <Set name="KeyStorePassword"><Property name="jetty.backchannel.keystore.password" /></Set>
        <Set name="EndpointIdentificationAlgorithm"></Set>
        <Set name="excludeProtocols">
          <Array type="String">
            <Item>SSLv3</Item>
          </Array>
        </Set>
        <Set name="IncludeCipherSuites">
          <Array type="String">
            <Item>TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</Item>
            <Item>TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</Item>
            <Item>TLS_RSA_WITH_AES_128_GCM_SHA256</Item>
            <Item>TLS_RSA_WITH_AES_256_GCM_SHA256</Item>
            <Item>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256</Item>
            <Item>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384</Item>
            <Item>TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA</Item>
            <Item>TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA</Item>
            <Item>TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA</Item>
            <Item>TLS_RSA_WITH_AES_128_CBC_SHA256</Item>
            <Item>TLS_RSA_WITH_AES_256_CBC_SHA384</Item>
            <Item>TLS_RSA_WITH_AES_128_CBC_SHA</Item>
            <Item>TLS_RSA_WITH_AES_256_CBC_SHA</Item>
          </Array>
        </Set>
      </New>
  4. Add the following content to JETTY_BASE/etc/jetty-https.xml:

    jetty-https.xml
      <!-- ============================================================= -->
      <!-- IdP SOAP protocol connector                                   -->
      <!-- ============================================================= -->
      <Call id="httpsSOAPConnector" name="addConnector">
        <Arg>
          <New class="org.eclipse.jetty.server.ServerConnector">
            <Arg name="server"><Ref refid="Server" /></Arg>
            <Arg name="acceptors" type="int"><Property name="ssl.acceptors" default="-1"/></Arg>
            <Arg name="selectors" type="int"><Property name="ssl.selectors" default="-1"/></Arg>
            <Arg name="factories">
              <Array type="org.eclipse.jetty.server.ConnectionFactory">
                <Item>
                  <New class="org.eclipse.jetty.server.SslConnectionFactory">
                    <Arg name="next">http/1.1</Arg>
                    <Arg name="sslContextFactory"><Ref refid="shibContextFactory"/></Arg>
                  </New>
                </Item>
                <Item>
                  <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                    <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
                  </New>
                </Item>
              </Array>
            </Arg>
            <Set name="host"><Property name="jetty.host" /></Set>
            <!-- Change port number as needed -->
            <Set name="port">8443</Set>
            <Set name="idleTimeout"><Property name="https.timeout" default="30000"/></Set>
            <Set name="soLingerTime"><Property name="https.soLingerTime" default="-1"/></Set>
            <Set name="acceptorPriorityDelta"><Property name="ssl.acceptorPriorityDelta" default="0"/></Set>
            <Set name="selectorPriorityDelta"><Property name="ssl.selectorPriorityDelta" default="0"/></Set>
            <Set name="acceptQueueSize"><Property name="https.acceptQueueSize" default="0"/></Set>
          </New>
        </Arg>
      </Call>

 

  • No labels