[
https://issues.apache.org/jira/browse/HADOOP-19972?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jose Luis López updated HADOOP-19972:
-------------------------------------
Description:
Move Hadoop's web servers from Jetty 9.4.58 to Jetty 12.1.14 on the ee8
environment, keeping {{javax.servlet}}. This issue is the port only: everything
that also works on Jetty 9.4 lands first, in the issues under *Depends on*.
*Scope*:
* hadoop-project/pom.xml: set jetty.version to 12.1.14. Replace the managed
jetty-servlet, jetty-webapp, javax-websocket-server-impl and websocket-client
with jetty-ee8-nested, jetty-ee8-servlet, jetty-ee8-webapp,
jetty-ee8-websocket-jetty-server (excluding jetty-ee8-annotations, which brings
the banned asm) and jetty-ee8-websocket-jetty-client. Drop
jetty-servlet-tester, which nothing uses.
* Rename the Jetty entries in the module poms: hadoop-auth, hadoop-common,
hadoop-kms, hadoop-hdfs-httpfs, hadoop-yarn-client, hadoop-yarn-common,
hadoop-yarn-services-api, the ApplicationHistoryServer, the NodeManager, the
ResourceManager, the Router and timelineservice-hbase-tests. hadoop-sls also
declares jetty-ee8-nested, and the NodeManager declares the WebSocket client
for its tests.
* hadoop-client-runtime and hadoop-client-minicluster: replace the Jetty 9.4
coordinates in the exclusions and filters with the ee8 and jetty-websocket-core
ones. The jetty-util exclusions of HADOOP-20014 stay.
* LICENSE-binary and NOTICE-binary: the Jetty 12.1.14 artifacts in place of the
9.4 ones; drop javax.websocket-api.
* HttpServer2: ee8 classes; Handler.Sequence in place of HandlerCollection;
Server#setRequestLog in place of RequestLogHandler; a core handler for
addHandlerAtFront; a /logs context that starts when hadoop.log.dir is missing;
a connector that can reopen a closed listener; the two settings below.
* HttpServer2Metrics: read Jetty 12's handle counters, convert nanoseconds to
milliseconds, publish the five async metrics as 0.
* Import changes to ee8 in the common servlets, McpHttpServer,
ApplicationHistoryServer, ResourceManager, Router, ApiServerWebApp, SLSWebApp
and the tests.
* WebSocket: the client and NodeManager move to the ee8 WebSocket API.
WebApps.Builder gets withServerConfigurer, so the NodeManager can install the
WebSocket components before its context starts.
* The YARN application catalog, only if it is still in the tree: exclude the
ee8 artifacts from its four Hadoop dependencies, so its war keeps Jetty 9.4.
* Tests: TestHttpServer, TestHttpServer2Metrics, TestSSLHttpServer,
TestPseudoAuthenticator, TestCheckpoint and TestNMContainerWebSocket follow
Jetty 12's behaviour.
*Why*: Jetty 9.4 is end of life and its CVEs get no open-source fix
(HADOOP-19910). Jetty 10 and 11 are end of life too, and Jetty 11 and later
otherwise require {{jakarta.servlet}}. Jetty 12's ee8 environment still serves
{{javax.servlet}}, so Hadoop reaches a supported Jetty without the namespace
break. ee8 is a stage, not the destination: the port to Jetty 12's API happens
here once, and HADOOP-19395 is then only the namespace change.
*Incompatible changes*. The reason phrase alone makes this incompatible. This
is the release note:
# *No custom HTTP reason phrase.* The phrase is always the standard text for
the status: "Unauthorized", not "Authentication required". Since HADOOP-20003,
HADOOP-20004 and HADOOP-20005 the message is also in the response body, and
this release's clients read it there. A client that reads only the phrase loses
the message, and an older KMS client no longer re-authenticates on a 403 from
the KMS, because it matches "Invalid signature" and "Anonymous requests are
disallowed" against the phrase.
# *Stricter URI parsing.* {{%2F}}, {{%2E}} segments and malformed encodings are
refused with 400. {{hadoop.http.uri.compliance.violations}} controls what is
allowed through; adding {{AMBIGUOUS_PATH_SEPARATOR}} accepts {{%2F}} again. The
default keeps paths that Hadoop needs, and {{SUSPICIOUS_PATH_CHARACTERS}} in it
also admits the encoded control characters {{%00}}, {{%09}}, {{%0A}}, {{%0D}}
and {{%7F}}, as Jetty 9.4 did.
# *TLS renegotiation is refused.* A client's TLS 1.2 renegotiation closes the
connection. {{hadoop.http.ssl.renegotiation.allowed=true}} restores 9.4's
behaviour.
# *Metrics.* The five async HTTP metrics read 0, because Jetty 12 cannot count
them. The {{dispatched*}} metrics now read Jetty 12's handle counters. All
names, and the milliseconds, are unchanged.
# *A response shorter than its Content-Length fails in the server.* The
servlet's write fails instead of a truncated body reaching the client, so the
error is reported on the other side: a short fsimage transfer now fails on the
NameNode.
# *Jetty's own output differs:* the error-page markup, {{charset=utf-8}} and
{{Vary}} on static files, a {{Date}} header on error responses, the default
acceptor count, and a context path without its trailing slash answering 301
with a relative {{Location}} where 9.4 sent 302 with an absolute one.
# *Internal API and dependencies.* {{InterfaceAudience.Private}} and
{{LimitedPrivate}} classes that name Jetty types now name the ee8 ones:
{{HttpServer2}} ({{addContext}}, {{defineFilter}}, {{getWebAppContext}},
{{addDefaultApps}}), {{WebApps}} and {{ContainerShellWebSocket}}.
{{addHandlerAtFront}} takes a core handler, so an ee8 context goes through
{{getCoreContextHandler()}}. Code calling these must be rebuilt. Jetty's
artifacts move to {{org.eclipse.jetty.ee8}}, so downstream exclusions need the
new coordinates. Public {{javax.servlet}} extension points do not change;
TestDownstreamServletCompatibility pins them.
Everything else keeps 9.4's behaviour: {{/static}} lists no directory,
{{/logs}} keeps its admin check when the log directory is missing, {{web.xml}}
error pages work, a stopped listener can be reopened, the NodeManager's
WebSocket upgrade works, and a {{Location}} set through {{sendRedirect}} stays
absolute.
*New settings*:
||Setting||Default||
|{{hadoop.http.uri.compliance.violations}}|{{AMBIGUOUS_EMPTY_SEGMENT,AMBIGUOUS_PATH_ENCODING,SUSPICIOUS_PATH_CHARACTERS}}|
|{{hadoop.http.ssl.renegotiation.allowed}}|{{false}}|
*Downstream*:
* Projects that use only the public API and {{javax.servlet}}: no rebuild, no
namespace change.
* Non-shaded artifacts: Jetty 12 and {{org.eclipse.jetty.ee8}} jars replace
Jetty 9.4's on the classpath. A project pinning Jetty 9.4 next to Hadoop can no
longer share one Jetty release with it.
* hadoop-client-runtime and hadoop-client-minicluster: the relocated Jetty is
12. Relocated classes are not API.
* The application catalog war keeps Jetty 9.4 through {{solr.jetty.version}}
until HADOOP-19998, if HADOOP-20008 landed. If HADOOP-19998 landed first, the
module is gone and no Jetty 9.4 artifact is left.
*Depends on*: HADOOP-20012, HADOOP-20013, HADOOP-20014, HADOOP-20015,
HADOOP-20016, HADOOP-19970, HADOOP-20003, HADOOP-20004, HADOOP-20005,
HADOOP-20006, HADOOP-20007, and HADOOP-20008 or HADOOP-19998.
*Not in scope*: {{jakarta.servlet}}, Jersey upgrades and ee9, ee10 or ee11:
HADOOP-19395. Guice 6 (HADOOP-19999) and jsr311-api (HADOOP-20000) are not
needed by this issue. HADOOP-19971 belongs to HADOOP-19395, and this issue does
not depend on it. Requires Java 17, so it cannot go to branch-3.3 or branch-3.4.
*CI*: touches hadoop-project, so a full build, including
hadoop-client-check-invariants, hadoop-client-check-test-invariants and
hadoop-client-integration-tests.
*PR*: to be rebuilt on trunk; the draft is
https://github.com/apache/hadoop/pull/8704
was:
Hadoop's web server is Jetty 9.4, which is end of life and gets no security
fixes. Jetty 10 and later require the {{jakarta.servlet}} namespace, which
would break every project that embeds Hadoop's web stack. Jetty 12's ee8
environment still serves {{{}javax.servlet{}}}, so this moves to a supported
Jetty without that break.
Jetty 9.4.58 to 12.1.12 on ee8. No public signature changes, and downstream
projects need not rebuild. {*}Requires Java 17{*}, so it cannot go to
branch-3.3 or branch-3.4. The YARN application catalog webapp stays on Jetty
9.4.58, which Solr 8 needs, but we make it independent, so we can migrate it in
another independent migration action or retire the app.
h2. ee8 is a staging post
ee8 is a stage, not the destination. The point of landing it is that the port
to Jetty 12's API happens here and is not repeated: afterwards Hadoop is on a
supported Jetty, and what remains is the namespace change on its own — ee10 or
ee11 and {{{}jakarta.servlet{}}}, under HADOOP-19395 — instead of a Jetty
upgrade and an API break having to be taken together. ee8 does carry a
compatibility layer that adapts every request, so it is a place to stand for a
release or two rather than indefinitely; unlike Jetty 10 and 11 it has a
supported vendor behind it, which is what makes standing there reasonable.
h2. Incompatible changes
This is the release note. The reason phrase alone makes this incompatible.
# *No custom HTTP reason phrase is sent.* Refusals from the authentication,
KMS and CSRF filters and from image transfer carry their message in the
response body instead, PUT and DELETE included, and Hadoop's clients read it
there. An older client sees the standard phrase: "Unauthorized" rather than
"Authentication required".
# *Stricter URI parsing.* {{{}%2F{}}}, {{%2E}} segments and malformed
encodings are refused with 400. {{hadoop.http.uri.compliance.violations}}
controls what is allowed through.
# *TLS renegotiation is refused.* A client's TLS 1.2 renegotiation closes the
connection. {{hadoop.http.ssl.renegotiation.allowed=true}} restores 9.4's
behaviour.
# *The five async HTTP metrics read 0.* The names and the metric set are
unchanged.
# *Jetty's own output differs:* the error-page markup, charset and {{Vary}} on
static files, a {{Date}} header on error responses, the default acceptor count,
and a context path without its trailing slash redirecting 301 with a relative
{{Location}} where 9.4 sent 302 with an absolute one.
Everything else keeps 9.4's behaviour: {{/static}} lists no directory,
{{/logs}} keeps its admin check when the log directory is missing, {{web.xml}}
error pages work, the HTTP server metrics stay in milliseconds under their
existing names, a stopped listener can be reopened, the NodeManager's web
socket upgrade works, and a redirect's {{Location}} stays absolute.
h2. New settings
||Setting||Default||
|{{hadoop.http.uri.compliance.violations}}|{{AMBIGUOUS_EMPTY_SEGMENT,AMBIGUOUS_PATH_ENCODING,SUSPICIOUS_PATH_CHARACTERS}}|
|{{hadoop.http.ssl.renegotiation.allowed}}|{{false}}|
Adding {{AMBIGUOUS_PATH_SEPARATOR}} to the first accepts {{%2F}} again.
h2. Split out
To keep this issue to the Jetty port itself, the parts that also work on Jetty
9.4 land first, each on its own:
* HADOOP-20003: clients read a refusal's reason from the body
* HADOOP-20004: filters send the reason in the body for every HTTP method
* HADOOP-20005: refused fsimage transfers carry their reason in the body
* HADOOP-20006: {{JettyUtils#clearContentType}}
* HADOOP-20007: test for the downstream javax.servlet contract
* HADOOP-20008: the app catalog's own Jetty version
This issue is blocked by all six. The incompatible changes listed above still
apply; after the split, the only cause of the reason-phrase change is Jetty 12
itself. The app catalog stays on Jetty 9.4 through {{solr.jetty.version}} until
HADOOP-19998.
h2. Not in scope
No move to {{{}jakarta.servlet{}}}, no Jersey upgrade, and no ee9, ee10 or
ee11. HADOOP-19395 lands the namespace change, in a major release;
HADOOP-19912, the umbrella for this move to Jetty 12 ee8, keeps
{{javax.servlet}}. This only stops that decision from blocking the security fix.
> Upgrade to Jetty 12 ee8
> -----------------------
>
> Key: HADOOP-19972
> URL: https://issues.apache.org/jira/browse/HADOOP-19972
> Project: Hadoop Common
> Issue Type: Sub-task
> Components: build, common
> Reporter: Jose Luis López
> Priority: Major
> Labels: pull-request-available
>
> Move Hadoop's web servers from Jetty 9.4.58 to Jetty 12.1.14 on the ee8
> environment, keeping {{javax.servlet}}. This issue is the port only:
> everything that also works on Jetty 9.4 lands first, in the issues under
> *Depends on*.
> *Scope*:
> * hadoop-project/pom.xml: set jetty.version to 12.1.14. Replace the managed
> jetty-servlet, jetty-webapp, javax-websocket-server-impl and websocket-client
> with jetty-ee8-nested, jetty-ee8-servlet, jetty-ee8-webapp,
> jetty-ee8-websocket-jetty-server (excluding jetty-ee8-annotations, which
> brings the banned asm) and jetty-ee8-websocket-jetty-client. Drop
> jetty-servlet-tester, which nothing uses.
> * Rename the Jetty entries in the module poms: hadoop-auth, hadoop-common,
> hadoop-kms, hadoop-hdfs-httpfs, hadoop-yarn-client, hadoop-yarn-common,
> hadoop-yarn-services-api, the ApplicationHistoryServer, the NodeManager, the
> ResourceManager, the Router and timelineservice-hbase-tests. hadoop-sls also
> declares jetty-ee8-nested, and the NodeManager declares the WebSocket client
> for its tests.
> * hadoop-client-runtime and hadoop-client-minicluster: replace the Jetty 9.4
> coordinates in the exclusions and filters with the ee8 and
> jetty-websocket-core ones. The jetty-util exclusions of HADOOP-20014 stay.
> * LICENSE-binary and NOTICE-binary: the Jetty 12.1.14 artifacts in place of
> the 9.4 ones; drop javax.websocket-api.
> * HttpServer2: ee8 classes; Handler.Sequence in place of HandlerCollection;
> Server#setRequestLog in place of RequestLogHandler; a core handler for
> addHandlerAtFront; a /logs context that starts when hadoop.log.dir is
> missing; a connector that can reopen a closed listener; the two settings
> below.
> * HttpServer2Metrics: read Jetty 12's handle counters, convert nanoseconds to
> milliseconds, publish the five async metrics as 0.
> * Import changes to ee8 in the common servlets, McpHttpServer,
> ApplicationHistoryServer, ResourceManager, Router, ApiServerWebApp, SLSWebApp
> and the tests.
> * WebSocket: the client and NodeManager move to the ee8 WebSocket API.
> WebApps.Builder gets withServerConfigurer, so the NodeManager can install the
> WebSocket components before its context starts.
> * The YARN application catalog, only if it is still in the tree: exclude the
> ee8 artifacts from its four Hadoop dependencies, so its war keeps Jetty 9.4.
> * Tests: TestHttpServer, TestHttpServer2Metrics, TestSSLHttpServer,
> TestPseudoAuthenticator, TestCheckpoint and TestNMContainerWebSocket follow
> Jetty 12's behaviour.
> *Why*: Jetty 9.4 is end of life and its CVEs get no open-source fix
> (HADOOP-19910). Jetty 10 and 11 are end of life too, and Jetty 11 and later
> otherwise require {{jakarta.servlet}}. Jetty 12's ee8 environment still
> serves {{javax.servlet}}, so Hadoop reaches a supported Jetty without the
> namespace break. ee8 is a stage, not the destination: the port to Jetty 12's
> API happens here once, and HADOOP-19395 is then only the namespace change.
> *Incompatible changes*. The reason phrase alone makes this incompatible. This
> is the release note:
> # *No custom HTTP reason phrase.* The phrase is always the standard text for
> the status: "Unauthorized", not "Authentication required". Since
> HADOOP-20003, HADOOP-20004 and HADOOP-20005 the message is also in the
> response body, and this release's clients read it there. A client that reads
> only the phrase loses the message, and an older KMS client no longer
> re-authenticates on a 403 from the KMS, because it matches "Invalid
> signature" and "Anonymous requests are disallowed" against the phrase.
> # *Stricter URI parsing.* {{%2F}}, {{%2E}} segments and malformed encodings
> are refused with 400. {{hadoop.http.uri.compliance.violations}} controls what
> is allowed through; adding {{AMBIGUOUS_PATH_SEPARATOR}} accepts {{%2F}}
> again. The default keeps paths that Hadoop needs, and
> {{SUSPICIOUS_PATH_CHARACTERS}} in it also admits the encoded control
> characters {{%00}}, {{%09}}, {{%0A}}, {{%0D}} and {{%7F}}, as Jetty 9.4 did.
> # *TLS renegotiation is refused.* A client's TLS 1.2 renegotiation closes the
> connection. {{hadoop.http.ssl.renegotiation.allowed=true}} restores 9.4's
> behaviour.
> # *Metrics.* The five async HTTP metrics read 0, because Jetty 12 cannot
> count them. The {{dispatched*}} metrics now read Jetty 12's handle counters.
> All names, and the milliseconds, are unchanged.
> # *A response shorter than its Content-Length fails in the server.* The
> servlet's write fails instead of a truncated body reaching the client, so the
> error is reported on the other side: a short fsimage transfer now fails on
> the NameNode.
> # *Jetty's own output differs:* the error-page markup, {{charset=utf-8}} and
> {{Vary}} on static files, a {{Date}} header on error responses, the default
> acceptor count, and a context path without its trailing slash answering 301
> with a relative {{Location}} where 9.4 sent 302 with an absolute one.
> # *Internal API and dependencies.* {{InterfaceAudience.Private}} and
> {{LimitedPrivate}} classes that name Jetty types now name the ee8 ones:
> {{HttpServer2}} ({{addContext}}, {{defineFilter}}, {{getWebAppContext}},
> {{addDefaultApps}}), {{WebApps}} and {{ContainerShellWebSocket}}.
> {{addHandlerAtFront}} takes a core handler, so an ee8 context goes through
> {{getCoreContextHandler()}}. Code calling these must be rebuilt. Jetty's
> artifacts move to {{org.eclipse.jetty.ee8}}, so downstream exclusions need
> the new coordinates. Public {{javax.servlet}} extension points do not change;
> TestDownstreamServletCompatibility pins them.
> Everything else keeps 9.4's behaviour: {{/static}} lists no directory,
> {{/logs}} keeps its admin check when the log directory is missing,
> {{web.xml}} error pages work, a stopped listener can be reopened, the
> NodeManager's WebSocket upgrade works, and a {{Location}} set through
> {{sendRedirect}} stays absolute.
> *New settings*:
> ||Setting||Default||
> |{{hadoop.http.uri.compliance.violations}}|{{AMBIGUOUS_EMPTY_SEGMENT,AMBIGUOUS_PATH_ENCODING,SUSPICIOUS_PATH_CHARACTERS}}|
> |{{hadoop.http.ssl.renegotiation.allowed}}|{{false}}|
> *Downstream*:
> * Projects that use only the public API and {{javax.servlet}}: no rebuild, no
> namespace change.
> * Non-shaded artifacts: Jetty 12 and {{org.eclipse.jetty.ee8}} jars replace
> Jetty 9.4's on the classpath. A project pinning Jetty 9.4 next to Hadoop can
> no longer share one Jetty release with it.
> * hadoop-client-runtime and hadoop-client-minicluster: the relocated Jetty is
> 12. Relocated classes are not API.
> * The application catalog war keeps Jetty 9.4 through {{solr.jetty.version}}
> until HADOOP-19998, if HADOOP-20008 landed. If HADOOP-19998 landed first, the
> module is gone and no Jetty 9.4 artifact is left.
> *Depends on*: HADOOP-20012, HADOOP-20013, HADOOP-20014, HADOOP-20015,
> HADOOP-20016, HADOOP-19970, HADOOP-20003, HADOOP-20004, HADOOP-20005,
> HADOOP-20006, HADOOP-20007, and HADOOP-20008 or HADOOP-19998.
> *Not in scope*: {{jakarta.servlet}}, Jersey upgrades and ee9, ee10 or ee11:
> HADOOP-19395. Guice 6 (HADOOP-19999) and jsr311-api (HADOOP-20000) are not
> needed by this issue. HADOOP-19971 belongs to HADOOP-19395, and this issue
> does not depend on it. Requires Java 17, so it cannot go to branch-3.3 or
> branch-3.4.
> *CI*: touches hadoop-project, so a full build, including
> hadoop-client-check-invariants, hadoop-client-check-test-invariants and
> hadoop-client-integration-tests.
> *PR*: to be rebuilt on trunk; the draft is
> https://github.com/apache/hadoop/pull/8704
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]