From c2df8c172b89f0859f19a472de6199e2ae5ec344 Mon Sep 17 00:00:00 2001 From: Simone Bordet Date: Wed, 30 Sep 2020 10:37:21 +0200 Subject: [PATCH] Improvements to the Jetty documentation. Ported the HTTP/2 documentation. Signed-off-by: Simone Bordet --- .../src/main/config/modules/alpn.mod | 15 +- .../main/asciidoc/old_docs/http2/chapter.adoc | 3 - .../old_docs/http2/configuring-http2.adoc | 72 --------- .../old_docs/http2/enabling-http2.adoc | 75 --------- .../asciidoc/old_docs/http2/introduction.adoc | 54 ------- .../operations-guide/introduction.adoc | 3 + .../operations-guide/keystore/chapter.adoc | 23 +++ .../operations-guide/modules/module-alpn.adoc | 30 ++++ .../modules/module-http2.adoc | 37 +++++ .../modules/module-http2c.adoc | 30 ++++ .../operations-guide/protocols/chapter.adoc | 1 + .../protocols/protocols-http.adoc | 2 +- .../protocols/protocols-http2.adoc | 153 ++++++++++++++++++ .../protocols/protocols-http2c.adoc | 72 +++++++++ .../protocols/protocols-http2s.adoc | 65 ++++++++ .../protocols/protocols-https.adoc | 14 +- .../protocols/protocols-ssl.adoc | 9 +- .../src/main/config/etc/jetty-http2c.xml | 1 + .../src/main/config/modules/http2.mod | 18 +-- .../src/main/config/modules/http2c.mod | 19 ++- .../java/org/eclipse/jetty/start/Module.java | 4 +- 21 files changed, 461 insertions(+), 239 deletions(-) delete mode 100644 jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-http2.adoc delete mode 100644 jetty-documentation/src/main/asciidoc/old_docs/http2/enabling-http2.adoc delete mode 100644 jetty-documentation/src/main/asciidoc/old_docs/http2/introduction.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/keystore/chapter.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/modules/module-alpn.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2c.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2c.adoc create mode 100644 jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2s.adoc diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod index 9fe36cb54b7..eaa55ebe73a 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod +++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn.mod @@ -1,7 +1,5 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - [description] -Enables the ALPN (Application Layer Protocol Negotiation) TLS extension. +Enables the handling of the ALPN (Application Layer Protocol Negotiation) TLS extension. [tag] connector @@ -20,11 +18,12 @@ lib/jetty-alpn-server-${jetty.version}.jar etc/jetty-alpn.xml [ini-template] -## Overrides the order protocols are chosen by the server. -## The default order is that specified by the order of the -## modules declared in start.ini. +# tag::documentation[] +## Specifies the ordered list of application protocols supported by the server. +## The default list is specified by the list of the protocol modules that have +## been enabled, and the order is specified by the module dependencies. # jetty.alpn.protocols=h2,http/1.1 -## Specifies what protocol to use when negotiation fails. +## Specifies the protocol to use when the ALPN negotiation fails. # jetty.alpn.defaultProtocol=http/1.1 - +# end::documentation[] diff --git a/jetty-documentation/src/main/asciidoc/old_docs/http2/chapter.adoc b/jetty-documentation/src/main/asciidoc/old_docs/http2/chapter.adoc index 09ca1ed7e88..eefe585b2de 100644 --- a/jetty-documentation/src/main/asciidoc/old_docs/http2/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/old_docs/http2/chapter.adoc @@ -19,8 +19,5 @@ [[http2]] == HTTP/2 -include::introduction.adoc[] -include::enabling-http2.adoc[] -include::configuring-http2.adoc[] include::configuring-push.adoc[] include::configuring-haproxy.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-http2.adoc b/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-http2.adoc deleted file mode 100644 index 49db2c5c90e..00000000000 --- a/jetty-documentation/src/main/asciidoc/old_docs/http2/configuring-http2.adoc +++ /dev/null @@ -1,72 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under -// the terms of the Eclipse Public License 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0 -// -// This Source Code may also be made available under the following -// Secondary Licenses when the conditions for such availability set -// forth in the Eclipse Public License, v. 2.0 are satisfied: -// the Apache License v2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -[[http2-configuring]] -=== Configuring HTTP/2 - -Enabling the HTTP/2 module in the Jetty server does not create a HTTP/2 specific connector, but rather it adds a HTTP/2 Connection factory to an -existing connector. -Thus configuring HTTP/2 is a combination of configuring common properties on the connector and HTTP/2 specific properties on the connection factory. -The modules and XML files involved can be seen with the following commands: - -[source,screen, subs="{sub-order}"] -.... -$ java -jar $JETTY_HOME/start.jar --list-modules - ... - 1) alpn-impl - ... - 2) http ${jetty.base}/start.d/http.ini - 2) ssl ${jetty.base}/start.d/ssl.ini - 3) alpn ${jetty.base}/start.d/alpn.ini - 3) http2c ${jetty.base}/start.d/http2c.ini - ... - 4) http2 ${jetty.base}/start.d/http2.ini - 5) https ${jetty.base}/start.d/https.ini - -$ java -jar $JETTY_HOME/start.jar --list-config - ... - ${jetty.home}/etc/jetty-ssl.xml - ${jetty.home}/etc/jetty-ssl-context.xml - ${jetty.home}/etc/jetty-alpn.xml - ${jetty.home}/etc/jetty-http2c.xml - ${jetty.home}/etc/jetty-http.xml - ... - ${jetty.home}/etc/jetty-http2.xml - ${jetty.home}/etc/jetty-https.xml -.... - -The common properties associated with connectors (host,port, timeouts, etc.) can be set in the module ini files (or `start.ini` if `--add-to-start` was used): `${jetty.base}/start.d/http.ini` and `${jetty.base}/start.d/ssl.ini`. -These properties are instantiated in the associated XML files: `${jetty.home}/etc/jetty-http.xml`; `${jetty.home}/etc/jetty-ssl.xml`, plus the SSL keystore is instantiated in `${jetty.home}/etc/jetty-ssl-context.xml`. - -____ -[NOTE] -If you are planning to edit XML files, make sure to copy them to your `{$jetty.base}/etc/` directory before doing so. -The XML files that come with the Jetty distribution should *not* be modified directly. -____ - -HTTP/2 specific properties can be set in the module ini files: `${jetty.base}/start.d/http2.ini` and `${jetty.base}/start.d/http2c.ini`, which are instantiated in the associated XML files: `${jetty.home}/etc/jetty-http2.xml`; `${jetty.home}/etc/jetty-http2c.xml`, respectively. -Currently there are very few HTTP/2 configuration properties and the default values are reasonable: - -.HTTP/2 Configuration Properties -[cols=",",options="header",] -|======================================================================= -|Property |Description -|jetty.http2.maxConcurrentStreams |The maximum number of concurrently open streams allowed on a single HTTP/2 connection (default 128). Larger values increase parallelism but cost a memory commitment. -|jetty.http2.initialSessionRecvWindow |The initial receive flow control window size for a new session (default 1048576). Larger values may allow greater throughput but also risk head of line blocking if TCP/IP flow control is triggered. -|jetty.http2.initialStreamRecvWindow |The initial receive flow control window size for a new stream (default 524288). Larger values may allow greater throughput but also risk head of line blocking if TCP/IP flow control is triggered. -|======================================================================= diff --git a/jetty-documentation/src/main/asciidoc/old_docs/http2/enabling-http2.adoc b/jetty-documentation/src/main/asciidoc/old_docs/http2/enabling-http2.adoc deleted file mode 100644 index ebde323405d..00000000000 --- a/jetty-documentation/src/main/asciidoc/old_docs/http2/enabling-http2.adoc +++ /dev/null @@ -1,75 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under -// the terms of the Eclipse Public License 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0 -// -// This Source Code may also be made available under the following -// Secondary Licenses when the conditions for such availability set -// forth in the Eclipse Public License, v. 2.0 are satisfied: -// the Apache License v2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -[[http2-enabling]] -=== Enabling HTTP/2 - -This section is written assuming that a link:#startup-base-and-home[Jetty base directory] is being used. -A demo Jetty base that supports HTTP/1, HTTPS/1 and deployment from a webapps directory can be created with the commands: - -[source, screen, subs="{sub-order}"] -.... -$ JETTY_BASE=http2-demo -$ mkdir $JETTY_BASE -$ cd $JETTY_BASE -$ java -jar $JETTY_HOME/start.jar --add-to-start=http,https,deploy,test-keystore -.... - -The commands above create a `$JETTY_BASE` directory called `http2-demo`, and initializes the `http,` `https` and `deploy` modules (and their dependencies) to run a typical Jetty Server on port 8080 (for HTTP/1) and 8443 (for HTTPS/1). -Note that the `test-keystore` module downloads a demo keystore file with a self signed certificate, which needs to be replaced by a Certificate Authority issued certificate for real deployment. -A keystore can also be added by enabling and configuring the `ssl` module. - -To add HTTP/2 to this demo base, it is just a matter of enabling the `http2` module with the following command: - -[source, screen, subs="{sub-order}"] -.... -$ java -jar $JETTY_HOME/start.jar --add-to-start=http2 -.... - -This command does not create a new connector, but instead simply adds the HTTP/2 protocol to the existing HTTPS/1 connector, so that it now supports both protocols on port 8443. -To do this, it also transitively enables the ALPN module for protocol negotiation. -The support for each protocol can be seen in the info logging when the server is started: - -[source,screen, subs="{sub-order}"] ----- -$ java -jar $JETTY_HOME/start.jar -... -2015-06-17 14:16:12.549:INFO:oejs.ServerConnector:main: Started ServerConnector@34c9c77f{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} -2015-06-17 14:16:12.782:INFO:oejs.ServerConnector:main: Started ServerConnector@711f39f9{SSL,[ssl, alpn, h2, h2-17, http/1.1]}{0.0.0.0:8443} -... ----- - -This log shows that port 8080 supports only HTTP/1.1 (which by specification includes HTTP/1.0 support), while port 8443 supports the SSL protocol, with ALPN negotiation to select between several versions of HTTP/2 (h2 & the draft h2-17) and HTTP/1.1. -What is not shown is that HTTP/1.1 is the default ALPN protocol, so that if a client connects that does not speak ALPN, then HTTP/1.1 will be assumed. - -A browser can now be pointed at `https://localhost:8443/` and if it supports HTTP/2 then it will be used (often indicated by a lightening bolt icon in the address bar). -Note that a browser pointed at this server with URL starting with `http://localhost:8080/` will still talk HTTP/1.1, as HTTP/2 has not been enabled on the plain text connector. - -HTTP/2 can be enabled on the plain text connector and the server restarted with the following command: - -[source,screen] -.... -$ java -jar $JETTY_HOME/start.jar --add-to-start=http2c -$ java -jar $JETTY_HOME/start.jar -.. -2015-06-17 14:16:12.549:INFO:oejs.ServerConnector:main: Started ServerConnector@6f32cd1e{HTTP/1.1,[http/1.1, h2c, h2c-17]}{0.0.0.0:8080} -2015-06-17 14:16:12.782:INFO:oejs.ServerConnector:main: Started ServerConnector@711f39f9{SSL,[ssl, alpn, h2, h2-17, http/1.1]}{0.0.0.0:8443} -.. -.... - -No major browser currently supports plain text HTTP/2, so the 8080 port will only be able to use HTTP/2 with specific clients (eg `curl`) that use the upgrade mechanism or assume HTTP/2. diff --git a/jetty-documentation/src/main/asciidoc/old_docs/http2/introduction.adoc b/jetty-documentation/src/main/asciidoc/old_docs/http2/introduction.adoc deleted file mode 100644 index 2c81f182022..00000000000 --- a/jetty-documentation/src/main/asciidoc/old_docs/http2/introduction.adoc +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under -// the terms of the Eclipse Public License 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0 -// -// This Source Code may also be made available under the following -// Secondary Licenses when the conditions for such availability set -// forth in the Eclipse Public License, v. 2.0 are satisfied: -// the Apache License v2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -[[http2-introduction]] -=== Introducing HTTP/2 - -Jetty supports both a client and a server implementation for the HTTP/2 protocol as defined by http://tools.ietf.org/html/rfc7540[RFC 7540]. - -The requirements for running HTTP/2 are JDK 8 or greater, and typically also ALPN support (see xref:alpn-chapter[]). - -A server deployed over TLS (SSL) normally advertises the HTTP/2 protocol via the TLS extension Application Layer Protocol Negotiation link:#alpn[(ALPN)]. - -____ -[NOTE] -To use HTTP/2 in Jetty via a TLS connector you need to add the link:#alpn-starting[ALPN boot jar] in the boot classpath. -This is done automatically when using the Jetty distribution's start.jar link:#startup-modules[module system], but must be configured directly otherwise. -____ - -[[http2-security-update]] -==== Jetty HTTP/2 Security Update - -In mid-2019, there were a link:#security-reports[number of CVEs] were issued warning against vulnerable HTTP/2 implementations. These CVEs (CVE-2019-9511 thru CVE-2019-9518) generally centered around attackers manipulating and flooding HTTP/2 servers and creating a denial of service (DOS). These vulnerabilities were patched with Jetty 9.4.21. - -As a result of these CVEs, Jetty introduced a new, configurable denial of service (DOS) protection feature in Jetty 9.4.22. - -Jetty’s HTTP/2 implementation now features a new Rate Control parameter, `jetty.http2.rateControl.maxEventsPerSecond`, that defaults to 20 events per second, per connection for all pings, bad frames, settings frames, priority changes etc. - - -[[http2-modules]] -==== Jetty HTTP/2 Sub Projects - -The Jetty HTTP/2 implementation consists of the following sub-projects (each producing a jar file): - -1. `http2-common`: Contains the HTTP/2 API and a partial implementation shared across other modules. -2. `http2-hpack`: Contains the HTTP/2 HPACK implementation for HTTP header compression. -3. `http2-server`: Provides the server-side implementation of HTTP/2. -4. `http2-client`: Provides the implementation of HTTP/2 client with a low level HTTP/2 API, dealing with HTTP/2 streams, frames, etc. -5. `http2-http-client-transport`: Provides the implementation of the HTTP/2 transport for `HttpClient` (see xref:client-http[this section]). -Applications can use the higher level API provided by `HttpClient` to send HTTP requests and receive HTTP responses, and the HTTP/2 transport will take care of converting them in HTTP/2 format (see also https://webtide.com/http2-support-for-httpclient/[this blog entry]). diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/introduction.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/introduction.adoc index a9fe1011160..392b8f4e76f 100644 --- a/jetty-documentation/src/main/asciidoc/operations-guide/introduction.adoc +++ b/jetty-documentation/src/main/asciidoc/operations-guide/introduction.adoc @@ -30,6 +30,7 @@ If you are new to Eclipse Jetty, read xref:og-begin[here] to download, install, If you know Eclipse Jetty already, jump to a feature: * xref:og-sessions[HTTP Session Caching and Clustering] +* xref:og-protocols-http2[HTTP/2 Support] TODO @@ -41,6 +42,8 @@ TODO * xref:og-protocols-http[Configure Clear-Text HTTP/1.1] * xref:og-protocols-https[Configure Secure HTTP/1.1 (https)] +* xref:og-protocols-http2c[Configure Clear-Text HTTP/2] +* xref:og-protocols-http2s[Configure Secure HTTP/2] TODO diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/keystore/chapter.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/keystore/chapter.adoc new file mode 100644 index 00000000000..74693b7a560 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/keystore/chapter.adoc @@ -0,0 +1,23 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-keystore]] +=== Configuring KeyStores + +TODO +// TODO: see old_docs/connectors/configuring-ssl.adoc diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-alpn.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-alpn.adoc new file mode 100644 index 00000000000..44665f51c60 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-alpn.adoc @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-module-alpn]] +==== Module `alpn` + +The `alpn` module enables support for the ALPN negotiation mechanism of the TLS protocol. + +You can configure the list of application protocols negotiated by the ALPN mechanism, as well as the default protocol to use if the ALPN negotiation fails (for example, the client does not support ALPN). + +The module properties are: + +---- +include::{JETTY_HOME}/modules/alpn.mod[tags=documentation] +---- diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2.adoc new file mode 100644 index 00000000000..30dc14d7518 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2.adoc @@ -0,0 +1,37 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-module-http2]] +==== Module `http2` + +The `http2` module enables support for the secure HTTP/2 protocol. + +The module properties are: + +---- +include::{JETTY_HOME}/modules/http2.mod[tags=documentation] +---- + +// tag::rate-control[] +The `jetty.http2.rateControl.maxEventsPerSecond` property controls the number of "bad" or "unnecessary" frames that a client may send before the server closes the connection (with code link:https://tools.ietf.org/html/rfc7540#section-7[`ENHANCE_YOUR_CALM`]) to avoid a denial of service. + +For example, an attacker may send empty `SETTINGS` frames to a server in a tight loop. +While the `SETTINGS` frames don't change the server configuration and each of them is somehow harmless, the server will be very busy processing them because they are sent by the attacker one after the other, causing a CPU spike and eventually a denial of service (as all CPUs will be busy processing empty `SETTINGS` frames). + +The same attack may be performed with `PRIORITY` frames, empty `DATA` frames, `PING` frames, etc. +// end::rate-control[] diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2c.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2c.adoc new file mode 100644 index 00000000000..5b1a435326d --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/modules/module-http2c.adoc @@ -0,0 +1,30 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-module-http2c]] +==== Module `http2c` + +The `http2c` module enables support for the clear-text HTTP/2 protocol. + +The module properties are: + +---- +include::{JETTY_HOME}/modules/http2c.mod[tags=documentation] +---- + +include::module-http2.adoc[tags=rate-control] diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/chapter.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/chapter.adoc index e1c61b3ff73..679f597831d 100644 --- a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/chapter.adoc @@ -38,6 +38,7 @@ $ java -jar $JETTY_HOME/start.jar --list-modules=connector include::protocols-http.adoc[] include::protocols-https.adoc[] +include::protocols-http2.adoc[] include::protocols-ssl.adoc[] // TODO: old_docs/connectors/*.adoc diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http.adoc index 392141dc059..d2e01a5db6b 100644 --- a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http.adoc +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http.adoc @@ -63,7 +63,7 @@ $ java -jar $JETTY_HOME/start.jar --add-module=server Now the `$JETTY_BASE` directory looks like this: -[source,subs=quotes] +[source] ---- JETTY_BASE ├── resources diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2.adoc new file mode 100644 index 00000000000..4df02b34ca1 --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2.adoc @@ -0,0 +1,153 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-protocols-http2]] +==== Configuring HTTP/2 + +link:https://tools.ietf.org/html/rfc7540[HTTP/2] is the successor of the HTTP/1.1 protocol, but it is quite different from HTTP/1.1: where HTTP/1.1 is a duplex, text-based protocol, HTTP/2 is a multiplex, binary protocol. + +Because of these fundamental differences, a client and a server need to _negotiate_ what version of the HTTP protocol they speak, based on what versions each side supports. + +To ensure maximum compatibility, and reduce the possibility that an intermediary that only understands HTTP/1.1 will close the connection when receiving unrecognized HTTP/2 bytes, HTTP/2 is typically deployed over secure connections, using the TLS protocol to wrap HTTP/2. + +IMPORTANT: Browsers only support secure HTTP/2. + +The protocol negotiation is performed by the link:https://tools.ietf.org/html/rfc7301[ALPN TLS extension]: the client advertises the list of protocols it can speak, and the server communicates to the client the protocol chosen by the server. + +For example, you can have a client that only supports HTTP/1.1 and a server that supports both HTTP/1.1 and HTTP/2: + +[plantuml] +---- +skinparam backgroundColor transparent +skinparam monochrome true +skinparam shadowing false + +participant "client\nsupports\nhttp/1.1" as client +participant "server\nsupports\nhttp/1.1 & http/2" as server + +group TLS handshake +client -> server : ClientHello (alpn=[http/1.1]) +server -> server : picks http/1.1 +server -> client : ServerHello (alpn=http/1.1) +...rest of TLS handshake... +end +group TLS HTTP/1.1 +client -> server : HTTP/1.1 GET +server -> client : HTTP/1.1 200 +end +---- + +Nowadays, it's common that both clients and servers support HTTP/2, so servers prefer HTTP/2 as the protocol to speak: + +[plantuml] +---- +skinparam backgroundColor transparent +skinparam monochrome true +skinparam shadowing false + +participant "client\nsupports\nhttp/1.1 & http/2" as client +participant "server\nsupports\nhttp/1.1 & http/2" as server + +group TLS handshake +client -> server : ClientHello (alpn=[http/1.1,h2]) +server -> server : picks http/2 +server -> client : ServerHello (alpn=h2) +...rest of TLS handshake... +end +group TLS HTTP/2 +client -> server : HTTP/2 GET +server -> client : HTTP/2 200 +end +---- + +When you configure a connector with the HTTP/2 protocol, you typically want to also configure the HTTP/1.1 protocol. +The reason to configure both protocols is that you typically do not control the clients: for example an old browser that does not support HTTP/2, or a monitoring console that performs requests using HTTP/1.1, or a heartbeat service that performs a single HTTP/1.0 request to verify that the server is alive. + +==== Secure vs Clear-Text HTTP/2 + +Deciding whether you want to configure Jetty with xref:og-protocols-http2s[secure HTTP/2] or xref:og-protocols-http2c[clear-text HTTP/2] depends on your use case. + +You want to configure secure HTTP/2 when Jetty is exposed directly to browsers, because browsers only support secure HTTP/2. + +[plantuml] +---- +skinparam backgroundColor transparent +skinparam monochrome true +skinparam shadowing false +skinparam roundCorner 10 + +rectangle browser +cloud internet +rectangle jetty + +jetty <--> internet : TLS+HTTP/2 +internet <--> browser : TLS+HTTP/2 +---- + +You may configure clear-text HTTP/2 (mostly for performance reasons) if you offload TLS at a load balancer (for example, link:https://haproxy.org/[HAProxy]) or at a reverse proxy (for example, link:https://nginx.org/[nginx]). + +[plantuml] +---- +skinparam backgroundColor transparent +skinparam monochrome true +skinparam shadowing false +skinparam roundCorner 10 + +rectangle browser +cloud internet +rectangle haproxy +rectangle jetty + +note right of haproxy: TLS offload + +jetty <--> haproxy : HTTP/2 (clear-text) +haproxy <--> internet : TLS+HTTP/2 +internet <--> browser : TLS+HTTP/2 +---- + +You may configure clear-text HTTP/2 (mostly for performance reasons) to call microservices deployed to different Jetty servers (although you may want to use secure HTTP/2 for confidentiality reasons). + +[plantuml] +---- +skinparam backgroundColor transparent +skinparam monochrome true +skinparam shadowing false +skinparam roundCorner 10 + +rectangle browser +cloud internet +rectangle haproxy +rectangle jetty +rectangle microservice1 +rectangle microservice2 +rectangle microservice3 + +note right of haproxy: TLS offload + +internet <--> browser : TLS+HTTP/2 +haproxy <--> internet : TLS+HTTP/2 +jetty <--> haproxy : HTTP/2 (clear-text) +microservice1 <--> jetty : HTTP/2 +microservice2 <--> jetty : HTTP/2 +microservice3 <--> jetty : HTTP/2 +microservice2 <--> microservice3 : HTTP/2 +microservice1 <--> microservice3 : HTTP/2 +---- + +include::protocols-http2s.adoc[] +include::protocols-http2c.adoc[] diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2c.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2c.adoc new file mode 100644 index 00000000000..8909f119f9e --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2c.adoc @@ -0,0 +1,72 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-protocols-http2c]] +==== Configuring Clear-Text HTTP/2 + +When you enable clear-text HTTP/2 you typically want to enable also clear-text HTTP/1.1, for backwards compatibility reasons and to allow clients to link:https://tools.ietf.org/html/rfc7540#section-3.2[upgrade] from HTTP/1.1 to HTTP/2. + +You need to enable: + +* the `http` Jetty module, which provides the clear-text connector and adds the HTTP/1.1 protocol to the clear-text connector +* the `http2c` Jetty module, which adds the HTTP/2 protocol to the clear-text connector + +---- +$ java -jar $JETTY_HOME/start.jar --add-modules=http,http2c +---- + +Starting Jetty yields: + +---- +$ java -jar $JETTY_HOME/start.jar +---- +[source,subs=quotes] +---- +2020-09-30 09:18:36.322:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-29T22:40:09.015Z; git: ba5f91fe00a68804a586b7dd4e2520c8c948dcc8; jvm 15+36-1562 +2020-09-30 09:18:36.349:INFO :oejs.AbstractConnector:main: Started ServerConnector@636be97c##{HTTP/1.1, (http/1.1, h2c)}{0.0.0.0:8080}## +2020-09-30 09:18:36.361:INFO :oejs.Server:main: Started Server@3c72f59f{STARTING}[10.0.0-SNAPSHOT,sto=5000] @526ms +---- + +Note how Jetty is listening on port `8080` and the protocols supported are HTTP/1.1 and `h2c` (i.e. clear-text HTTP/2). + +With this configuration, browsers and client applications will be able to connect to port `8080` using: + +* HTTP/1.1 directly (e.g. `curl --http1.1 ++http://localhost:8080++`): +---- +GET / HTTP/1.1 +Host: localhost:8080 +---- +* HTTP/1.1 with upgrade to HTTP/2 (e.g. `curl --http2 ++http://localhost:8080++`): +---- +GET / HTTP/1.1 +Host: localhost:8080 +Connection: Upgrade, HTTP2-Settings +Upgrade: h2c +HTTP2-Settings: +---- +* HTTP/2 directly (e.g. `curl --http2-prior-knowledge ++http://localhost:8080++`): +---- +50 52 49 20 2a 20 48 54 54 50 2f 32 2e 30 0d 0a +0d 0a 53 4d 0d 0a 0d 0a 00 00 12 04 00 00 00 00 +00 00 03 00 00 00 64 00 04 40 00 00 00 00 02 00 +00 00 00 00 00 1e 01 05 00 00 00 01 82 84 86 41 +8a a0 e4 1d 13 9d 09 b8 f0 1e 07 7a 88 25 b6 50 +c3 ab b8 f2 e0 53 03 2a 2f 2a +---- + +The HTTP/2 protocol parameters can be configured by editing the xref:og-module-http2c[`http2c` module] properties. diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2s.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2s.adoc new file mode 100644 index 00000000000..d171bd5420e --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-http2s.adoc @@ -0,0 +1,65 @@ +// +// ======================================================================== +// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under +// the terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0 +// +// This Source Code may also be made available under the following +// Secondary Licenses when the conditions for such availability set +// forth in the Eclipse Public License, v. 2.0 are satisfied: +// the Apache License v2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +[[og-protocols-http2s]] +==== Configuring Secure HTTP/2 + +When you enable secure HTTP/2 you typically want to enable also secure HTTP/1.1, for backwards compatibility reasons: in this way, old browsers or other clients that do not support HTTP/2 will be able to connect to your server. + +You need to enable: + +* the `ssl` Jetty module, which provides the secure connector and the keystore and TLS configuration +* the `http2` Jetty module, which adds ALPN handling and adds the HTTP/2 protocol to the secured connector +* optionally, the `https` Jetty module, which adds the HTTP/1.1 protocol to the secured connector + +Use the following command (issued from within the `$JETTY_BASE` directory): + +---- +$ java -jar $JETTY_HOME/start.jar --add-modules=ssl,http2,https +---- + +As when enabling the `https` Jetty module, you need a valid keystore (read xref:og-keystore[this section] to create your own keystore). + +As a quick example, you can enable the xref:og-module-test-keystore[`test-keystore` module], that provides a keystore containing a self-signed certificate: + +---- +$ java -jar $JETTY_HOME/start.jar --add-modules=test-keystore +---- + +Starting Jetty yields: + +---- +$ java -jar $JETTY_HOME/start.jar +---- +[source,subs=quotes] +---- +2020-09-29 19:00:47.316:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-29T13:28:40.441Z; git: 9c0082610528a846b366ae26f4c74894579a8e48; jvm 15+36-1562 +2020-09-29 19:00:47.528:INFO :oejus.SslContextFactory:main: x509=X509@7770f470(mykey,h=[localhost],w=[]) for Server@24313fcc[provider=null,keyStore=file:///tmp/jetty.base/etc/test-keystore.p12,trustStore=file:///tmp/jetty.base/etc/test-keystore.p12] +2020-09-29 19:00:47.621:INFO :oejs.AbstractConnector:main: Started ServerConnector@73700b80##{SSL, (ssl, alpn, h2, http/1.1)}{0.0.0.0:8443}## +2020-09-29 19:00:47.630:INFO :oejs.Server:main: Started Server@30ee2816{STARTING}[10.0.0-SNAPSHOT,sto=5000] @746ms +---- + +Note how Jetty is listening on port `8443` and the protocols supported are the sequence `(ssl, alpn, h2, http/1.1)`. + +The (ordered) list of protocols after `alpn` are the _application protocols_, in the example above `(h2, http/1.1)`. + +When a new connection is accepted by the connector, Jetty first interprets the TLS bytes, then it handles the ALPN negotiation knowing that the application protocols are (in order) `h2` and then `http/1.1`. + +You can customize the list of application protocols and the default protocol to use in case the ALPN negotiation fails by editing the xref:og-module-alpn[`alpn` module] properties. + +The HTTP/2 protocol parameters can be configured by editing the xref:og-module-http2[`http2` module] properties. diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-https.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-https.adoc index 56b28aac4b7..fe43c38973f 100644 --- a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-https.adoc +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-https.adoc @@ -45,7 +45,7 @@ Then, the xref:og-module-https[`https` module] adds HTTP/1.1 as the protocol sec The `$JETTY_BASE` directory looks like this: -[source,subs=verbatim] +[source] ---- $JETTY_BASE ├── resources @@ -55,7 +55,7 @@ $JETTY_BASE └── ssl.ini ---- -Note that the keystore file is missing, because you have to provide one with the cryptographic material you want (read xref:og-ssl[this section] to create your own keystore). +Note that the keystore file is missing, because you have to provide one with the cryptographic material you want (read xref:og-keystore[this section] to create your own keystore). You need to configure these two properties by editing `ssl.ini`: * `jetty.sslContext.keyStorePath` @@ -64,7 +64,7 @@ You need to configure these two properties by editing `ssl.ini`: As a quick example, you can enable the xref:og-module-test-keystore[`test-keystore` module], that provides a keystore containing a self-signed certificate: ---- -$ java -jar $JETTY_HOME/start.jar --add-modules=ssl,https +$ java -jar $JETTY_HOME/start.jar --add-modules=test-keystore ---- ---- INFO : test-keystore initialized in ${jetty.base}/start.d/test-keystore.ini @@ -75,6 +75,7 @@ INFO : Base directory was modified The `$JETTY_BASE` directory is now: +[source,subs=quotes] ---- ├── etc │ └── #test-keystore.p12# @@ -100,3 +101,10 @@ $ java -jar $JETTY_HOME/start.jar ---- Note how Jetty is listening on port `8443` for the secure HTTP/1.1 protocol. + +[WARNING] +==== +If you point your browser at `+https://localhost:8443/+` you will get a warning from the browser about a "potential security risk ahead", or that "your connection is not private", or similar message depending on the browser. + +This is normal because the certificate contained in `test-keystore.p12` is self-signed -- and as such not signed by a recognized certificate authority -- and therefore browsers do not trust it. +==== diff --git a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-ssl.adoc b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-ssl.adoc index 8c9ac79a430..0d2032b8d4b 100644 --- a/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-ssl.adoc +++ b/jetty-documentation/src/main/asciidoc/operations-guide/protocols/protocols-ssl.adoc @@ -34,15 +34,14 @@ Keystores may encode the cryptographic material with different encodings, the mo After configuring the keystore path and keystore password, you may want to further customize the parameters of the TLS protocol, such as the minimum TLS protocol version, or the TLS algorithms, etc. -The Jetty `ssl` module allows you to configure the keystore and the TLS parameters; if other modules require encryption, they declare a dependency on the `ssl` module. +The `ssl` Jetty module allows you to configure a secure network connector -- i.e. a connector configured with the TLS protocol, the keystore and the TLS parameters; if other modules require encryption, they declare a dependency on the `ssl` module. -Since the `ssl` module is only about encryption, it does not configure a connector listening on a network port because it does not know what is the wrapped protocol. It is the job of other Jetty modules to configure the wrapped protocol. -For example, it is the xref:og-protocols-https[`https` module] that configures the listening network port for secure HTTP/1.1. -The `https` module depends on the `ssl` module to allow the configuration of keystore and TLS, and adds HTTP/1.1 as the protocol wrapped by TLS. +For example, it is the xref:og-protocols-https[`https` module] that configures the wrapped protocol to be HTTP/1.1. +Similarly, it is the xref:og-protocols-http2[`http2` module] that configures the wrapped protocol to be HTTP/2. -Recall from the xref:og-modules[section about modules], that only modules that are explicitly enabled get their module configuration file (`+*.ini+`) saved in `$JETTY_BASE/start.d/`, and you want `$JETTY_BASE/start.d/ssl.ini` to be present so that you can configure the keystore and TLS properties. +Recall from the xref:og-modules[section about modules], that only modules that are explicitly enabled get their module configuration file (`+*.ini+`) saved in `$JETTY_BASE/start.d/`, and you want `$JETTY_BASE/start.d/ssl.ini` to be present so that you can configure the connector properties, the keystore properties and the TLS properties. // TODO: section about client authentication with certificates? // See readme_keystores.txt about the fact that the server keystore needs the CA=true extension. diff --git a/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml b/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml index e820dd186ff..3f77565aeec 100644 --- a/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml +++ b/jetty-http2/http2-server/src/main/config/etc/jetty-http2c.xml @@ -8,6 +8,7 @@ + diff --git a/jetty-http2/http2-server/src/main/config/modules/http2.mod b/jetty-http2/http2-server/src/main/config/modules/http2.mod index 9a871e39139..f1742041b51 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2.mod @@ -1,8 +1,5 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - [description] -Enables HTTP2 protocol support on the TLS(SSL) Connector with ALPN. -Uses the ALPN extension to select which protocol to use. +Enables the support for the secure HTTP/2 protocol. [tags] connector @@ -21,17 +18,20 @@ lib/http2/*.jar etc/jetty-http2.xml [ini-template] -## Max number of concurrent streams per connection +# tag::documentation[] +## Specifies the maximum number of concurrent requests per session. # jetty.http2.maxConcurrentStreams=128 -## Initial stream receive window (client to server) +## Specifies the initial stream receive window (client to server) in bytes. # jetty.http2.initialStreamRecvWindow=524288 -## Initial session receive window (client to server) +## Specifies the initial session receive window (client to server) in bytes. # jetty.http2.initialSessionRecvWindow=1048576 -## The max number of keys in all SETTINGS frames +## Specifies the maximum number of keys in all SETTINGS frames received by a session. # jetty.http2.maxSettingsKeys=64 -## Max number of bad frames and pings per second +## Specifies the maximum number of bad frames and pings per second, +## after which a session is closed to avoid denial of service attacks. # jetty.http2.rateControl.maxEventsPerSecond=20 +# end::documentation[] diff --git a/jetty-http2/http2-server/src/main/config/modules/http2c.mod b/jetty-http2/http2-server/src/main/config/modules/http2c.mod index be9674850da..46b5364ce0b 100644 --- a/jetty-http2/http2-server/src/main/config/modules/http2c.mod +++ b/jetty-http2/http2-server/src/main/config/modules/http2c.mod @@ -1,8 +1,5 @@ -# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html - [description] -Enables the HTTP2C protocol on the HTTP Connector. -The connector will accept both HTTP/1 and HTTP/2 connections. +Enables the support for the clear-text HTTP/2 protocol. [tags] connector @@ -19,14 +16,20 @@ lib/http2/*.jar etc/jetty-http2c.xml [ini-template] -## Max number of concurrent streams per connection +# tag::documentation[] +## Specifies the maximum number of concurrent requests per session. # jetty.http2c.maxConcurrentStreams=1024 -## Initial stream receive window (client to server) + ## Specifies the initial stream receive window (client to server) in bytes. # jetty.http2c.initialStreamRecvWindow=65535 -## The max number of keys in all SETTINGS frames +## Specifies the initial session receive window (client to server) in bytes. +# jetty.http2.initialSessionRecvWindow=1048576 + +## Specifies the maximum number of keys in all SETTINGS frames received by a session. # jetty.http2.maxSettingsKeys=64 -## Max number of bad frames and pings per second +## Specifies the maximum number of bad frames and pings per second, +## after which a session is closed to avoid denial of service attacks. # jetty.http2.rateControl.maxEventsPerSecond=20 +# end::documentation[] diff --git a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java index 6e4d9ceb68d..8047da2c816 100644 --- a/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java +++ b/jetty-start/src/main/java/org/eclipse/jetty/start/Module.java @@ -375,7 +375,9 @@ public class Module implements Comparable // for the [ini-template] section if ("INI-TEMPLATE".equals(sectionType)) { - _iniTemplate.add(line); + // Exclude asciidoc tag lines used in documentation. + if (!line.contains("tag::") && !line.contains("end::")) + _iniTemplate.add(line); } } else