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

ambient: stash hbone peer principal in endpoint metadata #50753

Conversation

keithmattix
Copy link
Contributor

@keithmattix keithmattix commented Apr 30, 2024

Please provide a description of this PR:
If envoyproxy/envoy#33857 merges, we'll be able to use io.istio.upstream_peer_principal to grab the destination principal in telemetry

@istio-testing
Copy link
Collaborator

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Apr 30, 2024
@istio-policy-bot istio-policy-bot added area/ambient Issues related to ambient mesh area/networking release-notes-none Indicates a PR that does not require release notes. labels Apr 30, 2024
@istio-testing istio-testing added the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label Apr 30, 2024
…data key instead

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
@keithmattix keithmattix force-pushed the ambient/waypoint-passthrough-destination-principal branch from f968348 to e2653c5 Compare April 30, 2024 02:26
@istio-testing istio-testing added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Apr 30, 2024
@keithmattix
Copy link
Contributor Author

This implementation doesn't work; the metadata is on the wrong listener. I'm iterating locally and will push periodically

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
@istio-testing istio-testing added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Apr 30, 2024
Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
@keithmattix keithmattix changed the title Use UPSTREAM_PEER_URI_SAN to populate io.istio.peer_principal Use UPSTREAM_PEER_URI_SAN to populate io.istio.upstream_peer_principal May 1, 2024
Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
@istio-testing istio-testing added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 1, 2024
@keithmattix keithmattix changed the title Use UPSTREAM_PEER_URI_SAN to populate io.istio.upstream_peer_principal ambient: stash hbone peer principal in endpoint metadata May 1, 2024
@keithmattix keithmattix marked this pull request as ready for review May 1, 2024 21:04
@keithmattix keithmattix requested review from a team as code owners May 1, 2024 21:04
@istio-testing istio-testing removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label May 1, 2024
@keithmattix
Copy link
Contributor Author

This is ready for review now; we decided to stash the identity in metadata due to complexity

@keithmattix keithmattix added the cherrypick/release-1.22 Set this label on a PR to auto-merge it to the release-1.22 branch label May 1, 2024
@istio-testing
Copy link
Collaborator

@keithmattix: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
lint_istio 06aa692 link true /test lint
gencheck_istio 06aa692 link true /test gencheck

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. I understand the commands that are listed here.

@@ -57,9 +58,32 @@ func buildInternalUpstreamCluster(name string, internalListener string) *cluster
}
}

func buildEncapInternalUpstreamCluster(name string, internalListener string) *cluster.Cluster {
Copy link
Member

Choose a reason for hiding this comment

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

This seems identical to buildInternalUpstreamCluster. is it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah this is from a former iteration where I had a custom filter. I'll clean this up once I get this all working locally

@@ -667,6 +667,10 @@ func buildEnvoyLbEndpoint(b *EndpointBuilder, e *model.IstioEndpoint, mtlsEnable
ep.HostIdentifier = &endpoint.LbEndpoint_Endpoint{Endpoint: &endpoint.Endpoint{
Address: util.BuildInternalAddressWithIdentifier(connectOriginate, net.JoinHostPort(address, strconv.Itoa(port))),
}}
peerPrincipal, _ := structpb.NewStruct(map[string]any{
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this for everything doing hbone or just waypoints?

Like does sidecar have the issue today? Seems like probably yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I would think so; the simplest implementation seemed to be just always adding the identity in endpoint metadata

@kyessenov
Copy link
Contributor

@keithmattix I'd prefer keeping ambient stuff to ambient code, so if we can avoid changing EDS for ambient, that's better. Adding another field to flatbuffer is not a problem, we have to refactor it anyways to support Otel telemetry.

@keithmattix
Copy link
Contributor Author

keithmattix commented May 2, 2024

@keithmattix I'd prefer keeping ambient stuff to ambient code, so if we can avoid changing EDS for ambient, that's better. Adding another field to flatbuffer is not a problem, we have to refactor it anyways to support Otel telemetry.

Ack - I just pushed up my stash. Serializing to the WorkloadMetadataObject is returning an empty string for some reason, and when I try to access the flat buffer directly, it looks corrupted. I've never worked with flat buffers, so any advice would be appreciated

@keithmattix keithmattix marked this pull request as draft May 2, 2024 21:59
@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label May 2, 2024
@keithmattix
Copy link
Contributor Author

Converting back to draft as I'm still testing and trying to get it to work e2e

@costinm
Copy link
Contributor

costinm commented May 2, 2024 via email

@howardjohn
Copy link
Member

WDS works well for ztunnel because its the source of truth for things. Its IMO a poor choice when its decoupled from the rest of the routing flow (reminds me of authz and HTTPRoute 🙂 ).

For example, what happens when the IP we send to is the east-west GW IP? We want metadata for the underlying destination, not the EW GW.

This information is already in EDS, we already put 4 pieces of metadata there -- and it correctly handles these cases. Why put a 5th in a different location?

@kyessenov
Copy link
Contributor

This information is already in EDS, we already put 4 pieces of metadata there -- and it correctly handles these cases. Why put a 5th in a different location?

Because we know that was not a good solution. Not every endpoint is in a cluster to start with, you have to support pass-through cases just the same way. There's no reason why WDS/MDS can't support gateway IPs.

@howardjohn
Copy link
Member

Because we know that was not a good solution. Not every endpoint is in a cluster to start with, you have to support pass-through cases just the same way.

Ok but we don't do mTLS for those either, so the identity information doesn't matter.

Having a disjoint source of information isn't really acceptable on the authorization path

@kyessenov
Copy link
Contributor

Because we know that was not a good solution. Not every endpoint is in a cluster to start with, you have to support pass-through cases just the same way.

Ok but we don't do mTLS for those either, so the identity information doesn't matter.

Having a disjoint source of information isn't really acceptable on the authorization path

Waypoint absolutely relies on WDS for all source telemetry right now. We can just as well rely on it for destination telemetry, instead of trying to make it a hybrid of EDS on the destination side. I would agree if we didn't use WDS already, but it's heavily used at this point on Waypoints.

@howardjohn
Copy link
Member

TBH I am a bit confused by the position here. In the past, hadn't you advocated for deriving more metadata from trusted attributes? I.e. get the namespace, identity, etc from the TLS handshake. Using WDS seems further from that. What am I missing?

@kyessenov
Copy link
Contributor

@howardjohn Yes, when Envoy performs L4 functions as in the sidecar we should use the trusted attributes. But with Ambient, L4 is intentionally walled from L7 so L7 ultimately has to trust something else to provide those attributes. Whether you trust ztunnel on the destination side, Cilium/kernel, or istiod, doesn't really matter - you simply look up identity wherever you can.

Costin points out to a valid model of a sidecar also dropping L4 functions, where we'd need to do this lookup as well, but that's a separate topic.

@howardjohn
Copy link
Member

Even in the case where you have ztunnel, the model we (or, I) am pushing for is to have an exchange of information between these two layers. Blindly trusting is not a good model IMO. And we are blurring the layers by needing to look up the information out of band instead of just asking the layer.

@kyessenov
Copy link
Contributor

Even in the case where you have ztunnel, the model we (or, I) am pushing for is to have an exchange of information between these two layers. Blindly trusting is not a good model IMO. And we are blurring the layers by needing to look up the information out of band instead of just asking the layer.

I don't think it's a problem. istiod is just a skip-level manager that you can ask instead of going to the direct manager :) There's a general consistency problem that can be improved if you do it on the wire - you can absolutely do the same with an internal protocol between HCM and tcp_proxy instead of raw TCP that read/write principals. But that requires custom filters for a relatively minor feature right now.

@howardjohn
Copy link
Member

I agree communication between the layers is more work and maybe not worth it, but I don't see how EDS vs WDS is more or less work. Both seem to be just plugging 1 new field into existing mechanisms. Then we will want to use that in SAN match, but probably that work is similar across both methods

@kyessenov
Copy link
Contributor

EDS is not meant for policy - it's a load assignment, not even config. Putting a policy for SAN into EDS feels like an abuse of xDS data model.

@howardjohn
Copy link
Member

Where else would you put per-endpoint policies? If we are talking about abusing XDS data model that does not include WDS either

@costinm
Copy link
Contributor

costinm commented May 3, 2024 via email

@howardjohn
Copy link
Member

The intent (from me, maybe not Keith -- I will let him say) is to use this for telemetry and authz. Our current SAN match is trust-domain/* which is obviously unacceptable long term.

At least with the current Istio mode, authz should only be based on the peer certificate.

I am talking about how to verify the cert

@costinm
Copy link
Contributor

costinm commented May 3, 2024 via email

@costinm
Copy link
Contributor

costinm commented May 3, 2024

Ok - I am confused... Is this in context of the previous WG meeting and getting principal for telemetry ? Or for some authentication feature that I'm not aware of ( normally CDS has secure naming ) ?

John - I don't mind if ztunnel can pass the data ( PROXY or other mean)- but ztunnel gets it from Istiod as well.
Waypoint, sidecar or ztunnel trust Istiod to provide the correct info about an IP - including its service account -
both for cluster IPs ( secure naming ) and endpoints, and I don't see why a lookup directly with WDS would be
less trusted then getting the data from ztunnel ( less efficient - yes, that's clear)

@keithmattix
Copy link
Contributor Author

~medium term we definitely need to validate the SAN of the upstream endpoint, otherwise the telemetry on the wire could be false without us knowing. The immediate fix is to try and make sure telemetry is fixed, but I don't see why we shouldn't do SAN validation as well

@costinm
Copy link
Contributor

costinm commented May 3, 2024

The intent (from me, maybe not Keith -- I will let him say) is to use this for telemetry and authz. Our current SAN match is trust-domain/* which is obviously unacceptable long term.

I would suggest not mixing (again) telemetry and authz. They have very different requirements, and I agree current SAN match is really bad and needs to be fixed.

At least with the current Istio mode, authz should only be based on the peer certificate.

I am talking about how to verify the cert

I have been thinking about telemetry - and not sure I have full context on the authz issue.
It can't be about waypoint verifying the client cert - that would be covered by authz policy matches, and
I assume HA-PROXY discussion for sandwitches.
Is it about 'secure naming' for waypoints ? That would be covered by CDS for services - and there is no EDS
for pods that are not in a service.

Keith - can you add some comments to the PR description to make the use case(s) more clear, and if it is
security related - it would really, really help to have a doc that can be security reviewed by people who
focus on this area.

@howardjohn
Copy link
Member

howardjohn commented May 3, 2024 via email

@costinm
Copy link
Contributor

costinm commented May 3, 2024

~medium term we definitely need to validate the SAN of the upstream endpoint, otherwise the telemetry on the wire could be false without us knowing. The immediate fix is to try and make sure telemetry is fixed, but I don't see why we shouldn't do SAN validation as well

We should certainly do SAN validation - but not confuse the security and trust model used in authz with the one used
for telemetry. If we end up with trusted telemetry data - it's great, but not all telemetry can be signed and authenticated
and we would get (again) distracted. Istio telemetry has not been trust-worthy - and perhaps we can live few more releases with this, since using WDS for telemetry data is far more secure than the current headers and metadata exchange.

I still don't know what 'upstream endpoint' you're validating and where. For clusters - I assume we still use
CDS and normal process. When the upstream is a pod without CDS - there is no EDS either, so not clear how adding
peer info in EDS would help. To be honest I don't really understand the security model for 'to workload' very
well and I don't think the docs we have are detailed enough ( but I'm not an expert in security - hope someone
does understand the actual details in this area ). But unless something dramatic changed in EDS - a pod that
is not part of a service should not be there.

@costinm
Copy link
Contributor

costinm commented May 3, 2024

Yes it's securing naming in CDS doesn't work in waypoints due to the internal listener hop. If we are already giving a per-endpoint identity in don't see why we would then aggregate that into a cluster match

So this is a HTTP request for "example.ns" that hits waypoint, gets routed to "example-v1" cluster - which has a bunch of
endpoints. What does the internal hop do ? If Envoy is initiating mTLS - it should have all the info. If it's sandwitch - ztunnel should have the peer info, based on the pod IP.

Why we aggregate all pod identities in the cluster is a controversial issue, but the current approved design for
secure naming and 'client validating server identity' is what we have. Not perfect - but a change in security
model requires very serious review. Regardless - not aggregating doesn't do much - we still rely on what
the pod happens to run as instead of what user intends ( I.e. "only example service account can be used for the example service, if any pod with wrong label happens to be deployed - reject" ). At least that's the controversial part
in the secure naming AFAIK - and I believe the Gateway design as I understand it is moving into explicit user
intent instead of aggregation/guessing.

If the request is NOT for a cluster/service - but directly to an endpoint ( workload to workload ) - that's a whole different
discussion.

@costinm
Copy link
Contributor

costinm commented May 3, 2024

@keithmattix I'd prefer keeping ambient stuff to ambient code, so if we can avoid changing EDS for ambient, that's better. Adding another field to flatbuffer is not a problem, we have to refactor it anyways to support Otel telemetry.

Ack - I just pushed up my stash. Serializing to the WorkloadMetadataObject is returning an empty string for some reason, and when I try to access the flat buffer directly, it looks corrupted. I've never worked with flat buffers, so any advice would be appreciated

I haven't seen the code - how did we end up with flatbuffers ? Didn't we have enough protobuffers and Json and yaml ? Is it something required by envoy ?

Nothing wrong with flatbuffers - I like them - but seems one more complexity.

@kyessenov
Copy link
Contributor

Nothing wrong with flatbuffers - I like them - but seems one more complexity.

We had flatbuffers since version 1.5 or so :D They were forced by Wasm, there's no good reason to use them now, so it just remains a tech debt.

@keithmattix
Copy link
Contributor Author

Closing because I was able to get this working with WDS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/ambient Issues related to ambient mesh area/networking cherrypick/release-1.22 Set this label on a PR to auto-merge it to the release-1.22 branch do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. release-notes-none Indicates a PR that does not require release notes. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants