-
Notifications
You must be signed in to change notification settings - Fork 83
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
Add upstream TLS trust from CM bundles #1171
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: ReToCode The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@skonto @dprotaso what do you think of that approach for knative/serving#14609. With this approach, this is not tied to trust-manager. ConfigMaps seem to be a very common interface for CA bundles, see https://github.com/ReToCode/knative-encryption/tree/main/8-trust-sources. We can also extend this to knative/serving#14609 (comment) once this has landed. But I'd vote for reading it using the K8s clients instead of mounting it to the filesystem, as this solves the reloading concern. |
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #1171 +/- ##
==========================================
- Coverage 81.04% 80.94% -0.10%
==========================================
Files 18 18
Lines 1456 1496 +40
==========================================
+ Hits 1180 1211 +31
- Misses 219 223 +4
- Partials 57 62 +5 ☔ View full report in Codecov by Sentry. |
In general I see secrets being used as well. For trust manager it seems cm are first option. I don't have strong preference. |
vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/configmap/configmap.go
Outdated
Show resolved
Hide resolved
Hm where do you mean? I don't think we have a current solution (other than |
fb8d388
to
33ab71d
Compare
I was referring to the docs: https://cert-manager.io/docs/trust/trust-manager
|
That is just for sources when I'm reading it right. The result to mount in workloads is always a Configmap? |
It seems it supports: sources/targets.
|
33ab71d
to
92f2583
Compare
92f2583
to
fe0c4d2
Compare
@skonto this is ready now, please take another look. /unhold |
@@ -466,3 +517,24 @@ func domainsForRule(rule v1alpha1.IngressRule) []string { | |||
} | |||
return domains | |||
} | |||
|
|||
func checkCertBundle(certs []byte) error { |
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 a side note it seems that this error is not being caught by decode (probably not considered an error):
var rsaSecretCertPEM = `-----BEGIN CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
-----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.
I played around with decode a bit.
The way it is written:
func Decode(data []byte) (p *Block, rest []byte) {
// pemStart begins with a newline. However, at the very beginning of
// the byte array, we'll accept the start string without it.
rest = data
for {
if bytes.HasPrefix(rest, pemStart[1:]) {
rest = rest[len(pemStart)-1:]
} else if _, after, ok := bytes.Cut(rest, pemStart); ok {
rest = after
} else {
return nil, data
}
var typeLine []byte
typeLine, rest = getLine(rest)
if !bytes.HasSuffix(typeLine, pemEndOfLine) {
continue
}
typeLine = typeLine[0 : len(typeLine)-len(pemEndOfLine)]
p = &Block{
Headers: make(map[string]string),
Type: string(typeLine),
}
...
It seems it is always going to consume the input.
I am wondering if there is a scenario where block== nil but we have len(rest) >0.
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 I had one case with that, that's why I added
|| len(rest) > 0
, this way we error out in checkCertBundle
when there is still a rest that is not consumed.
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.
Yeah I think it parses from comment to comment, so having multiple -----BEGIN CERTIFICATE-----
is just ignored, as long as the cert within is valid.
if block != nil { | ||
switch block.Type { | ||
case "CERTIFICATE": | ||
_, err := x509.ParseCertificate(block.Bytes) |
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.
Are we planning to do any verification at some point like with this function: https://github.com/istio/istio/blob/master/security/pkg/pki/util/keycertbundle.go#L284 or as soon as we get the cert bundle we assume an external entity is responsible to create valid combinations of ca certs/tls certs etc?
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, we give the CA to envoy, envoy will then use it to verify the upstream TLS server cert. I don't think we need to pre-validate. Otherwise we'd also need to reconcile on a number of upstream certs which we actually don't really want to read from each ingress.
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.
Yeah just wondering if Istio is doing a pre-validation tep.
false, | ||
&envoycorev3.TransportSocket{ | ||
Name: wellknown.TransportSocketTls, | ||
ConfigType: typedConfig(false, 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.
Passing nil here (also tested with a missing cm) means that we end up having no validation since this is passed to
InlineBytes: expectedCert, |
Check comments here too:
Lines 816 to 835 in 2a72a55
// TLS certificate data containing certificate authority certificates to use in verifying | |
// a presented peer certificate (e.g. server certificate for clusters or client certificate | |
// for listeners). If not specified and a peer certificate is presented it will not be | |
// verified. By default, a client certificate is optional, unless one of the additional | |
// options (:ref:`require_client_certificate | |
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.DownstreamTlsContext.require_client_certificate>`, | |
// :ref:`verify_certificate_spki | |
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.verify_certificate_spki>`, | |
// :ref:`verify_certificate_hash | |
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.verify_certificate_hash>`, or | |
// :ref:`match_typed_subject_alt_names | |
// <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.match_typed_subject_alt_names>`) is also | |
// specified. | |
// | |
// It can optionally contain certificate revocation lists, in which case Envoy will verify | |
// that the presented peer certificate has not been revoked by one of the included CRLs. Note | |
// that if a CRL is provided for any certificate authority in a trust chain, a CRL must be | |
// provided for all certificate authorities in that chain. Failure to do so will result in | |
// verification failure for both revoked and unrevoked certificates from that chain. | |
// The behavior of requiring all certificates to contain CRLs can be altered by |
Would that allow tls communication without validation or connection is failing?
Also do you think that this affects us envoyproxy/envoy#19326 downstream? 🤔
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 about this part:
" Note
// that if a CRL is provided for any certificate authority in a trust chain, a CRL must be
// provided for all certificate authorities in that chain. Failure to do so will result in
// verification failure for both revoked and unrevoked certificates from that chain."
Do you know the implications of this (I am not familiar with this case)?
7ea03f4
to
9529993
Compare
/lgtm |
/hold |
/unhold |
Changes
ca.crt
in activators cert secret, net-kourier now also adds additional trust bundles to the trust poolPartially knative/serving#14609
Release Note
Docs
Will be added once the full encryption feature is completed.