diff --git a/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc b/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc index 45b14005a65b..400f9e541719 100644 --- a/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc +++ b/documentation/jetty/modules/operations-guide/pages/modules/standard.adoc @@ -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 <>. -[[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: @@ -635,18 +634,18 @@ Refer to <> 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 <> 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: @@ -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"] ----- - - - - - <1> - - <2> - - ^TLS_RSA_.*$ - ^.*_(MD5|SHA|SHA1)$ - - - - - - - ^SSL_.*$ - - - - - ----- -<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` diff --git a/documentation/jetty/modules/operations-guide/pages/protocols/index.adoc b/documentation/jetty/modules/operations-guide/pages/protocols/index.adoc index a15277f5ee62..201247516b50 100644 --- a/documentation/jetty/modules/operations-guide/pages/protocols/index.adoc +++ b/documentation/jetty/modules/operations-guide/pages/protocols/index.adoc @@ -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` @@ -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 ---- @@ -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: @@ -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. @@ -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] @@ -793,27 +795,21 @@ You can precisely set the list of excluded ciphers, completely overriding Jetty' - - - ^TLS_RSA_.*$ - ^.*_RSA_.*_(MD5|SHA|SHA1)$ - ^.*_DHE_RSA_.*$ - SSL_RSA_WITH_DES_CBC_SHA - SSL_DHE_RSA_WITH_DES_CBC_SHA - SSL_DHE_DSS_WITH_DES_CBC_SHA - SSL_RSA_EXPORT_WITH_RC4_40_MD5 - SSL_RSA_EXPORT_WITH_DES40_CBC_SHA - SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA - SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA - - + + + + ^TLS_DHE_.*$ + TLS_CHACHA20_POLY1305_SHA256 + + + ---- 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 diff --git a/documentation/jetty/modules/operations-guide/pages/tools/index.adoc b/documentation/jetty/modules/operations-guide/pages/tools/index.adoc index 308c8f3ffe71..f5cbebc7ef40 100644 --- a/documentation/jetty/modules/operations-guide/pages/tools/index.adoc +++ b/documentation/jetty/modules/operations-guide/pages/tools/index.adoc @@ -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 diff --git a/jetty-core/jetty-server/src/main/config/etc/jetty-ssl-context.xml b/jetty-core/jetty-server/src/main/config/etc/jetty-ssl-context.xml index 241322ae6a40..8a8677dd4fdf 100644 --- a/jetty-core/jetty-server/src/main/config/etc/jetty-ssl-context.xml +++ b/jetty-core/jetty-server/src/main/config/etc/jetty-ssl-context.xml @@ -4,56 +4,63 @@ - - + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + + + + diff --git a/jetty-core/jetty-server/src/main/config/modules/ssl-context.mod b/jetty-core/jetty-server/src/main/config/modules/ssl-context.mod new file mode 100644 index 000000000000..806391faa8fc --- /dev/null +++ b/jetty-core/jetty-server/src/main/config/modules/ssl-context.mod @@ -0,0 +1,114 @@ +[description] +Enables the TLS (SSL) configuration to support secure protocols. + +[tags] +connector +ssl +internal + +[depend] +server + +[xml] +etc/jetty-ssl-context.xml + +[ini-template] +# tag::documentation[] +### SslContextFactory Configuration +### Note that OBF passwords are not secure, just protected from casual observation. + +## The JSSE Provider. +# jetty.sslContext.provider= + +## The KeyStore file path, either an absolute path or a relative path to $JETTY_BASE. +# jetty.sslContext.keyStorePath=etc/keystore.p12 + +## The KeyStore password. +# jetty.sslContext.keyStorePassword= + +## The Keystore type. +# jetty.sslContext.keyStoreType=PKCS12 + +## The KeyStore provider. +# jetty.sslContext.keyStoreProvider= + +## The KeyManager password. +# jetty.sslContext.keyManagerPassword= + +## The TrustStore file path, either an absolute path or a relative path to $JETTY_BASE. +# jetty.sslContext.trustStorePath=etc/keystore.p12 + +## The TrustStore password. +# jetty.sslContext.trustStorePassword= + +## The TrustStore type. +# jetty.sslContext.trustStoreType=PKCS12 + +## The TrustStore provider. +# jetty.sslContext.trustStoreProvider= + +## The Endpoint Identification Algorithm. +## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String). +# jetty.sslContext.endpointIdentificationAlgorithm= + +## Whether client certificate authentication is required. +# jetty.sslContext.needClientAuth=false + +## Whether client certificate authentication is desired, but not required. +# jetty.sslContext.wantClientAuth=false + +## Whether cipher order is significant. +# jetty.sslContext.useCipherSuitesOrder=true + +## The SSLSession cache size. +# jetty.sslContext.sslSessionCacheSize=-1 + +## The SSLSession cache timeout (in seconds). +# jetty.sslContext.sslSessionTimeout=-1 + +## Whether TLS renegotiation is allowed. +# jetty.sslContext.renegotiationAllowed=true + +## The max number of TLS renegotiations per connection. +# jetty.sslContext.renegotiationLimit=5 + +## Whether client SNI data is required for all secure connections. +## When SNI is required, clients that do not send SNI data are rejected with a TLS handshake error. +# jetty.sslContext.sniRequired=false + +## The specific TLS protocol to use. +# jetty.sslContext.protocol= + +## A comma-separated list of TLS protocols to include. +# jetty.sslContext.includeProtocols= + +## A comma-separated list of TLS protocols to exclude. +# jetty.sslContext.excludeProtocols=SSL,SSLv2,SSLv2Hello,SSLv3 + +## A comma-separated list of cipher suites to include. +# jetty.sslContext.includeCipherSuites= + +## A comma-separated list of cipher suites regular expression patterns to exclude. +# jetty.sslContext.excludeCipherSuites=^.*_(MD5|SHA|SHA1)$,^SSL_.*$,^.*_NULL_.*$,^.*_anon_.*$ + +## The alias to use when the KeyStore contains multiple entries. +# jetty.sslContext.alias= + +## Whether to validate the certificates in the KeyStore at startup. +# jetty.sslContext.validateCertificates=false + +## Whether to validate peer certificates received during the TLS handshake. +# jetty.sslContext.validatePeerCertificates=false + +## The secure random algorithm to use to initialize the SSLContext. +# jetty.sslContext.secureRandomAlgorithm= + +## The KeyManagerFactory algorithm. +# jetty.sslContext.keyManagerFactoryAlgorithm= + +# The TrustManagerFactory algorithm. +# jetty.sslContext.trustManagerFactoryAlgorithm= + +## Whether TLS session caching should be used. +# jetty.sslContext.sessionCachingEnabled=true +# end::documentation[] diff --git a/jetty-core/jetty-server/src/main/config/modules/ssl.mod b/jetty-core/jetty-server/src/main/config/modules/ssl.mod index 6a419b2feed5..dc764c7215d9 100644 --- a/jetty-core/jetty-server/src/main/config/modules/ssl.mod +++ b/jetty-core/jetty-server/src/main/config/modules/ssl.mod @@ -1,6 +1,7 @@ [description] Enables a TLS (SSL) connector to support secure protocols. -Secure HTTP/1.1 is provided by enabling the "https" module and secure HTTP/2 is provided by enabling the "http2" module. +Secure HTTP/1.1 is provided by enabling the "https" module. +Secure HTTP/2 is provided by enabling the "http2" module. [tags] connector @@ -8,14 +9,14 @@ ssl internal [depend] +ssl-context server [xml] etc/jetty-ssl.xml -etc/jetty-ssl-context.xml [ini-template] -# tag::documentation-connector[] +# tag::documentation[] ### TLS (SSL) Connector Configuration ## The host/address to bind the connector to. @@ -69,68 +70,4 @@ etc/jetty-ssl-context.xml ## Whether to include the subdomain property in any Strict-Transport-Security header. # jetty.ssl.stsIncludeSubdomains=true -# end::documentation-connector[] - -# tag::documentation-ssl-context[] -### SslContextFactory Configuration -## Note that OBF passwords are not secure, just protected from casual observation. - -## Whether client SNI data is required for all secure connections. -## When SNI is required, clients that do not send SNI data are rejected with a TLS handshake error. -# jetty.sslContext.sniRequired=false - -## The Endpoint Identification Algorithm. -## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String). -# jetty.sslContext.endpointIdentificationAlgorithm= - -## The JSSE Provider. -# jetty.sslContext.provider= - -## The KeyStore file path, either an absolute path or a relative path to $JETTY_BASE. -# jetty.sslContext.keyStorePath=etc/keystore.p12 - -## The TrustStore file path, either an absolute path or a relative path to $JETTY_BASE. -# jetty.sslContext.trustStorePath=etc/keystore.p12 - -## The KeyStore password. -# jetty.sslContext.keyStorePassword= - -## The Keystore type. -# jetty.sslContext.keyStoreType=PKCS12 - -## The KeyStore provider. -# jetty.sslContext.keyStoreProvider= - -## The KeyManager password. -# jetty.sslContext.keyManagerPassword= - -## The TrustStore password. -# jetty.sslContext.trustStorePassword= - -## The TrustStore type. -# jetty.sslContext.trustStoreType=PKCS12 - -## The TrustStore provider. -# jetty.sslContext.trustStoreProvider= - -## Whether client certificate authentication is required. -# jetty.sslContext.needClientAuth=false - -## Whether client certificate authentication is desired, but not required. -# jetty.sslContext.wantClientAuth=false - -## Whether cipher order is significant. -# jetty.sslContext.useCipherSuitesOrder=true - -## The SSLSession cache size. -# jetty.sslContext.sslSessionCacheSize=-1 - -## The SSLSession cache timeout (in seconds). -# jetty.sslContext.sslSessionTimeout=-1 - -## Whether TLS renegotiation is allowed. -# jetty.sslContext.renegotiationAllowed=true - -## The max number of TLS renegotiations per connection. -# jetty.sslContext.renegotiationLimit=5 -# end::documentation-ssl-context[] +# end::documentation[] diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index 20725ff049a1..c0b62879fc00 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -51,7 +51,6 @@ import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; import javax.net.ssl.CertPathTrustManagerParameters; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; @@ -585,7 +584,7 @@ public void setExcludeCipherSuites(String... cipherSuites) } /** - * You can either use the exact Cipher suite name or a a regular expression. + * You can either use the exact Cipher suite name or a regular expression. * * @param cipher Cipher names to add to {@link SSLEngine#setEnabledCipherSuites(String[])} */ @@ -605,7 +604,7 @@ public String[] getIncludeCipherSuites() } /** - * You can either use the exact Cipher suite name or a a regular expression. + * You can either use the exact Cipher suite name or a regular expression. * * @param cipherSuites The array of cipher suite names to include in * {@link SSLEngine#setEnabledCipherSuites(String[])} @@ -1929,9 +1928,8 @@ public SSLParameters customize(SSLParameters sslParams) sslParams.setCipherSuites(_selectedCipherSuites); if (_selectedProtocols != null) sslParams.setProtocols(_selectedProtocols); - if (this instanceof Server) + if (this instanceof Server server) { - Server server = (Server)this; if (server.getWantClientAuth()) sslParams.setWantClientAuth(true); if (server.getNeedClientAuth()) @@ -2380,7 +2378,7 @@ public String sniSelect(String keyType, Principal[] issuers, SSLSession session, boolean sniRequired = isSniRequired(); if (LOG.isDebugEnabled()) - LOG.debug("Selecting alias: keyType={}, sni={}, sniRequired={}, certs={}", keyType, String.valueOf(sniHost), sniRequired, certificates); + LOG.debug("Selecting alias: keyType={}, sni={}, sniRequired={}, certs={}", keyType, sniHost, sniRequired, certificates); String alias; if (sniHost == null) @@ -2393,7 +2391,7 @@ public String sniSelect(String keyType, Principal[] issuers, SSLSession session, // Match the SNI host. List matching = certificates.stream() .filter(x509 -> x509.matches(sniHost)) - .collect(Collectors.toList()); + .toList(); if (matching.isEmpty()) { @@ -2419,7 +2417,7 @@ public String sniSelect(String keyType, Principal[] issuers, SSLSession session, } if (LOG.isDebugEnabled()) - LOG.debug("Selected alias={}", String.valueOf(alias)); + LOG.debug("Selected alias={}", alias); return alias; }