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>

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.

If an artifact file exists on disk prior to the deployment process, the checksum of the artifact file will be compared to the checksum of the artifact to be deployed. If the checksums match, deployment of the artifact in question will be skipped. If the checksums do not match, the artifact will be deployed, overwriting the existing artifact file. To prevent contention during the deployment process, a platform-dependent lock will be acquired on the artifact file. The lock should prevent other processes from accessing the artifact file while it is being processed. Ultimately, the checksum and locking strategy should ensure valid deployments while preventing unnecessary writes to disk and file contention when multiple Repose processes are running concurrently.

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 deployment-directory is not shared between more than one Repose instance if the auto-clean feature is used.

If the auto-clean feature is not being used, it should be safe to share the deployment-directory between multiple Repose instances.

Files in the deployment directory are only removed if the auto-clean feature is used, and even then, only when Repose shuts down. Since files in the deployment directory are made accessible to Repose at runtime (via the classpath), files in the deployment directory that are not managed by Repose could affect the behavior of Repose and could even result in errors. As such, care should be taken to ensure that errant files do not end up in the deployment directory.

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

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. All of Jetty’s built-in default allowed protocols and ciphers are cleared and then the configured inclusion and exclusion lists are applied if an ssl-configuration is specified.

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

— Jetty
The Definitive Reference

Protocols and ciphers are configured using the same process. We start with the list of all that are available on the host system. This list is culled to contain only those that match the included RegEx statements. Then the list is further culled to remove any that match the excluded RegEx statements.

In the following example, the container configuration includes only the recommended TLS ciphers and protocols. This in turn automatically excludes all SSL protocols and ciphers as they do not meet the inclusion criteria.

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>
            <!-- include only the recommended protocols and ciphers -->
            <included-protocols>
                <protocol>TLSv1.2</protocol>
            </included-protocols>
            <included-ciphers>
                <!-- This allows only the following:
                - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
                - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
                - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
                - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
                - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
                - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
                -->
                <cipher>TLS_ECDHE_RSA_WITH_AES_(128|256)_(CBC|GCM)_SHA(256|384)?</cipher>
                <!-- The opening ^ and closing $ are assumed and will cause failure if present. -->
            </included-ciphers>
            <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.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).

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