Skip to content

Commit

Permalink
release-1.24: Backport #5827 and #5850 (#5853)
Browse files Browse the repository at this point in the history
* Add configurability for HTTP requests per IO cycle (#5827)

An additional mitigation to CVE-2023-44487 available in Envoy 1.27.1.
This change allows configuring the http.max_requests_per_io_cycle Envoy
runtime setting via Contour configuration to allow administrators of
Contour to prevent abusive connections from starving resources from
others. The default is left as the existing behavior, that is no limit,
so as not to impact existing valid traffic.

See the Envoy release notes for more information:
https://www.envoyproxy.io/docs/envoy/v1.27.1/version_history/v1.27/v1.27.1

* HTTP/2 max concurrent streams can be configured (#5850)

Adds a global Listener configuration field for admins to be able to
protect their installations of Contour/Envoy with a limit. Default is no
limit to ensure existing behavior is not impacted for valid traffic.
This field can be used for tuning resource usage or mitigated DOS
attacks like in CVE-2023-44487.

Also fixes omitempty tags on MaxRequestsPerIOCycle field.

Signed-off-by: Sunjay Bhatia <[email protected]>
  • Loading branch information
sunjayBhatia authored Oct 16, 2023
1 parent 4d50ef8 commit e86620a
Show file tree
Hide file tree
Showing 26 changed files with 733 additions and 35 deletions.
21 changes: 21 additions & 0 deletions apis/projectcontour/v1alpha1/contourconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,27 @@ type EnvoyListenerConfig struct {
// TLS holds various configurable Envoy TLS listener values.
// +optional
TLS *EnvoyTLS `json:"tls,omitempty"`

// Defines the limit on number of HTTP requests that Envoy will process from a single
// connection in a single I/O cycle. Requests over this limit are processed in subsequent
// I/O cycles. Can be used as a mitigation for CVE-2023-44487 when abusive traffic is
// detected. Configures the http.max_requests_per_io_cycle Envoy runtime setting. The default
// value when this is not set is no limit.
//
// +kubebuilder:validation:Minimum=1
// +optional
MaxRequestsPerIOCycle *uint32 `json:"maxRequestsPerIOCycle,omitempty"`

// Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS Envoy will advertise in the
// SETTINGS frame in HTTP/2 connections and the limit for concurrent streams allowed
// for a peer on a single HTTP/2 connection. It is recommended to not set this lower
// than 100 but this field can be used to bound resource usage by HTTP/2 connections
// and mitigate attacks like CVE-2023-44487. The default value when this is not set is
// unlimited.
//
// +kubebuilder:validation:Minimum=1
// +optional
HTTP2MaxConcurrentStreams *uint32 `json:"httpMaxConcurrentStreams,omitempty"`
}

// EnvoyTLS describes tls parameters for Envoy listneners.
Expand Down
10 changes: 10 additions & 0 deletions apis/projectcontour/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions changelogs/unreleased/5827-sunjayBhatia-minor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Max HTTP requests per IO cycle is configurable as an additional mitigation for HTTP/2 CVE-2023-44487

Envoy v1.27.1 mitigates CVE-2023-44487 with some default runtime settings, however the `http.max_requests_per_io_cycle` does not have a default value.
This change allows configuring this runtime setting via Contour configuration to allow administrators of Contour to prevent abusive connections from starving resources from other valid connections.
The default is left as the existing behavior (no limit) so as not to impact existing valid traffic.

The Contour ConfigMap can be modified similar to the following (and Contour restarted) to set this value:

```
listener:
max-requests-per-io-cycle: 10
```

(Note this can be used in addition to the existing Listener configuration field `listener.max-requests-per-connection` which is used primarily for HTTP/1.1 connections and is an approximate limit for HTTP/2)

See the [Envoy release notes](https://www.envoyproxy.io/docs/envoy/v1.27.1/version_history/v1.27/v1.27.1) for more details.
11 changes: 11 additions & 0 deletions changelogs/unreleased/5850-sunjayBhatia-minor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## HTTP/2 max concurrent streams is configurable

This field can be used to limit the number of concurrent streams Envoy will allow on a single connection from a downstream peer.
It can be used to tune resource usage and as a mitigation for DOS attacks arising from vulnerabilities like CVE-2023-44487.

The Contour ConfigMap can be modified similar to the following (and Contour restarted) to set this value:

```
listener:
http2-max-concurrent-streams: 50
```
5 changes: 4 additions & 1 deletion cmd/contour/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ func (s *Server) doServe() error {
ServerHeaderTransformation: contourConfiguration.Envoy.Listener.ServerHeaderTransformation,
XffNumTrustedHops: *contourConfiguration.Envoy.Network.XffNumTrustedHops,
ConnectionBalancer: contourConfiguration.Envoy.Listener.ConnectionBalancer,
HTTP2MaxConcurrentStreams: contourConfiguration.Envoy.Listener.HTTP2MaxConcurrentStreams,
}

if listenerConfig.RateLimitConfig, err = s.setupRateLimitService(contourConfiguration); err != nil {
Expand All @@ -383,7 +384,9 @@ func (s *Server) doServe() error {
&xdscache_v3.RouteCache{},
&xdscache_v3.ClusterCache{},
endpointHandler,
&xdscache_v3.RuntimeCache{},
xdscache_v3.NewRuntimeCache(xdscache_v3.ConfigurableRuntimeSettings{
MaxRequestsPerIOCycle: contourConfiguration.Envoy.Listener.MaxRequestsPerIOCycle,
}),
}

// snapshotHandler is used to produce new snapshots when the internal state changes for any xDS resource.
Expand Down
2 changes: 2 additions & 0 deletions cmd/contour/servecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,8 @@ func (ctx *serveContext) convertToContourConfigurationSpec() contour_api_v1alpha
DisableMergeSlashes: &ctx.Config.DisableMergeSlashes,
ServerHeaderTransformation: serverHeaderTransformation,
ConnectionBalancer: ctx.Config.Listener.ConnectionBalancer,
MaxRequestsPerIOCycle: ctx.Config.Listener.MaxRequestsPerIOCycle,
HTTP2MaxConcurrentStreams: ctx.Config.Listener.HTTP2MaxConcurrentStreams,
TLS: &contour_api_v1alpha1.EnvoyTLS{
MinimumProtocolVersion: ctx.Config.TLS.MinimumProtocolVersion,
CipherSuites: cipherSuites,
Expand Down
12 changes: 12 additions & 0 deletions cmd/contour/servecontext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,18 @@ func TestConvertServeContext(t *testing.T) {
return cfg
},
},
"envoy listener settings": {
getServeContext: func(ctx *serveContext) *serveContext {
ctx.Config.Listener.MaxRequestsPerIOCycle = ref.To(uint32(10))
ctx.Config.Listener.HTTP2MaxConcurrentStreams = ref.To(uint32(30))
return ctx
},
getContourConfiguration: func(cfg contour_api_v1alpha1.ContourConfigurationSpec) contour_api_v1alpha1.ContourConfigurationSpec {
cfg.Envoy.Listener.MaxRequestsPerIOCycle = ref.To(uint32(10))
cfg.Envoy.Listener.HTTP2MaxConcurrentStreams = ref.To(uint32(30))
return cfg
},
},
}

for name, tc := range cases {
Expand Down
47 changes: 47 additions & 0 deletions examples/contour/01-crds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,29 @@ spec:
slashes from request URL paths. \n Contour's default is
false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2 connections
and the limit for concurrent streams allowed for a peer
on a single HTTP/2 connection. It is recommended to not
set this lower than 100 but this field can be used to bound
resource usage by HTTP/2 connections and mitigate attacks
like CVE-2023-44487. The default value when this is not
set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in a single
I/O cycle. Requests over this limit are processed in subsequent
I/O cycles. Can be used as a mitigation for CVE-2023-44487
when abusive traffic is detected. Configures the http.max_requests_per_io_cycle
Envoy runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the Server
header on the response path. When configured as overwrite,
Expand Down Expand Up @@ -3197,6 +3220,30 @@ spec:
duplicate slashes from request URL paths. \n Contour's
default is false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2
connections and the limit for concurrent streams allowed
for a peer on a single HTTP/2 connection. It is recommended
to not set this lower than 100 but this field can be
used to bound resource usage by HTTP/2 connections and
mitigate attacks like CVE-2023-44487. The default value
when this is not set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in
a single I/O cycle. Requests over this limit are processed
in subsequent I/O cycles. Can be used as a mitigation
for CVE-2023-44487 when abusive traffic is detected.
Configures the http.max_requests_per_io_cycle Envoy
runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the
Server header on the response path. When configured
Expand Down
47 changes: 47 additions & 0 deletions examples/render/contour-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,29 @@ spec:
slashes from request URL paths. \n Contour's default is
false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2 connections
and the limit for concurrent streams allowed for a peer
on a single HTTP/2 connection. It is recommended to not
set this lower than 100 but this field can be used to bound
resource usage by HTTP/2 connections and mitigate attacks
like CVE-2023-44487. The default value when this is not
set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in a single
I/O cycle. Requests over this limit are processed in subsequent
I/O cycles. Can be used as a mitigation for CVE-2023-44487
when abusive traffic is detected. Configures the http.max_requests_per_io_cycle
Envoy runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the Server
header on the response path. When configured as overwrite,
Expand Down Expand Up @@ -3410,6 +3433,30 @@ spec:
duplicate slashes from request URL paths. \n Contour's
default is false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2
connections and the limit for concurrent streams allowed
for a peer on a single HTTP/2 connection. It is recommended
to not set this lower than 100 but this field can be
used to bound resource usage by HTTP/2 connections and
mitigate attacks like CVE-2023-44487. The default value
when this is not set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in
a single I/O cycle. Requests over this limit are processed
in subsequent I/O cycles. Can be used as a mitigation
for CVE-2023-44487 when abusive traffic is detected.
Configures the http.max_requests_per_io_cycle Envoy
runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the
Server header on the response path. When configured
Expand Down
47 changes: 47 additions & 0 deletions examples/render/contour-gateway-provisioner.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,29 @@ spec:
slashes from request URL paths. \n Contour's default is
false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2 connections
and the limit for concurrent streams allowed for a peer
on a single HTTP/2 connection. It is recommended to not
set this lower than 100 but this field can be used to bound
resource usage by HTTP/2 connections and mitigate attacks
like CVE-2023-44487. The default value when this is not
set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in a single
I/O cycle. Requests over this limit are processed in subsequent
I/O cycles. Can be used as a mitigation for CVE-2023-44487
when abusive traffic is detected. Configures the http.max_requests_per_io_cycle
Envoy runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the Server
header on the response path. When configured as overwrite,
Expand Down Expand Up @@ -3211,6 +3234,30 @@ spec:
duplicate slashes from request URL paths. \n Contour's
default is false."
type: boolean
httpMaxConcurrentStreams:
description: Defines the value for SETTINGS_MAX_CONCURRENT_STREAMS
Envoy will advertise in the SETTINGS frame in HTTP/2
connections and the limit for concurrent streams allowed
for a peer on a single HTTP/2 connection. It is recommended
to not set this lower than 100 but this field can be
used to bound resource usage by HTTP/2 connections and
mitigate attacks like CVE-2023-44487. The default value
when this is not set is unlimited.
format: int32
minimum: 1
type: integer
maxRequestsPerIOCycle:
description: Defines the limit on number of HTTP requests
that Envoy will process from a single connection in
a single I/O cycle. Requests over this limit are processed
in subsequent I/O cycles. Can be used as a mitigation
for CVE-2023-44487 when abusive traffic is detected.
Configures the http.max_requests_per_io_cycle Envoy
runtime setting. The default value when this is not
set is no limit.
format: int32
minimum: 1
type: integer
serverHeaderTransformation:
description: "Defines the action to be applied to the
Server header on the response path. When configured
Expand Down
Loading

0 comments on commit e86620a

Please sign in to comment.