-
Notifications
You must be signed in to change notification settings - Fork 47
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: validator: Load TLS configuration from ConfigMap #1119
base: main
Are you sure you want to change the base?
Conversation
These methods are not used from outside the package. Signed-off-by: Andrej Krejcir <[email protected]>
Do not create or use the struct when using HTTP. Signed-off-by: Andrej Krejcir <[email protected]>
This package was copied directly from vm-console-proxy: https://github.com/kubevirt/vm-console-proxy/tree/main/pkg/filewatch In a future commit, it will replace file watch logic in internal/template-validator/tlsinfo. We do this to simplify watching multiple directories with TRS certificate and TLS configuration. Signed-off-by: Andrej Krejcir <[email protected]>
Runs all callbacks before processing watch events. This means that callbacks will have a change to notice the files after the watch was started, but no events happened yet. Signed-off-by: Andrej Krejcir <[email protected]>
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 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 |
874c9bc
to
520ceb4
Compare
@akrejcir Is it simialr to the implementation as in |
It is exactly the same package. I've mentioned it in the commit message: 3b2e200 Do you mean that SSP should import |
520ceb4
to
6ef7c2f
Compare
}) | ||
It("should load certificate", func() { | ||
Expect(tlsInfo.Init()).To(Succeed()) | ||
defer tlsInfo.Clean() |
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.
defer
vs DeferCleanup
?
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.
defer
is called when func() {}
returns. DeferCleanup()
is called after the It()
test case, similarly to AfterEach()
. It is useful to call in BeforeEach()
to register cleanups that will be called after the test.
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.
Does it make a difference using DeferCleanup
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.
I think only a performance difference.
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 it be moved to AfterEach()
?
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.
Yes, but I prefer it this way. It is also how it's used in the validator code app.go
.
Using the filewatch package in template validator will make it easier to watch multiple directories in a future commit. Signed-off-by: Andrej Krejcir <[email protected]>
The GetClientConfig() will be used in future commit to set TLS options. Signed-off-by: Andrej Krejcir <[email protected]>
The TLS configuration is read from a ConfigMap that is mounted as a file. This allows updating the configuration without restarting the pod. Signed-off-by: Andrej Krejcir <[email protected]>
Signed-off-by: Andrej Krejcir <[email protected]>
This will make it easier to modify the tests in future commit. Signed-off-by: Andrej Krejcir <[email protected]>
Check TLS policy of template validator pod. Signed-off-by: Andrej Krejcir <[email protected]>
6ef7c2f
to
d1bdb12
Compare
Quality Gate passedIssues Measures |
} | ||
|
||
ti.minTLSVersion = minVersion | ||
ti.cipherSuites = common.CipherIDs(tlsOptions.OpenSSLCipherNames, nil) |
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 happens if this leaves us with an empty slice in case of user misconfiguration?
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.
Good point. If user passes unknown cipher names, they will be silently left out. That is how it is implemented in the library function crypto.OpenSSLToIANACipherSuites()
. I will add code to return an error instead.
If ti.cipherSuites
is empty slice, then no cipher suites are enabled, except TLS 1.3 ciphers, which cannot be disabled.
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.
Thinking about this, it may be desired behavior. Usually, on TCP connection, the server gives client a list of supported ciphers and the client chooses. Any unknown ciphers are ignored.
Maybe it is ok to use the same approach for configuration file. User could specify multiple ciphers, and it is not an error if the validator does not know some of them.
What do you think?
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 was thinking what happens if you configure the API server with an empty slice if using TLS 1.1/1.2? Will it fallback to default ciphers? I'm not sure we should swallow this error silently. It is misconfiguration of the API server, not a failure in negotiating a cipher during a handshake.
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 we configure the server ciphers with empty slice []
and not use TLS 1.3, then no ciphers will be enabled, so it will not accept any connection. If we configure it with nil
slice, then it will use default ciphers.
This is IMHO a bad API design in the standard library. Usually in other places there is no functional difference between []
and nil
.
Ok, I will change the code, so it fails with error if ciphers in config file are not known.
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've implemented the error checking and noticed that OpenShift's TLS security profiles also contain ciphers that are not implemented in the TLS in golang and they are silently ignored.
For example, here is the TLS Intermediate
profile:
https://github.com/openshift/api/blob/a2817b89f7e0989016967055a142d5e88bed18de/config/v1/types_tlssecurityprofile.go#L288-L303
TLSProfileIntermediateType: {
Ciphers: []string{
"TLS_AES_128_GCM_SHA256",
"TLS_AES_256_GCM_SHA384",
"TLS_CHACHA20_POLY1305_SHA256",
"ECDHE-ECDSA-AES128-GCM-SHA256",
"ECDHE-RSA-AES128-GCM-SHA256",
"ECDHE-ECDSA-AES256-GCM-SHA384",
"ECDHE-RSA-AES256-GCM-SHA384",
"ECDHE-ECDSA-CHACHA20-POLY1305",
"ECDHE-RSA-CHACHA20-POLY1305",
"DHE-RSA-AES128-GCM-SHA256",
"DHE-RSA-AES256-GCM-SHA384",
},
MinTLSVersion: VersionTLS12,
},
It contains ciphers DHE-RSA-AES128-GCM-SHA256
and DHE-RSA-AES256-GCM-SHA384
, which are not available in the golang TLS library.
The code that does the translation between names and cipher IDs ignores them: https://github.com/openshift/library-go/blob/64780a4acea5ee3e565683ad96b1f4f0799f0bd2/pkg/crypto/crypto.go#L149-L180
https://github.com/openshift/library-go/blob/64780a4acea5ee3e565683ad96b1f4f0799f0bd2/pkg/crypto/crypto.go#L300-L314
So it is not trivial to check if a cipher name is valid. We don't want it to fail if users set one of the OpenShift's profiles, but they already contain unknown ciphers. So we would need to specifically allow them, even if they are not implemented.
What do you think?
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.
As long as an empty slice that is not nil does not result in default values being used, I'm fine with it.
But strange that these profiles ship ciphers that are not supported. Are they supported in downstream distributions of golang?
}) | ||
It("should load certificate", func() { | ||
Expect(tlsInfo.Init()).To(Succeed()) | ||
defer tlsInfo.Clean() |
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.
Does it make a difference using DeferCleanup
here?
What this PR does / why we need it:
This PR moves the TLS configuration of
template-validator
to a ConfigMap. It is mounded as a file in the pod, and validator is able to update its configuration without restarting the pod.Which issue(s) this PR fixes:
Jira: https://issues.redhat.com/browse/CNV-28716
Release note: