envoyproxy / envoy

Cloud-native high-performance edge/middle/service proxy
https://www.envoyproxy.io
Apache License 2.0
25.02k stars 4.82k forks source link

Golang network filter missing functions #29270

Open or-adar opened 1 year ago

or-adar commented 1 year ago

I'm experimenting with the new golang network filter in v1.27.0 and I noticed that native C++ filters are exposed to more functions than what the golang filter is exposing. for instance, the ConnectionCallback interface: https://github.com/envoyproxy/envoy/blob/f17f1fdd644cc4b32f65579184757e3975843db6/contrib/golang/common/go/api/filter.go#L176-L183 exposes 3 methods, but from what it looks like the connection callback should have more methods such as requestedServerName() to retreive the SNI of the requested server and so on..

so, am I missing something? or is there a plan to add any missing methods to the connection callback later on?

doujiang24 commented 1 year ago

Yep, the network filter is the early iteration, new features in the TODO list.

Could you please describe your case a bit, and is there other APIs you needed? except the requestedServerName.

cc @antJack

or-adar commented 1 year ago

Cool, good to know! is there a page to track the TODO list you mentioned?

And for my use case, I wanted to use requestedServerName to examine some custom behaviour that will mint a self signed certificate in the bacground based on the SNI on the request, and I thought about using the Golang network filter for the task.

doujiang24 commented 1 year ago

is there a page to track the TODO list you mentioned?

not yet, feel free to create issues, or even PRs, when you need new features.

And for my use case, I wanted to use requestedServerName to examine some custom behaviour that will mint a self signed certificate in the bacground based on the SNI on the request,

Do you want to generate a self signed certificate, on demand, by using Golang, based on the SNI? if yes, I think it might be too late?

or-adar commented 1 year ago

I was planning to use the generated self signed certificate on subsequent requests with that SNI using xDS, so it could be late but not that late.

doujiang24 commented 1 year ago

@or-adar oh, I see. then, how does first SSL/TLS connection handshake? is there already a useable bootstrap certificate?

or-adar commented 1 year ago

@doujiang24 No, the first connection is being forwarded as-is and the TLS handshake won't be handled by Envoy in that case (for the first request).

But coming to think of it, maybe it won't be really great for what I'll be trying to acheive, and I'll need to consider the first connection as well.

Do you think I should use a different approach? like retreiving the SNI through gRPC access logs? (or will it be too late as well for the first connection like with the golang network filter? or maybe there's some way to retry the first connection somehow after xDS manages to insert the appropriate filter chain for the required domain?) Other option I can come up with is creating a custom handshaker that'll generate certificates for each domain a user has requested at runtime..?

doujiang24 commented 1 year ago

yep, custom_hanshaker could be a workable choice, but it's a bit overhead if we just need generate certificates at runtime. it will take over the SSL session resumption and SSL ticket, and etc.

actually, I had implemented a custom_handshaker that support using Golang to hand generate certificate at runtime, but, not opensource yet. I might create a PR for it when I have enough free time.

But, I do think a better choice, might be a custom_certificate_specifier, similar to custom_handshaker, so that the golang extension that implemented the custom_certificate_specifier do not need to care about SSL session/ticket.

or-adar commented 1 year ago

it could produce a bit of overhead but it can be tolerated, as theoretically I will need to mint the self signed certificate only once (per domain), for the first connection, and reuse existing certificates for consequent requests with that same domain (as the certificate for that domain should already exist).

I haven't heard about custom_certificate_specifier or got to find anything about it in the docs/codebase, do you have any reference?

Also, does creating custom_certificate_specifier/custom_handshaker requires forking the project? or you can write the custom logic in a separate codebase and reference it with a compiled binary that you mount to a container running envoy (similar to how it could be acheived with wasm/golang network filter)? I just never seen any examples of custom_handshaker so if you have any known exaples or references, I'd appreciate it if you could share them with me!

doujiang24 commented 1 year ago

oh, custom_certificate_specifier is just my thought, not a implementation yet.

Also, does creating custom_certificate_specifier/custom_handshaker requires forking the project?

yep, it need to recompile a envoy binary. but after we have a golang extenstion that implement the custom_certificate_specifier/custom_handshaker, then we could just compile a golang.so in a separate code base and mount to a container running envoy.

yep, I'll create a PR as a demo when I have some time, might be this weekend.

or-adar commented 1 year ago

appreciate the response!

just to be clear, the golang extension for custom_certificate_specifier/custom_handshaker is something that is planned?

And the PR you are talking about showcases a golang extension that allows extending custom_certificate_specifier/custom_handshaker?

doujiang24 commented 1 year ago

just to be clear, the golang extension for custom_certificate_specifier/custom_handshaker is something that is planned?

yep, it's on our TODO list, but not a high priority. anyway, I'll create a PR for the draft version.

And the PR you are talking about showcases a golang extension that allows extending custom_certificate_specifier/custom_handshaker?

yep, that's it, but it might not be a fully workable stage, might be a draft version at first.

or-adar commented 1 year ago

oh I see, thank you for clarifying! Looking forward to seeing the progress

BenAgai commented 1 year ago

Hi @or-adar, @doujiang24 I’m currently researching how to do selective TLS bumping that will affect incoming connections. i.e hold incoming connection, accepted by Envoy, before TLS handshake is made, generate certificate for them if needed and perform TLS bumping.

I, too, didn’t find a way to do the above. I succeeded in implementing selective TLS bumping but it won’t work with newly incoming connections for which I didn’t create certificate yet (as the certificate creation happens at a later point where the handshake was already done).

@doujiang24 , Regarding your response on using custom_handshaker, I would like to avoid code changes in Envoy as much as possible. Sorry if I’m asking the same question, but is there any plan to provide Go API to do the above without the need to change Envoy’s code base? (A POC/draft will be good to look at as well)

Thanks!

doujiang24 commented 1 year ago

is there any plan to provide Go API to do the above without the need to change Envoy’s code base?

yep, just like the current Golang filter extension: https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/golang_filter

doujiang24 commented 1 year ago

Hello @or-adar and @BenAgai , here is the draft PR: https://github.com/envoyproxy/envoy/pull/29383

But I may not have enough time to finish it in short, welcome to continue it, or other better ways, if you are instersted it.

BenAgai commented 1 year ago

Thanks @doujiang24 for the reply! I hope #29383 will be prioritized as I believe the above feature is desired by more people.

Have a good week!

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in the next 7 days unless it is tagged "help wanted" or "no stalebot" or other activity occurs. Thank you for your contributions.