Skip to content

Commit

Permalink
Fixes #3377 - Improve jetty-ssl-context.xml.
Browse files Browse the repository at this point in the history
Split `ssl.mod` and `jetty-ssl.xml` into `ssl-context.mod` and `jetty-ssl-context.xml`.

Added as properties all those that were missing to configure `SslContextFactory`.

Updated documentation.
Removed duplicate documentation section about custom configuration of TLS properties via a custom XML file.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
  • Loading branch information
sbordet committed Nov 29, 2024
1 parent d1fc707 commit f4029ad
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 209 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -613,13 +613,12 @@ include::{jetty-home}/modules/size-limit.mod[tags=documentation]

The `ssl` module provides the secure connector, and allows you to configure the KeyStore properties and the TLS parameters, and depends on the <<server,`server` module>>.

[[ssl-connector]]
=== Secure Connector Properties
For more information about securing a connector and supporting secure protocols, refer to xref:protocols/index.adoc#ssl[this section].

The module properties to configure the secure connector are:

----
include::{jetty-home}/modules/ssl.mod[tags=documentation-connector]
include::{jetty-home}/modules/ssl.mod[tags=documentation]
----

Among the configurable properties, the most relevant are:
Expand All @@ -635,18 +634,18 @@ Refer to <<http-acceptors,this section>> for more information about acceptor thr
The number of NIO selectors (with an associated thread) that manage connections -- default -1 (i.e. a select heuristic decides the value; the current heuristic calculates a value based on the number of cores).
Refer to <<http-selectors,this section>> for more information about selector threads.

The module properties to configure the KeyStore and TLS parameters are:

----
include::{jetty-home}/modules/ssl.mod[tags=documentation-ssl-context]
----
[[ssl-context]]
== Module `ssl-context`

[[ssl-keystore-tls]]
=== KeyStore Properties and TLS Properties
The `ssl-context` module provides the KeyStore, TrustStore and TLS configuration necessary to the `ssl` module.

The Jetty component that manages the KeyStore, that contains the cryptographic material and the TLS configuration is an instance of `SslContextFactory.Server`.

You can configure the `SslContextFactory.Server` by specifying properties, or by invoking its method for a more xref:ssl-advanced[advanced configuration].
The module properties to configure the KeyStore and TLS parameters are:

----
include::{jetty-home}/modules/ssl-context.mod[tags=documentation]
----

Among the configurable properties, the most relevant are:

Expand All @@ -663,61 +662,10 @@ Whether client certificate authentication should be required.
`jetty.sslContext.wantClientAuth`::
Whether client certificate authentication should be requested.

If you configure client certificate authentication, you need to configure and distribute a client KeyStore as explained in xref:keystore/index.adoc#client-authn[this section].

[[ssl-advanced]]
=== Advanced TLS Configuration

Configuring `SslContextFactory.Server` using properties as explained in xref:ssl-keystore-tls[this section] is sufficient for most cases.

For the cases where Jetty module properties are not defined, or when you need more advanced configuration (for example the ability to include and/or exclude the TLS cipher suites), you can follow these steps:
Configuring `SslContextFactory.Server` using properties is sufficient for most cases.
For the cases where Jetty module properties are not defined, or when you need more advanced configuration, you can refer to xref:protocols/index.adoc#ssl-customize[this section].

. Modify `$JETTY_BASE/start.d/ssl.ini` by adding a path to a custom XML file, for example:
+
.ssl.ini
[source,subs="verbatim,quotes"]
----
--module=ssl
*etc/ssl-config.xml* <1>
...
----
<1> The path to the custom XML file, relative to `$JETTY_BASE`.
. Create the custom XML file, with your advanced configuration.
For example, to exclude certain TLS ciphers you can use the following file:
+
.ssl-config.xml
[source,xml,subs="verbatim"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://jetty.org/jetty/configure_10_0.dtd">
<Configure>
<Ref refid="sslContextFactory"> <1>
<!-- Example using the Set element -->
<Set name="ExcludeCipherSuites"> <2>
<Array type="String">
<Item>^TLS_RSA_.*$</Item>
<Item>^.*_(MD5|SHA|SHA1)$</Item>
</Array>
</Set>
<!-- Example using the Call element -->
<Call name="addExcludeCipherSuites">
<Arg>
<Array type="String">
<Item>^SSL_.*$</Item>
</Array>
</Arg>
</Call>
</Ref>
</Configure>
----
<1> Reference the existing `sslContextFactory` object.
<2> Call the method `setExcludeCipherSuites(String\...)` to specify regular expressions of the TLS ciphers you want to exclude.

The syntax to use in the custom XML file is described in xref:xml/index.adoc[this section].

In the custom XML file you can call any `SslContextFactory.Server` method.
Refer to the `SslContextFactory.Server` link:{javadoc-url}/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html[javadocs] for the comprehensive list of methods.
If you configure client certificate authentication, you need to configure and distribute a client KeyStore as explained in xref:keystore/index.adoc#client-authn[this section].

[[ssl-reload]]
== Module `ssl-reload`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ $JETTY_BASE
│ └── jetty-logging.properties
└── start.d
├── https.ini
└── ssl.ini
└── ssl-context.ini
----

Note that the KeyStore file is missing, because you have to provide one with the cryptographic material you want (read xref:keystore/index.adoc[this section] to create your own KeyStore).
You need to configure these two properties by editing `ssl.ini`:
You need to configure these two properties by editing `ssl-context.ini`:

* `jetty.sslContext.keyStorePath`
* `jetty.sslContext.keyStorePassword`
Expand Down Expand Up @@ -141,7 +141,7 @@ The `$JETTY_BASE` directory is now:
│ └── jetty-logging.properties
└── start.d
├── https.ini
├── ssl.ini
├── ssl-context.ini
└── test-keystore.ini
----

Expand Down Expand Up @@ -716,21 +716,22 @@ If you enable _both_ the `https` and the `http2` module, you will have a single
Secure protocols have a slightly more complicated configuration since they require to configure a _KeyStore_.
Refer to the xref:keystore/index.adoc[KeyStore section] for more information about how to create and manage a KeyStore.

For simple cases, you only need to configure the KeyStore path and KeyStore password as explained in xref:modules/standard.adoc#ssl-keystore-tls[this section].
For simple cases, you only need to configure the KeyStore path and KeyStore password as explained in xref:modules/standard.adoc#ssl-context[this section].

For more advanced configuration you may want to configure the TLS protocol versions, or the ciphers to include/exclude, etc.
The correct way of doing this is to create a custom xref:xml/index.adoc[Jetty XML file] and reference it in `$JETTY_BASE/start.d/ssl.ini`:
For more advanced configuration, for example where Jetty module properties are not defined, or the values for those properties need to be fetched from external sources, you can follow the steps below.

.ssl.ini
[source]
First, create a custom xref:xml/index.adoc[Jetty XML file] and reference it in `$JETTY_BASE/start.d/ssl-context.ini`:

.ssl-context.ini
[source,subs="verbatim,quotes"]
----
jetty.sslContext.keyStorePassword=my_passwd! <1>
etc/tls-config.xml <2>
--module=ssl-context
*etc/tls-config.xml* <1>
...
----
<1> Configures the `jetty.sslContext.keyStorePassword` property with the KeyStore password.
<2> References your newly created `$JETTY_BASE/etc/tls-config.xml`.
<1> The path to the custom XML file, relative to `$JETTY_BASE`.

The `ssl.ini` file above only shows the lines that are not commented out (you can leave the lines that are commented unmodified for future reference).
The `ssl-context.ini` file above only shows the lines that are not commented out (you can leave the lines that are commented unmodified for future reference).

You want to create the `$JETTY_BASE/etc/tls-config.xml` with the following template content:

Expand All @@ -748,7 +749,7 @@ You want to create the `$JETTY_BASE/etc/tls-config.xml` with the following templ
----
<1> Here goes your advanced configuration.

The `tls-config.xml` file references the `sslContextFactory` component (created by the `ssl` Jetty module) that configures the KeyStore and TLS parameters, so that you can now call its APIs via XML, and you will have full flexibility for any advanced configuration you want (see below for few examples).
The `tls-config.xml` file references the `sslContextFactory` component (created by the `ssl-context` Jetty module) that configures the KeyStore and TLS parameters, so that you can now call its APIs via XML (using the syntax described in xref:xml/index.adoc[this section]), and you will have full flexibility for any advanced configuration you want (see below for few examples).

Refer to the link:{javadoc-url}/org/eclipse/jetty/util/ssl/SslContextFactory.Server.html[SslContextFactory.Server javadocs] for the list of methods that you can call through the Jetty XML file.

Expand Down Expand Up @@ -783,7 +784,8 @@ To explicitly add the exclusion of TLSv1.0 and TLSv1.1 (that are also vulnerable
[[ssl-customize-ciphers]]
==== Customizing SSL/TLS Ciphers

You can precisely set the list of excluded ciphers, completely overriding Jetty's default, with this XML:
By default, certain cipher suites are already excluded because they are either weak or vulnerable.
To explicitly exclude more cipher suites in addition to those excluded by default, you can use this XML:

.tls-config.xml
[,xml]
Expand All @@ -793,27 +795,21 @@ You can precisely set the list of excluded ciphers, completely overriding Jetty'
<Configure>
<Ref refid="sslContextFactory">
<Set name="ExcludeCipherSuites">
<Array type="String">
<Item>^TLS_RSA_.*$</Item>
<Item>^.*_RSA_.*_(MD5|SHA|SHA1)$</Item>
<Item>^.*_DHE_RSA_.*$</Item>
<Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
<Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
<Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
<Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
<Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
</Array>
</Set>
<Call name="addExcludeCipherSuites">
<Arg>
<Array type="String">
<Item>^TLS_DHE_.*$</Item>
<Item>TLS_CHACHA20_POLY1305_SHA256</Item>
</Array>
</Arg>
</Call>
</Ref>
</Configure>
----

Note how each array item specifies a _regular expression_ that matches multiple ciphers, or specifies a precise cipher to exclude.

You can choose to create multiple XML files, and reference them all from `$JETTY_BASE/start.d/ssl.ini`, or put all your custom configurations in a single XML file.
You can choose to create multiple XML files, and reference them all from `$JETTY_BASE/start.d/ssl-context.ini`, or put all your custom configurations in a single XML file.

[[ssl-renew]]
=== Renewing the Certificates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ MD5:5eBe2294EcD0E0F08eAb7690D2A6Ee69 <4>
The `Password` tool produced an obfuscated string for the password `secret`, namely `OBF:1yta1t331v8w1v9q1t331ytc` (the prefix `OBF:` must be retained).
The obfuscated string can be de-obfuscated to obtain the original password.

Now you can use the obfuscated password in Jetty configuration files, for example to specify the KeyStore password in `ssl.ini` when configuring secure connectors, as explained xref:protocols/index.adoc#ssl-customize[here].
Now you can use the obfuscated password in Jetty configuration files, for example to specify the KeyStore password in `ssl-context.ini` when configuring secure connectors, as explained xref:protocols/index.adoc#ssl-customize[here].
For example:

.ssl.ini
.ssl-context.ini
[,properties]
----
jetty.sslContext.keyStorePassword=OBF:1yta1t331v8w1v9q1t331ytc
Expand Down
79 changes: 43 additions & 36 deletions jetty-core/jetty-server/src/main/config/etc/jetty-ssl-context.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,63 @@
<Call name="addBean">
<Arg>
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory$Server">
<Set name="Provider" property="jetty.sslContext.provider" />
<Set name="KeyStorePath">
<Set name="provider" property="jetty.sslContext.provider" />
<Set name="keyStorePath">
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.sslContext.keyStorePath" default="etc/keystore.p12" /></Arg>
</Call>
</Set>
<Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" /></Set>
<Set name="KeyStoreType" property="jetty.sslContext.keyStoreType" />
<Set name="KeyStoreProvider" property="jetty.sslContext.keyStoreProvider" />
<Set name="KeyManagerPassword"><Property name="jetty.sslContext.keyManagerPassword" /></Set>
<Set name="TrustStorePath">
<Set name="keyStorePassword"><Property name="jetty.sslContext.keyStorePassword" /></Set>
<Set name="keyStoreType" property="jetty.sslContext.keyStoreType" />
<Set name="keyStoreProvider" property="jetty.sslContext.keyStoreProvider" />
<Set name="keyManagerPassword"><Property name="jetty.sslContext.keyManagerPassword" /></Set>
<Set name="trustStorePath">
<Call name="resolvePath" class="org.eclipse.jetty.xml.XmlConfiguration">
<Arg><Property name="jetty.base"/></Arg>
<Arg><Property name="jetty.sslContext.trustStorePath" deprecated="jetty.sslContext.trustStoreAbsolutePath,jetty.truststore" /></Arg>
</Call>
</Set>
<Set name="TrustStorePassword" property="jetty.sslContext.trustStorePassword" />
<Set name="TrustStoreType" property="jetty.sslContext.trustStoreType" />
<Set name="TrustStoreProvider" property="jetty.sslContext.trustStoreProvider" />
<Set name="EndpointIdentificationAlgorithm" property="jetty.sslContext.endpointIdentificationAlgorithm" />
<Set name="NeedClientAuth" property="jetty.sslContext.needClientAuth" />
<Set name="WantClientAuth" property="jetty.sslContext.wantClientAuth" />
<Set name="trustStorePassword" property="jetty.sslContext.trustStorePassword" />
<Set name="trustStoreType" property="jetty.sslContext.trustStoreType" />
<Set name="trustStoreProvider" property="jetty.sslContext.trustStoreProvider" />
<Set name="endpointIdentificationAlgorithm" property="jetty.sslContext.endpointIdentificationAlgorithm" />
<Set name="needClientAuth" property="jetty.sslContext.needClientAuth" />
<Set name="wantClientAuth" property="jetty.sslContext.wantClientAuth" />
<Set name="useCipherSuitesOrder" property="jetty.sslContext.useCipherSuitesOrder" />
<Set name="sslSessionCacheSize" property="jetty.sslContext.sslSessionCacheSize" />
<Set name="sslSessionTimeout" property="jetty.sslContext.sslSessionTimeout" />
<Set name="RenegotiationAllowed" property="jetty.sslContext.renegotiationAllowed" />
<Set name="RenegotiationLimit" property="jetty.sslContext.renegotiationLimit" />
<Set name="SniRequired" property="jetty.sslContext.sniRequired" />

<!-- Example of how to configure a PKIX Certificate Path revocation Checker
<Call id="pkixPreferCrls" class="java.security.cert.PKIXRevocationChecker$Option" name="valueOf"><Arg>PREFER_CRLS</Arg></Call>
<Call id="pkixSoftFail" class="java.security.cert.PKIXRevocationChecker$Option" name="valueOf"><Arg>SOFT_FAIL</Arg></Call>
<Call id="pkixNoFallback" class="java.security.cert.PKIXRevocationChecker$Option" name="valueOf"><Arg>NO_FALLBACK</Arg></Call>
<Call class="java.security.cert.CertPathBuilder" name="getInstance">
<Arg>PKIX</Arg>
<Call id="pkixRevocationChecker" name="getRevocationChecker">
<Call name="setOptions">
<Arg>
<Call class="java.util.EnumSet" name="of">
<Arg><Ref refid="pkixPreferCrls"/></Arg>
<Arg><Ref refid="pkixSoftFail"/></Arg>
<Arg><Ref refid="pkixNoFallback"/></Arg>
</Call>
</Arg>
</Call>
<Set name="renegotiationAllowed" property="jetty.sslContext.renegotiationAllowed" />
<Set name="renegotiationLimit" property="jetty.sslContext.renegotiationLimit" />
<Set name="sniRequired" property="jetty.sslContext.sniRequired" />
<Set name="protocol" property="jetty.sslContext.protocol" />
<Set name="includeProtocols">
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
<Arg><Property name="jetty.sslContext.includeProtocols" default="" /></Arg>
</Call>
</Set>
<Set name="excludeProtocols">
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
<Arg><Property name="jetty.sslContext.excludeProtocols" default="SSL,SSLv2,SSLv2Hello,SSLv3" /></Arg>
</Call>
</Set>
<Set name="includeCipherSuites">
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
<Arg><Property name="jetty.sslContext.includeCipherSuites" default="" /></Arg>
</Call>
</Set>
<Set name="excludeCipherSuites">
<Call class="org.eclipse.jetty.util.StringUtil" name="csvSplit">
<Arg><Property name="jetty.sslContext.excludeCipherSuites" default="^.*_(MD5|SHA|SHA1)$,^SSL_.*$,^.*_NULL_.*$,^.*_anon_.*$" /></Arg>
</Call>
</Call>
<Set name="PkixCertPathChecker"><Ref refid="pkixRevocationChecker"/></Set>
-->
</Set>
<Set name="certAlias" property="jetty.sslContext.alias" />
<Set name="validateCerts" property="jetty.sslContext.validateCertificates" />
<Set name="validatePeerCerts" property="jetty.sslContext.validatePeerCertificates" />
<Set name="secureRandomAlgorithm" property="jetty.sslContext.secureRandomAlgorithm" />
<Set name="keyManagerFactoryAlgorithm" property="jetty.sslContext.keyManagerFactoryAlgorithm" />
<Set name="trustManagerFactoryAlgorithm" property="jetty.sslContext.trustManagerFactoryAlgorithm" />
<Set name="sessionCachingEnabled" property="jetty.sslContext.sessionCachingEnabled" />
</New>
</Arg>
</Call>
Expand Down
Loading

0 comments on commit f4029ad

Please sign in to comment.