The container configuration is required to set up Repose. It is used to tell the system where to look for component artifacts and where to deploy them.

Configuration

The following example shows a basic configuration for the Container file.

container.cfg.xml - Default
<?xml version="1.0" encoding="UTF-8"?>
<repose-container xmlns='http://docs.openrepose.org/repose/container/v2.0'>
    <deployment-config>
        <deployment-directory auto-clean="false">/var/repose</deployment-directory>
        <artifact-directory check-interval="60000">/usr/share/repose/filters</artifact-directory>
        <logging-configuration href="file:///etc/repose/log4j2.xml"/>
    </deployment-config>
</repose-container>

Cluster Specific Container Configuration

A user may configure different values for different Repose clusters. This is achieved by including one or more cluster-config elements which map to clusters in the system-model. All configuration within a cluster-config element is optional. When configuration is present, it will override the base configuration (i.e., the deployment-config element) values. This functionality may be referred to as "container configuration patching" or simply as "patching".

When discussing patches, one might notice that there is ambiguity in the rules for how patches are applied. Below is a list of common ambiguities, and how they are handled in this context:

  • Is there any way to "patch out" or remove some configuration that is in the deployment-config element?

    • Generally speaking, no. The applied patch will only override existing values. There is no way to designate that some configuration should be removed. However, there is a case where configuration may technically be removed – collections. See the next bullet for more details.

  • How are collections (i.e., all and sequence XSD elements, list attributes) patched? Are elements in the patch collection added to the base collection? Does the patch collection replace the base collection?

    • Patching will treat collections as a single unit, and so configuring a collection in the cluster-config (e.g., included-protocols for SSL) will result in that cluster using the "patched" collection. It will not use anything configured in the deployment-config element. Items in collections are not combined.

Not all configuration is patchable. Some values (e.g., the deployment-directory) cannot be overridden due to internal system constraints. Currently the only items that are patchable are some of the deployment-config element’s attributes. Specifically only the following:

  • via (Deprecated scheduled for removal in v9.0.0.0)

  • via-header

  • content-body-read-limit

  • idleTimeout

  • soLingerTime

Something else to be aware of is that the deployment-directory and artifact-directory values should be fully qualified paths. This is the case as the exact location of the launcing JVM may not remain in the same location and this would effect relative paths. The path should not start or end with a whitespace character as all leading and trailing whitespace is ignored in reading this value. All white space in the middle of the path name will be preserved and should not be escaped in any way.

Artifacts

Artifacts are files containing resources which extend the functionality of Repose. Technically, Repose artifacts are Enterprise Application Archives (EARs).

For example, as part of the package installation of Repose (either using a DEB or RPM package), a filter-bundle-x.x.x.x.ear artifact is placed in the default artifact directory. The filter bundle artifact provides a number of filters that can be used in the filter chain, as well as descriptors of those filters. Without this artifact, Repose would not know about the filters contained within, and therefore, would be not able to use those filters in the filter chain.

Deployment

The deployment process is the process by which Repose organizes the content of Artifacts in preparation for utilization.

To be more specific, the deployment process is comprised of the following steps:

  1. Identify all artifacts in the artifact-directory.

  2. Compute the hash of each artifact.

  3. Create a directory for each artifact as a subdirectory of the deployment-directory.

    1. Each artifact will be associated with its own directory.

    2. The name of each directory will be the hash of the associated artifact.

  4. Extract the contents of the each artifact to its associated directory.

Since each artifact is extracted to a directory named the hash of said artifact, deployment directory names are consistent and predictable. As a result, there will be only one copy of the extracted contents of each artifact, and therefore, disk space usage should also be predictable.

The auto-clean feature may be used to delete deployment directories when Repose shuts down. This feature helps manage disk space usage, and remove the contents of artifacts which are no longer in use. Only deployment directories created by the instance of Repose which is shutting down will be deleted.

If all of the follow conditions are met, Repose may delete deployment directories that are in use by other Repose processes:

  • More than one Repose process is running.

  • More than one Repose process is using the same deployment directory.

  • At least one Repose process has enabled the auto-clean feature.

  • One of the Repose processes with the auto-clean feature enabled stops gracefully.

To avoid this situation, it is highly recommended that the same deployment-directory is not used for more than one Repose instance.

Via Header Configuration

The following assume:

  • the request and response are HTTP/1.1

  • the host is localhost

  • the servicing port is 10010

  • the Repose version is 8.4.1.0

The interaction between the deprecated via attribute and the new via-header element are as follows:

via attribute via-header element Request header Response header

Undefined

Undefined

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Repose (Repose/8.4.1.0)

Stuff

Undefined

1.1 Stuff (Repose/8.4.1.0)

1.1 Stuff (Repose/8.4.1.0)

Stuff

Defined

Will not parse

The following further assumes the deprecated via attribute is not defined and the via-header element contains:

request-prefix response-prefix repose-version Request header Response header

Undefined

Undefined

Undefined

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Repose (Repose/8.4.1.0)

Potato

Undefined

Undefined

1.1 Potato (Repose/8.4.1.0)

1.1 Repose (Repose/8.4.1.0)

Undefined

Salad

Undefined

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Salad (Repose/8.4.1.0)

Potato

Salad

Undefined

1.1 Potato (Repose/8.4.1.0)

1.1 Salad (Repose/8.4.1.0)

Undefined

Undefined

true

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Repose (Repose/8.4.1.0)

Potato

Undefined

true

1.1 Potato (Repose/8.4.1.0)

1.1 Repose (Repose/8.4.1.0)

Undefined

Salad

true

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Salad (Repose/8.4.1.0)

Potato

Salad

true

1.1 Potato (Repose/8.4.1.0)

1.1 Salad (Repose/8.4.1.0)

Undefined

Undefined

false

1.1 localhost:10010 (Repose/8.4.1.0)

No header added

Potato

Undefined

false

1.1 Potato (Repose/8.4.1.0)

No header added

Undefined

Salad

false

1.1 localhost:10010 (Repose/8.4.1.0)

1.1 Salad

Potato

Salad

false

1.1 Potato (Repose/8.4.1.0)

1.1 Salad

User-Supplied Logging Configuration

There are two steps to supply a logging configuration for Repose:

  1. Add a log configuration file to the Repose configuration files directory (e.g., /etc/repose).

  2. Specify the name of the log configuration file in the container.cfg.xml file. It should look like the following example.

container.cfg.xml - Logging
<logging-configuration href="file:///etc/repose/log4j2.xml"/>

Default Logging Configuration

If a user-supplied logging configuration file is not found, Repose programmatically sets default log4j properties. This default properties add a ConsoleAppender to the ROOT logger. The output will be formatted using a PatternLayout set to the pattern %d %-4r [%t] %-5p %c - %m%n. The default log level is set to DEBUG.

SSL/TLS Client Authentication

SSL/TLS Client Authentication is being used more and more for communications between different enclaves. This addition to the SSL/TLS handshake involves the Client presenting credentials to the Server in the same manner as the Server does to the Client. If the credentials presented by the Client are not trusted, then the Server will sever the connection just as the Client would have if the situation was reversed. Since a Client initiates contact with the Server, the Server’s credentials are simply to validate it is who the Client was trying to contact. This is accomplished through Certificate Authorities (CA) and the Trust Hierarchies built into the Public Key Infrastructure (PKI). Even though you can optionally add a particular Server’s credentials directly into a Client so that it will implicitly trust a particular Server essentially bypassing the distributed trust mechanism in favor of a more direct one, this is the only way to build a relationship for a Client to a Server.

To require SSL/TLS Client Authentication, set the need-client-auth attribute to True. With this setting enabled, only Clients that have a Public Key imported into the trust store referenced by the truststore-filename element will be allowed to connect. The truststore is a Java Keystore that can be created/updated using the command line tool named aptly enough, keytool. Below is an example of importing a Client certificate (client.crt) into a truststore (truststore.jks):

keytool
keytool -import -file client.crt -alias client -keystore truststore.jks

This will update the keystore if it exists or create a new one if it doesn’t. The tool will also prompt for a password. The password will be used to access an existing file or set as the password on a new one.

To use the truststore created/updated in the example above, the following would need to be added/updated in the container.cfg.xml file:

container.cfg.xml - Truststore
<ssl-configuration need-client-auth="true">
    <truststore-filename>truststore.jks</truststore-filename>
    <truststore-password>password</truststore-password>

For more details, see:

Valve Configuration of SSL/TLS Certificates

Repose Valve is based on Jetty and uses its services for SSL/TLS termination. To enable this feature you need to:

  1. Obtain keys and certificates from somewhere OR generate them.

  2. Load the keys and certificates into a keystore file.

  3. Place the keystore file in your Repose configuration root directory.

  4. Place the keystore information in your container.cfg.xml file.

  5. Place the desired HTTPS port in your system-model.cfg.xml file. See System Model for more details.

Keystore information is located within the <ssl-configuration> element as shown in the following example.

container.cfg.xml - SSL/TLS Certificates
<?xml version="1.0" encoding="UTF-8"?>
<repose-container xmlns='http://docs.openrepose.org/repose/container/v2.0'>
    <deployment-config>
        <deployment-directory auto-clean="false">/var/repose</deployment-directory>
        <artifact-directory check-interval="60000">/usr/share/repose/filters</artifact-directory>
        <logging-configuration href="log4j2.xml"/>
        <ssl-configuration>
            <keystore-filename>keystore.repose</keystore-filename>
            <keystore-password>manage</keystore-password>
            <key-password>password</key-password>
        </ssl-configuration>
    </deployment-config>
</repose-container>

Whitelisting and Blacklisting Ciphers and Protocols

Since security is a constantly moving target, any recommended configuration would quickly become out of date. A risk assessment should always be performed by the appropriately qualified people for your organization. Links to industry-standard references are provided in the SSL References section below.

Repose supports whitelisting and blacklisting specific protocols and ciphers by exposing portions of the Jetty configuration via the container.cfg.xml file. You can use this feature if a specific protocol or cipher has been compromised and you want to block its usage and harden your Repose instance. Any of Jetty’s built-in defaults are cleared and then the configured inclusion and exclusion lists are applied if any are defined.

When working with Includes / Excludes, it is important to know that Excludes will always win.

— Jetty
The Definitive Reference

In the following example, the container configuration includes the TLS v1.2 protocol and TLS ciphers and excludes then SSLv3 protocol and SSL ciphers.

container.cfg.xml - Protocols and ciphers
<repose-container xmlns='http://docs.openrepose.org/repose/container/v2.0'>
    <deployment-config>
       <deployment-directory auto-clean="false">/var/repose</deployment-directory>
       <artifact-directory check-interval="60000">/usr/share/repose/filters</artifact-directory>
       <logging-configuration href="file:///etc/repose/log4j2.xml"/>
       <ssl-configuration>
          <keystore-filename>keystore.jks</keystore-filename>
          <keystore-password>password</keystore-password>
          <key-password>password</key-password>
          <included-ciphers>
              <cipher>.*TLS.*</cipher>
          </included-ciphers>
          <excluded-ciphers>
              <cipher>.*SSL.*</cipher>
          </excluded-ciphers>
          <excluded-protocols>
               <protocol>SSLv3</protocol>
          </excluded-protocols>
          <included-protocols>
              <protocol>TLSv1.2</protocol>
          </included-protocols>
          <tls-renegotiation-allowed>false</tls-renegotiation-allowed>
      </ssl-configuration>
    </deployment-config>
</repose-container>

You need to specify your keystore in the container configuration just as you would in Jetty.

Diffie-Hellman Security Risk and Key Size

Certain attacks (such as Logjam) leverage the weakness of "small" Diffie-Hellman (DH) keys. To mitigate the risk of such attackers, users may either exclude vulnerable ciphers, or lengthen the DH keys used by Repose. Instructions for the former are above. For the latter, note the following:

Diffie-Hellman (DH) keys of sizes less than 1024 bits have been deprecated because of their insufficient strength. In JDK 8, you can customize the ephemeral DH key size with the system property jdk.tls.ephemeralDHKeySize.

— Java Secure Socket Extension (JSSE) Reference Guide

In other words, the Java option -Djdk.tls.ephemeralDHKeySize=2048 can be passed when starting Repose to force the use of longer DH keys.

For more details, see Customizing DH Keys.

Available Ciphers and Protocols

The list of available ciphers and protocols varies depending on the JVM. We have added a command line option to Repose Valve to display the available and default enabled ciphers and protocols:

Show SSL Params
java -jar /usr/share/repose/repose-valve.jar --show-ssl-params

This will dump a list of the default enabled SSL/TLS parameters for the JVM you’re using. Additionally, it will list all available ciphers and protocols, should you wish to use one of those.

Running in Insecure Mode

This mode should only be used during development testing. These settings are NOT intended for a production environment.

When running in insecure mode, Repose will accept all certificates from external services with which it communicates (e.g., authentication service, origin service).

Valve

When running the Valve deployment, Repose may be placed in insecure mode by passing in the -k option as follows:

Insecure Mode - Valve
java -jar /usr/share/repose/repose-valve.jar -c /etc/repose -k

ROOT.war

When running the ROOT.war deployment, Repose may be placed in insecure mode by passing in the following system property:

Insecure Mode - ROOT.war
-Dinsecure=true