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

fix: match SNI when using TLS listeners with hostname #2942

Merged
merged 8 commits into from
May 10, 2024

Conversation

michaelbeaumont
Copy link
Contributor

What type of PR is this?

A fix for TLS listener with hostname handling.

What this PR does / why we need it:

This PR sets filterChainMatch.serverNames when using TLS listeners with a hostname.

Which issue(s) this PR fixes:

@michaelbeaumont michaelbeaumont requested a review from a team as a code owner March 15, 2024 17:12
@michaelbeaumont michaelbeaumont force-pushed the feat/tls-terminate-hostname branch from 62584b7 to 992dd33 Compare March 15, 2024 17:13
@arkodg
Copy link
Contributor

arkodg commented Mar 15, 2024

hey @michaelbeaumont, for my understanding, is this PR is trying to solve ?

Listener Protocol: TLS
TLS Mode: Terminate
Route Type: TCPRoute

https://gateway-api.sigs.k8s.io/guides/tls/#clientserver-and-tls

afaik this should be supported today
#1431
https://gateway.envoyproxy.io/v1.0.0/user/security/tls-termination/

@michaelbeaumont
Copy link
Contributor Author

michaelbeaumont commented Mar 15, 2024

Hey, yeah traffic is terminated properly, but if I set hostname on that listener, there's no filtering of traffic by SNI as specified by the spec for hostname. The final commit shows the difference for this listener.

Implementations MUST apply Hostname matching appropriately for each of the following protocols:

  • TLS: The Listener Hostname MUST match the SNI.

@arkodg
Copy link
Contributor

arkodg commented Mar 15, 2024

got it makes sense, thanks for clarifying !
is there a way to modify the TCP Listener IR w/o affecting the HTTP Listener IR structure and achieving the same goal ?
Currently the Hostnames field within the HTTP Listener is used for Filter Chain creation with a server_name constaint

Copy link
Member

@zhaohuabing zhaohuabing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@michaelbeaumont Thank you for addressing the issue! A few comments.

// +k8s:deepcopy-gen=true
type TLSInspectorConfig struct {
// Server names that are compared against the server names of a new connection.
// Wildcard hosts are supported in the prefix form. Partial wildcards are not
// supported, and values like *w.example.com are invalid.
// SNIs are used only in case of TLS Passthrough.
SNIs []string `json:"snis,omitempty" yaml:"snis,omitempty"`
Copy link
Member

@zhaohuabing zhaohuabing Mar 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving SNIs up to TLSConfig and removing TLSInspectorConfig?

TLS Inspector is an implementation detail of Envoy, so we probably don't need to expose it to ir.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's already exposed as TLS.Passthrough isn't it? I can add SNIs directly to TLSConfig if you prefer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote for making TLSInspectorConfig an embedded field within TLS

type TLS struct {
, removing the need for a dedicated Passthrough field

  • passthrough logic can be computed using - isTLSPassthrough := irListener.TLS != nil && irListener.TLS.Terminate == nil
  • this also eliminates the need to add Inspector into the TLSConfig field, which is common to HTTPS, which uses another field (listener.Hostname) for SNI inspection

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed an update here, it changes a different part of the IR though, passthrough -> inspector, since that's now common between mode: Terminate and mode: Passthrough

Copy link
Member

@zhaohuabing zhaohuabing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add multiple hostnames in the gateway API translator and XDS translator tests for TLS termination? This could cover the scenario where a single listener needs to handle multiple SNIs. Thanks!

@shuji-2019
Copy link

Is there any updates for this feature ?

@michaelbeaumont michaelbeaumont force-pushed the feat/tls-terminate-hostname branch from 522da6a to 4d6da72 Compare April 21, 2024 14:01
@zirain zirain requested review from zhaohuabing and arkodg April 23, 2024 01:23
@arkodg arkodg added this to the v1.1.0-rc1 milestone May 7, 2024
@aoledk
Copy link
Contributor

aoledk commented May 8, 2024

@michaelbeaumont Are you still working on this? If not I can help, based on your previous work.

@michaelbeaumont michaelbeaumont force-pushed the feat/tls-terminate-hostname branch from ac557ab to 2fdf048 Compare May 9, 2024 21:49
@michaelbeaumont
Copy link
Contributor Author

Updated and merged

@@ -1082,6 +1082,14 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
accepted = true
irKey := t.getIRKey(listener.gateway)

tls := ir.TLS{
Copy link
Contributor

@arkodg arkodg May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldnt this be executed conditionally ?
e.g.

if listener.TLS != nil {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think anything's changed here, previously we set unconditionally:

TLS: &ir.TLS{Terminate: irTLSConfigs(listener.tlsSecrets)},

irTLSConfigs returns nil if there aren't any secrets. The line you linked to is also gated by checking the listener protocol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool thanks for the checking!

@arkodg
Copy link
Contributor

arkodg commented May 10, 2024

@michaelbeaumont 'make lint's is failing because of trailing whitespaces, once that's fixed, LGTM from my end !

@arkodg
Copy link
Contributor

arkodg commented May 10, 2024

@michaelbeaumont can you also fix DCO and force push ?

Signed-off-by: Mike Beaumont <[email protected]>
@michaelbeaumont michaelbeaumont force-pushed the feat/tls-terminate-hostname branch from 30c4ab6 to 911aa09 Compare May 10, 2024 21:42
Copy link
Contributor

@arkodg arkodg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks !

@arkodg arkodg requested review from a team May 10, 2024 22:42
Copy link
Member

@zhaohuabing zhaohuabing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks!

It would be helpful if we wcould cover two snis on the same port in the xds translation test. But this can be added later.

@arkodg arkodg merged commit c30d09f into envoyproxy:main May 10, 2024
20 checks passed
@michaelbeaumont michaelbeaumont deleted the feat/tls-terminate-hostname branch May 10, 2024 23:56
@michaelbeaumont
Copy link
Contributor Author

@zhaohuabing I added another SNI to the test https://github.com/envoyproxy/gateway/pull/2942/files#diff-3481ca7cb1d20b614db1882fa576de2d303d434e519a17d12c2792436d6a0e18R28 actually

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants