-
Notifications
You must be signed in to change notification settings - Fork 472
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
Adds Per Route TLS Config to Gateway API Type #71
Conversation
@danehans: GitHub didn't allow me to request PR reviews from the following users: ironcladlou, Miciah. Note that only kubernetes-sigs members and repo collaborators can review this PR, and authors cannot review their own PRs. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
api/v1alpha1/gateway_types.go
Outdated
// Support: Core | ||
// | ||
// +optional | ||
Routes []core.ObjectReference `json:"routes,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are these Routes for? How do these Routes interact with the Routes on the Gateway?
Currently, Routes are properties of the Gateway, which implies that they are available on all listeners. Moving Routes to a listener could make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jpeach thanks for the review. This Routes
field is meant to (optionally) provide the ability to associate the TLS termination policy to specific routes. This could be done in the xRoute
resource, but then Devs would have that control instead of cluster admins. These routes could be all or a subset of routes that are bound to the gateway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to remove the route reference for now and make the termination policy a listener-scoped setting.
api/v1alpha1/gateway_types.go
Outdated
// Support: Core | ||
// | ||
// +optional | ||
TerminationPolicy TLSTerminationPolicy `json:"terminationPolicy,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If termination type is a property of the listener, how can we satisfy different termination needs for different backends? In the common case, I expect there is only one TLS listener on port 443, and some backends will want Edge
and others will want Passthrough
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me push a new commit for addressing this use case.
api/v1alpha1/gateway_types.go
Outdated
|
||
// TLSTerminationPassthrough terminates the TLS connection at the | ||
// destination service. The destination service is responsible for | ||
// decrypting data from the connection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should specify the requirements on the gateway for passthrough termination. The Gateway should enforce that the protocol is actually TLS. Is SNI required for route selection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the protocol should be TLS and I would expect SNI for route selection. I tried to address some of these details in #76.
api/v1alpha1/gateway_types.go
Outdated
// Support: Implementation-specific (For other resource types) | ||
// | ||
// +optional | ||
CACertificates []core.TypedLocalObjectReference `json:"caCertificates,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we require specific secret types for this? (IMHO, yes we should)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is server TLS policy for the listener, I think that we should not also be specifying the client TLS policy for re-ecrypting traffic to the backend. That client policy could have different validation policy, version requirements, client certificates, and all sorts of things that are awkward to express here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jpeach I'm pushing a new commit where the TLS termination policy is associated to a Route
within a Gateway
.
api/v1alpha1/gateway_types.go
Outdated
// TLSTerminationReencrypt terminates the TLS connection at the gateway. | ||
// The gateway creates an encrypted connection to the destination service | ||
// using the provided certificate from DestinationCACertificate. | ||
TLSTerminationReencrypt TLSTerminationType = "Reencrypt" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure that there are 3 cases. Another way to look at it is that we have 2 independent decisions
- terminate TLS
- proxy over TCP
- proxy over TLS
- don't terminate TLS
- proxy over TCP
- proxy over TLS
So, in this view, re-encryption is a property of the backend route.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where you're coming from. "Reencrypt" could be a route filter.
@Miciah either route type can be encapsulated in TLS. The TLS handshake will occur between client and gateway (non-passthrough mode). The gateway will select the appropriate certificate based on the SNI hostname in the client's hello message. If mode is |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: danehans The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
cc28347
to
63e2d58
Compare
66e5acd
to
266d652
Compare
xref #74 |
Are you saying the gateway controller will forward the decrypted packets to a |
// Route defines the schema for a route. | ||
type Route struct { | ||
// RouteRef is a reference to an object to associate with the Gateway. | ||
// RouteRef defines protocol-specific routing to back-ends (e.g. Services). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really what a Route is? Looking at the current spec, TcpRoute
and HTTPRoute
are defined. To my mind these have more in common with endpoints (since we are in a reverse-proxy configuration, they will appear to be endpoints from the perspective of the client).
I realize that this terminology is already in play, but maybe we can clarify here. The description of "routing to back-ends" seems more applicable to HTTPRouteAction
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you define more what "endpoint" and "client" you mention in the above.
Endpoint e.g. k8s Endpoint? Or something else?
Client as in the HTTP-client coming to the Gateway (or something else)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The purpose of the Route
type is to group attributes with the route reference. Currently, we're focused on TLS, but I can foresee other attributes a Cluster Operator may want to associate to a route, e.g. a traffic shaping policy.
api/v1alpha1/gateway_types.go
Outdated
Routes []core.TypedLocalObjectReference `json:"routes"` | ||
// Routes defines routes to associate with the Gateway. | ||
// | ||
// If unspecified, all routes will be associated to the Gateway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to interpret this. If there are no routes specified here, what routes are being associated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I commented there.
@@ -97,7 +127,7 @@ type Listener struct { | |||
// | |||
// Support: | |||
// +optional | |||
TLS *ListenerTLS `json:"tls,omitempty"` | |||
TLS *TLSConfig `json:"tls,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we need to step back from attaching TLS to the listener. The HTTPRouteHost
has the hostname, maybe that's the right place to put a TLS configuration? That would strongly bind TLS configuration and virtual hosts in a way that's currently only implicit (even with the ListenerCertificates changes below).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the App Dev is responsible for managing TLS config, then I agree that xRoute
is the right place for all TLS config management.
@@ -139,7 +169,7 @@ const ( | |||
TLS1_3 = "TLS1_3" | |||
) | |||
|
|||
// ListenerTLS describes the TLS configuration for a given port. | |||
// TLSConfig describes configuration for establishing a TLS connection. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, "establishing a TLS connection" implies pretty strongly that it is being used by a network client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe TLSConfig
=> TLSServerConfig
will be less ambiguous/
(the server also is part of connection establishment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is intended to be specific to accepting a TLS session, then I agree TLSServerConfig
is less ambiguous.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bowei I considered TLSServerConfig
but TLSConfig
contains client-side properties such as CACertificates
used by the Gateway
for establishing a TLS connection to a backend Service
.
// -----BEGIN CERTIFICATE----- | ||
// Destination Service CA Certificate Bundle. | ||
// -----END CERTIFICATE----- | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice improvement. Should we add a reference to #74, which hopefully will fully define the requirements around certificates?
@@ -167,7 +223,7 @@ type ListenerTLS struct { | |||
// values. | |||
// | |||
// +optional | |||
MinimumVersion *string `json:"minimumVersion"` | |||
MinimumVersion *string `json:"minimumVersion,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, are there any requirements on implementations if the minimum version is omitted? Maybe track a separate issue to discuss?
Certificates []core.TypedLocalObjectReference `json:"certificates,omitempty"` | ||
// | ||
// +optional | ||
ListenerCertificates []core.TypedLocalObjectReference `json:"listenerCertificates,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this relates back to my comment on Listener.TLS
. A collection of listener certificates makes sense when you are modeling a single port that can terminate different TLS names. However, further down, TLSConfig
is used in HTTPRouteAction
, and in that context it's not clear to me whether this is a pinned set of certificates that the client will verify and accept, or simply not used. Attaching the TLS server configuration to the HTTPHostRoute
could help to resolve this ambiguity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current understand is that the certs associated with the Gateway here are for downstream connection and the TLSConfig in HostRouteAction
is for the upstream hop.
266d652
to
70f518b
Compare
Certificates []core.TypedLocalObjectReference `json:"certificates,omitempty"` | ||
// | ||
// +optional | ||
ListenerCertificates []core.TypedLocalObjectReference `json:"listenerCertificates,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current understand is that the certs associated with the Gateway here are for downstream connection and the TLSConfig in HostRouteAction
is for the upstream hop.
// -----END CERTIFICATE----- | ||
// | ||
// Support: Core (Kubernetes ConfigMap) | ||
// Support: Implementation-specific (For other resource types) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/Implementation-specific/Custom
to be consistent with how this is used in other places.
Just a note: #56
// Support: Core | ||
// | ||
// +optional | ||
TLSTermination TLSTerminationType `json:"tlsTermination,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This gets interesting. Sometimes one can be in a situation where the termination is decided based on the SNI. For some SNIs, the proxy terminates TLS while for other it is passthrough. It has come up a few times but I'm not sure if it should be supported by our API.
Leaving a note here but I think it is okay to keep this as is.
@danehans: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Will reopen if virtual host model is accepted. |
…es/mci-https-backend added multi-cluster ingress end to end https recipe
After reviewing #35 feedback from @hbagdi, managing TLS termination at the
Gateway
is more appropriate than within axRoute
.Partially fixes: #49, #72
Fixes: #52
/assign @bowei
/cc @ironcladlou @Miciah