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

feature: allow overriding tls config based on client hello #3303

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

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
@@ -1211,6 +1211,7 @@ func (o *Options) tlsConfig(cr *certregistry.CertRegistry) (*tls.Config, error)

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?

* 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.

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