[
https://issues.apache.org/jira/browse/HDDS-16682?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Attila Doroszlai updated HDDS-16682:
------------------------------------
Fix Version/s: 2.3.0
Resolution: Implemented
Status: Resolved (was: Patch Available)
> Make the HTTPS SNI host check configurable instead of unconditionally disabled
> ------------------------------------------------------------------------------
>
> Key: HDDS-16682
> URL: https://issues.apache.org/jira/browse/HDDS-16682
> Project: Apache Ozone
> Issue Type: Improvement
> Components: Security
> Reporter: Andrey Yarovoy
> Assignee: Andrey Yarovoy
> Priority: Major
> Labels: pull-request-available
> Fix For: 2.3.0
>
>
> HDDS-8280 upgraded Jetty from 9.4 to 12.0.38. Jetty 12's
> SecureRequestCustomizer
> defaults sniHostCheck to true, which rejects any HTTPS request whose Host
> header
> (or TLS SNI) is not covered by the certificate the connector served, with a
> 400 "Invalid SNI". Jetty 9.4 only applied that check when the client's SNI
> actually matched a certificate in the keystore, so requests carrying no SNI or
> an unmatched name were served with the default certificate.
> That is a behavior change for every Ozone HTTPS endpoint, and it breaks setups
> that worked before the upgrade:
> * requests to an IP literal, which carry no SNI at all;
> * requests to localhost, a VIP, a load-balancer name, or any DNS alias that
> is
> absent from the keystore certificate's CN/SubjectAlternativeName.
> To keep the upgrade behavior-preserving, HttpServer2 currently disables the
> check unconditionally:
>
> hadoop-hdds/framework/src/main/java/org/apache/hadoop/hdds/server/http/HttpServer2.java
> httpConfig.addCustomizer(new SecureRequestCustomizer(false));
> That was the right call for the upgrade itself -- it keeps HDDS-8280 free of a
> behavior change on the TLS path -- but it leaves no way to get the hardening
> back. Operators whose certificates do cover every name clients use should be
> able to enable the check, and today they cannot without patching Ozone.
> Note that the Ozone HTTPS keystore is operator-supplied: HttpServer2 reads it
> from ssl-server.xml via hadoop.ssl.server.keystore.location, not from the SCM
> internal CA. So whether the check can be satisfied depends entirely on the
> operator's certificate, which is exactly why this belongs in configuration and
> cannot be decided for them.
> Proposed change
> ---------------
> Add a boolean configuration key, default false, that selects the sniHostCheck
> argument passed to SecureRequestCustomizer:
> ozone.http.sni.host.check.enabled (default: false)
> false -- current behavior: the Host/SNI name is not required to be covered
> by
> the served certificate (Jetty 9.4 semantics).
> true -- Jetty 12 default: reject requests whose Host or SNI is not covered
> by
> the served certificate.
> The key sits in the ozone.http.* namespace alongside ozone.http.policy and
> ozone.http.basedir, which already govern this HTTP server family including its
> HTTPS mode.
> Scope:
> * Read the key in HttpServer2.Builder (loadSSLConfiguration / the HTTPS
> connector path) and pass it to SecureRequestCustomizer, replacing the
> hard-coded false. Follow the shape of the existing allowAmbiguousUri flag
> --
> a Builder setter plus a BaseHttpServer hook -- so a service can override
> the
> cluster-wide value if one ever needs to.
> * Document the key in ozone-default.xml, stating plainly that the default
> preserves pre-Jetty-12 behavior and that enabling it requires the server
> certificate to carry every hostname and IP clients connect with, as a
> SubjectAlternativeName (an IP literal needs an iPAddress SAN, since such a
> request sends no SNI).
> * Mention it in the HTTPS section of the security docs next to the existing
> TLS configuration.
> Default kept at false deliberately: flipping it would be the behavior change
> HDDS-8280 avoided, and it would break clusters reached by VIP or IP literal on
> upgrade. Changing the default is a separate decision for a later release, and
> should be made only with a release note.
> Out of scope: Jetty's separate and stricter sniRequired option (reject
> requests
> that send no SNI at all). It is a different policy with a different blast
> radius
> and no pre-upgrade equivalent, so it should be its own Jira if anyone wants
> it.
> Testing
> -------
> TestHttpServer2SSL already has testIpLiteralServedWithNonMatchingCertificate,
> which asserts that the IP literal 127.0.0.1 is served 200 against the
> CN=localhost test keystore -- that test pins the default-false behavior and
> must keep passing unchanged. Add the mirror case: with the key set to true,
> the
> same IP-literal request gets 400 while the covered "localhost" name still gets
> 200. That is a direct test of the knob in both positions against one keystore.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]