Skip to content

Conversation

rickhlx
Copy link
Contributor

@rickhlx rickhlx commented Nov 8, 2024

Fixes #3295

This feature allows setting a custom TLS config based on the client's request. It uses tls GetConfigForClient to obtain the correct config for the specific client's hello.

This feature allows the use of ingress annotations or other methods to add custom configs per routes.

This is especially useful for the issue being fixed where we would like to setup client auth per ingress and/or routegroup.

* This method allows looking up custom config based on client hello
* Expand certificate registry type to allow for both certs and config
@rickhlx
Copy link
Contributor Author

rickhlx commented Nov 8, 2024

@szuecs could we get some early feedback? We'd like to know if implementing this in the CertificateRegistry seems like a good idea.

* Create function to parse client auth from annotation
* Set tls config when adding tls spec from ingress
* functions to parse and add configs to registry

if cr != nil {
config.GetCertificate = cr.GetCertFromHello
config.GetConfigForClient = cr.GetConfigFromHello
Copy link
Contributor Author

Choose a reason for hiding this comment

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

problem: the tls.Config from GetConfigForClient will override the previously used GetCertificate. So the two are mutually exclusive, from the docs:

Server configurations must set one of Certificates, GetCertificate or GetConfigForClient.

Copy link
Member

Choose a reason for hiding this comment

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

Check if the new one is non nil and if so only use that one, else fallback to current behavior.
Does it make sense?

Copy link
Contributor Author

@rickhlx rickhlx Nov 11, 2024

Choose a reason for hiding this comment

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

Makes sense.

I was also thinking we could also use GetConfigForClient only. This would allow us to use custom certs and custom TLS config. Config could be set to a "default" based on global skipper flags allowing it to be overridden. This approach shouldn't change the current behavior since it will effectively be the same functionality. Wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

I have no strong opinion on that onre

* Store tls.Config in registry to allow for certs and config to be stored
* Refactor registry to handle setting configs with hash for comparison
* Only ClientAuth and certs can be set with option for more tls configs
// ParseTLSClientAuth parses the string representations of different
// client auth types.
func ParseTLSClientAuth(s string) (tls.ClientAuthType, error) {
switch s {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
switch s {
switch strings.ToLower(s) {

just an idea to support casing as well

}

if found && !bytes.Equal(curr.hash, configHash) {
if !config.Certificate.Leaf.NotBefore.After(curr.config.Certificates[0].Leaf.NotBefore) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

problem: this causes config to be skipped when separate ingresses have different annotations. We'd need to set the annotation for all hosts regardless of the ingress.

Copy link
Member

Choose a reason for hiding this comment

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

I am not sure why you compare the "NotBefore" values.
As far as I understand config.Certificate is the global default and curr.config.Certificates[0] is the looked up one. So here we compare if default is not newer than the looked up one.
Should not we match the "better" one?
For example better match like *.foo.example vs www.foo.example ?

return nil
}

if found && !bytes.Equal(curr.hash, configHash) {
Copy link
Member

Choose a reason for hiding this comment

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

it's a duplicate check for found so maybe reafctor to have only one check for found.

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.

Override TLS Client Auth (potentially other TLSOptions) per Ingress/Route

4 participants