Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(translator): client tls session resumption #4293

Merged
merged 25 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions api/v1alpha1/tls_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ type ClientTLSSettings struct {
// +optional
ClientValidation *ClientValidationContext `json:"clientValidation,omitempty"`
TLSSettings `json:",inline"`

zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
// Session defines settings related to TLS session management.
// +optional
Session *Session `json:"session,omitempty"`
}

// +kubebuilder:validation:XValidation:rule="has(self.minVersion) && self.minVersion == '1.3' ? !has(self.ciphers) : true", message="setting ciphers has no effect if the minimum possible TLS version is 1.3"
Expand Down Expand Up @@ -133,3 +137,40 @@ type ClientValidationContext struct {
// +optional
CACertificateRefs []gwapiv1.SecretObjectReference `json:"caCertificateRefs,omitempty"`
}

// Session defines settings related to TLS session management.
type Session struct {
// Resumption determines the proxy's supported TLS session resumption option.
// By default, Envoy Gateway does not enable session resumption. Use sessionResumption to
// enable stateful and stateless session resumption. Users should consider security impacts
// of different resumption methods. Performance gains from resumption are diminished when
// Envoy proxy is deployed with more than one replica.
// +optional
Resumption *SessionResumption `json:"resumption,omitempty"`
}

// SessionResumption defines supported tls session resumption methods and their associated configuration.
type SessionResumption struct {
// Stateless defines setting for stateless (session-ticket based) session resumption
// +optional
Stateless *StatelessTLSSessionResumption `json:"stateless,omitempty"`

// Stateful defines setting for stateful (session-id based) session resumption
// +optional
Stateful *StatefulTLSSessionResumption `json:"stateful,omitempty"`
}

// StatefulTLSSessionResumption defines the stateful (session-id based) type of TLS session resumption.
// Note: When Envoy Proxy is deployed with more than one replica, session caches are not synchronized
// between instances, possibly leading to resumption failures.
// Envoy does not re-validate client certificates upon session resumption.
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-routematch-tlscontextmatchoptions
type StatefulTLSSessionResumption struct{}

// StatelessTLSSessionResumption defines the stateless (session-ticket based) type of TLS session resumption.
// Note: When Envoy Proxy is deployed with more than one replica, session ticket encryption keys are not
// synchronized between instances, possibly leading to resumption failures.
// In-memory session ticket encryption keys are rotated every 48 hours.
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/transport_sockets/tls/v3/common.proto#extensions-transport-sockets-tls-v3-tlssessionticketkeys
// https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Session-tickets
type StatelessTLSSessionResumption struct{}
80 changes: 80 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,27 @@ spec:
- "1.2"
- "1.3"
type: string
session:
description: Session defines settings related to TLS session management.
properties:
resumption:
description: |-
Resumption determines the proxy's supported TLS session resumption option.
By default, Envoy Gateway does not enable session resumption. Use sessionResumption to
enable stateful and stateless session resumption. Users should consider security impacts
of different resumption methods. Performance gains from resumption are diminished when
Envoy proxy is deployed with more than one replica.
properties:
stateful:
description: Stateful defines setting for stateful (session-id
based) session resumption
type: object
stateless:
description: Stateless defines setting for stateless (session-ticket
based) session resumption
type: object
type: object
type: object
signatureAlgorithms:
description: |-
SignatureAlgorithms specifies which signature algorithms the listener should
Expand Down
9 changes: 9 additions & 0 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,15 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli
}
}

if tlsParams.Session != nil && tlsParams.Session.Resumption != nil {
if tlsParams.Session.Resumption.Stateless != nil {
irTLSConfig.StatelessSessionResumption = true
}
if tlsParams.Session.Resumption.Stateful != nil {
irTLSConfig.StatefulSessionResumption = true
}
}

return irTLSConfig, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ clientTrafficPolicies:
signatureAlgorithms:
- sig1
- sig2
session:
resumption:
stateless: {}
stateful: {}
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ clientTrafficPolicies:
- curve1
maxVersion: "1.3"
minVersion: "1.0"
session:
resumption:
stateful: {}
stateless: {}
signatureAlgorithms:
- sig1
- sig2
Expand Down Expand Up @@ -174,6 +178,8 @@ xdsIR:
signatureAlgorithms:
- sig1
- sig2
statefulSessionResumption: true
statelessSessionResumption: true
- address: 0.0.0.0
hostnames:
- '*'
Expand Down
4 changes: 4 additions & 0 deletions internal/ir/xds.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ type TLSConfig struct {
SignatureAlgorithms []string `json:"signatureAlgorithms,omitempty" yaml:"signatureAlgorithms,omitempty"`
// ALPNProtocols exposed by this listener
ALPNProtocols []string `json:"alpnProtocols,omitempty" yaml:"alpnProtocols,omitempty"`
// StatelessSessionResumption determines if stateless (session-ticket based) session resumption is enabled
StatelessSessionResumption bool `json:"statelessSessionResumption,omitempty" yaml:"statelessSessionResumption,omitempty"`
// StatefulSessionResumption determines if stateful (session-id based) session resumption is enabled
StatefulSessionResumption bool `json:"statefulSessionResumption,omitempty" yaml:"statefulSessionResumption,omitempty"`
}

// TLSCertificate holds a single certificate's details
Expand Down
16 changes: 16 additions & 0 deletions internal/xds/translator/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,8 @@ func buildDownstreamQUICTransportSocket(tlsConfig *ir.TLSConfig) (*corev3.Transp
}
}

setDownstreamTLSSessionSettings(tlsConfig, tlsCtx.DownstreamTlsContext)

tlsCtxAny, err := anypb.New(tlsCtx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -664,6 +666,8 @@ func buildXdsDownstreamTLSSocket(tlsConfig *ir.TLSConfig) (*corev3.TransportSock
}
}

setDownstreamTLSSessionSettings(tlsConfig, tlsCtx)

tlsCtxAny, err := anypb.New(tlsCtx)
if err != nil {
return nil, err
Expand All @@ -677,6 +681,18 @@ func buildXdsDownstreamTLSSocket(tlsConfig *ir.TLSConfig) (*corev3.TransportSock
}, nil
}

func setDownstreamTLSSessionSettings(tlsConfig *ir.TLSConfig, tlsCtx *tlsv3.DownstreamTlsContext) {
if !tlsConfig.StatefulSessionResumption {
tlsCtx.DisableStatefulSessionResumption = true
}

if !tlsConfig.StatelessSessionResumption {
tlsCtx.SessionTicketKeysType = &tlsv3.DownstreamTlsContext_DisableStatelessSessionResumption{
DisableStatelessSessionResumption: true,
}
}
}

func buildTLSParams(tlsConfig *ir.TLSConfig) *tlsv3.TlsParameters {
p := &tlsv3.TlsParameters{}
isEmpty := true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ http:
minVersion: "1.0"
alpnProtocols:
- some-other-protocol
statefulSessionResumption: true
certificates:
- name: secret-1
# byte slice representation of "key-data"
Expand Down Expand Up @@ -107,6 +108,7 @@ tcp:
minVersion: "1.0"
alpnProtocols:
- some-other-protocol
statelessSessionResumption: true
certificates:
- name: secret-3
# byte slice representation of "key-data"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
name: envoy-gateway/gateway-1/tls-quic
udpListenerConfig:
downstreamSocketConfig: {}
Expand Down Expand Up @@ -96,5 +98,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
name: envoy-gateway/gateway-1/tls
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
listenerFilters:
- name: envoy.filters.listener.proxy_protocol
typedConfig:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,7 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
name: first-listener
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
- filterChainMatch:
serverNames:
- foo.net
Expand Down Expand Up @@ -117,6 +119,8 @@
sdsConfig:
ads: {}
resourceApiVersion: V3
disableStatefulSessionResumption: true
disableStatelessSessionResumption: true
- filterChainMatch:
serverNames:
- bar.com
Expand Down
Loading