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

K8 CSR support #387

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

K8 CSR support #387

wants to merge 1 commit into from

Conversation

aryan16
Copy link

@aryan16 aryan16 commented Feb 8, 2023

Added support for K8 CSR and custom signer

@istio-testing istio-testing added needs-rebase Indicates a PR needs to be rebased before being merged size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 8, 2023
@aryan16 aryan16 marked this pull request as draft February 8, 2023 22:31
@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Feb 8, 2023
@istio-testing istio-testing removed the needs-rebase Indicates a PR needs to be rebased before being merged label Feb 8, 2023
@aryan16
Copy link
Author

aryan16 commented Feb 8, 2023

@howardjohn I will move the client creation to the common level (probably when we create the configs) ?

@aryan16 aryan16 removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Feb 8, 2023
@aryan16 aryan16 marked this pull request as ready for review February 8, 2023 22:53
Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

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

Why do we have a different k8s csr support from sidecar? We send request to istiod and istiod will do this for sidecar

src/identity/customca.rs Show resolved Hide resolved
@aryan16
Copy link
Author

aryan16 commented Feb 9, 2023

Why do we have a different k8s csr support from sidecar? We send request to istiod and istiod will do this for sidecar

IMO Ztunnel has all the capabilities to make a CSR request directly. Why to add an extra complexity of sending req to istiod.
cc : @howardjohn

Cargo.toml Outdated Show resolved Hide resolved
Cargo.toml Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Feb 10, 2023
src/identity/manager.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Show resolved Hide resolved
src/identity/manager.rs Outdated Show resolved Hide resolved
@hzxuzhonghu
Copy link
Member

@aryan16 How can we support VM installation using this mode?

@istio-testing istio-testing removed the needs-rebase Indicates a PR needs to be rebased before being merged label Feb 14, 2023
@aryan16 aryan16 force-pushed the K8s-csr branch 2 times, most recently from 90cf030 to bb4ba58 Compare February 14, 2023 23:38
@aryan16
Copy link
Author

aryan16 commented Feb 14, 2023

@aryan16 How can we support VM installation using this mode?

If VM is able to talk to K8s api server then no issues, if not we won't be using this feature instead use the existing GRPC call to istiod.

@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Feb 16, 2023
@aryan16 aryan16 force-pushed the K8s-csr branch 2 times, most recently from 9f7fa6c to b832255 Compare February 21, 2023 23:10
@istio-testing istio-testing removed the needs-rebase Indicates a PR needs to be rebased before being merged label Feb 21, 2023
src/app.rs Outdated
if config.fake_ca {
let cert_manager = identity::mock::new_secret_manager(Duration::from_secs(86400));
build_with_cert(config, cert_manager).await
} else {
} else if config.custom_signer.is_some() {
Copy link
Member

@JimmyCYJ JimmyCYJ Feb 22, 2023

Choose a reason for hiding this comment

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

Did we validate the config before it is passed to build()?

Copy link
Author

Choose a reason for hiding this comment

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

you mean the custom signer? No we are not validating the custom signer, do we need it?

src/identity/customca.rs Show resolved Hide resolved
src/identity/customca.rs Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
src/config.rs Outdated Show resolved Hide resolved
@@ -414,6 +415,19 @@ impl SecretManager<CaClient> {
}
}

impl SecretManager<CustomSigner> {
pub async fn origin(cfg: crate::config::Config) -> Result<Self, anyhow::Error> {
Copy link
Member

Choose a reason for hiding this comment

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

what does "origin" mean?

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I know it is a function, I just do not get the name?

Copy link
Author

Choose a reason for hiding this comment

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

oh I saw the same name at many places in rust example codes as a replacement of new. Do you think I should update it?

src/identity/manager.rs Outdated Show resolved Hide resolved
src/app.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved

async fn check_signed_cert(csr: &Api<CertificateSigningRequest>, csr_name: &String) -> Result<k8s_openapi::ByteString, anyhow::Error> {
let lp = ListParams::default().fields(&format!("{}{}", "metadata.name=", csr_name)).timeout(30);
let mut stream = csr.watch(&lp, "0").await?.boxed();
Copy link
Member

Choose a reason for hiding this comment

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

just watch has a race condition; if it was finished before we start the watch it will break. Need a List+Watch

I would overall prefer a long lived watched on a label we set on each CSR but ok with list+watch approach like we do in chiron/utils.go in the short term. Note you need to put ResourceVersion as well.

Copy link
Author

Choose a reason for hiding this comment

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

Updated, PTAL

src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/identity/customca.rs Outdated Show resolved Hide resolved
src/tls/boring.rs Outdated Show resolved Hide resolved
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Mar 1, 2023

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: aryan16 / name: Aryan Gupta (16bd692)

@aryan16 aryan16 force-pushed the K8s-csr branch 2 times, most recently from 59c4c2a to 72b7541 Compare March 1, 2023 18:49
@istio-testing istio-testing added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Mar 1, 2023
@aryan16 aryan16 requested a review from howardjohn March 2, 2023 22:02
@istio-testing
Copy link
Contributor

PR needs rebase.

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.

@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Mar 4, 2023
@costinm
Copy link
Contributor

costinm commented Mar 30, 2023

What's next ? The DNS proxy ( which is REQUIRED if the underlying network is not secure ) ? Integration with the external SDS provider using UDS ?

Can we please add the agent and just use it ? No need for ztunnel to duplicate all the integrations and do everything ( in a slightly different way ).

A design doc on such changes with focus on security will also be greatly appreciated:

  • who approves the CSRs and on what criteria ? If Istiod, why not use the existing code that also generates the CSR
  • VMs - how does it change the install and security requirements ? We didn't use k8s signing from VMs because
    it required VMs to have K8S SA and access - which means higher escalation risks and permissions.
  • what are the benefits compared to using the current method and letting Istiod generate the k8s sign request ?

But even if we conclude direct integration with k8s from the proxy is best ( and I can be convinced it's a more
standard protocol than our gRPC call to Istiod ) - we should still do it in the agent, so both sidecars and ambient
are consistent and use whatever is best.

@costinm
Copy link
Contributor

costinm commented Mar 30, 2023

On a related note - ztunnel should eventually match the integrations we have, including SDS and CSI-based providers ( in both dedicated mode and in future if we implement delegation ).

I saw the FAKE provider - IMO it should be replaced (or we should add) with a mode that reads from /var/run/secrets... ( same default as istio-agent ), and fallback to SDS using the well-known path that the Envoy is using ( for Spire and all other integrations ).
And once SDS is added - we can maybe remove the call to Istiod and keep ztunnel focused on proxying, not implementing multiple CA protocols, just XDS and files.

impl SecretManager<CustomSigner> {
pub async fn origin(cfg: crate::config::Config) -> Result<Self, anyhow::Error> {
let k8s_client = tls::create_k8s_client(cfg.k8s_ca_crt).await;
match k8s_client {
Copy link
Contributor

Choose a reason for hiding this comment

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

This won't work on VMs.

Pretty sure there is a way to initialize k8s client in rust that works with both 'in cluster' and kubeconfig.

Same for the tokens - outside of K8S you need all the auth methods, the VM may use MDS or external commands to authenticate ( gcloud, etc ).

pub async fn create_k8s_client(root_cert: RootCert) -> Result<kube::Client, anyhow::Error> {
let mut conn = ssl::SslConnector::builder(ssl::SslMethod::tls_client())?;
conn.set_verify(ssl::SslVerifyMode::PEER);
conn.set_alpn_protos(Alpn::H2.encode())?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the only SSL connection we create in ztunnel ? Any chance we could use the same code - or client library code ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-rebase Indicates a PR needs to be rebased before being merged size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants