From 2de8b7cf3fdef274976c23b98de73fbce7a0c914 Mon Sep 17 00:00:00 2001 From: Faseela K Date: Mon, 20 Mar 2023 21:30:45 +0100 Subject: [PATCH] Add docs test for custom CA k8s (#12910) * Add docs test for custom CA k8s Signed-off-by: Faseela K * wait for secrets to be created Signed-off-by: Faseela K * Fix tests Signed-off-by: Faseela K * address review comments Signed-off-by: Faseela K --------- Signed-off-by: Faseela K --- .../cert-management/custom-ca-k8s/index.md | 44 ++- .../cert-management/custom-ca-k8s/snips.sh | 271 ++++++++++++++++++ .../cert-management/custom-ca-k8s/test.sh | 51 ++++ 3 files changed, 354 insertions(+), 12 deletions(-) create mode 100644 content/en/docs/tasks/security/cert-management/custom-ca-k8s/snips.sh create mode 100644 content/en/docs/tasks/security/cert-management/custom-ca-k8s/test.sh diff --git a/content/en/docs/tasks/security/cert-management/custom-ca-k8s/index.md b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/index.md index f8d145e9c6..e270c58ac7 100644 --- a/content/en/docs/tasks/security/cert-management/custom-ca-k8s/index.md +++ b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/index.md @@ -6,7 +6,7 @@ keywords: [security,certificate] aliases: - /docs/tasks/security/custom-ca-k8s/ owner: istio/wg-security-maintainers -test: no +test: yes status: Experimental --- @@ -30,6 +30,12 @@ Cert-manager has added [experimental Support for Kubernetes `CertificateSigningR Make sure to enable feature gate: `--feature-gates=ExperimentalCertificateSigningRequestControllers=true` {{< /warning >}} + {{< text bash >}} + $ helm repo add jetstack https://charts.jetstack.io + $ helm repo update + $ helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set featureGates="ExperimentalCertificateSigningRequestControllers=true" --set installCRDs=true + {{< /text >}} + 1. Create three self signed cluster issuers `istio-system`, `foo` and `bar` for cert-manager. Note: Namespace issuers and other types of issuers can also be used. @@ -125,12 +131,22 @@ Cert-manager has added [experimental Support for Kubernetes `CertificateSigningR $ kubectl apply -f ./selfsigned-issuer.yaml {{< /text >}} +## Verify secrets are created for each cluster issuer + +{{< text bash >}} +$ kubectl get secret -n cert-manager -l controller.cert-manager.io/fao=true +NAME TYPE DATA AGE +bar-ca-selfsigned kubernetes.io/tls 3 3m36s +foo-ca-selfsigned kubernetes.io/tls 3 3m36s +istio-ca-selfsigned kubernetes.io/tls 3 3m38s +{{< /text >}} + ## Export root certificates for each cluster issuer {{< text bash >}} -$ export istioca=$(kubectl get clusterissuers istio-system -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d) -$ export fooca=$(kubectl get clusterissuers foo -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d) -$ export barca=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d) +$ export ISTIOCA=$(kubectl get clusterissuers istio-system -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') +$ export FOOCA=$(kubectl get clusterissuers foo -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') +$ export BARCA=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') {{< /text >}} ## Deploy Istio with default cert-signer info @@ -148,15 +164,15 @@ $ export barca=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretNam ISTIO_META_CERT_SIGNER: istio-system caCertificates: - pem: | - $istioca + $ISTIOCA certSigners: - clusterissuers.cert-manager.io/istio-system - pem: | - $fooca + $FOOCA certSigners: - clusterissuers.cert-manager.io/foo - pem: | - $barca + $BARCA certSigners: - clusterissuers.cert-manager.io/bar components: @@ -186,7 +202,7 @@ $ export barca=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretNam verbs: - approve EOF - $ istioctl install -f ./istio.yaml + $ istioctl install --skip-confirmation -f ./istio.yaml {{< /text >}} 1. Create the `bar` and `foo` namespaces. @@ -251,7 +267,7 @@ When the workloads are deployed, they send CSR requests with related signer info 1. Check network connectivity between service `sleep` and `httpbin` in the `foo` namespace. {{< text bash >}} - $ kubectl exec -it $SLEEP_POD_FOO -n foo -c sleep curl http://httpbin.foo:8000/html + $ kubectl exec "$SLEEP_POD_FOO" -n foo -c sleep -- curl http://httpbin.foo:8000/html @@ -270,18 +286,22 @@ When the workloads are deployed, they send CSR requests with related signer info 1. Check network connectivity between service `sleep` in the `foo` namespace and `httpbin` in the `bar` namespace. {{< text bash >}} - $ kubectl exec -it $SLEEP_POD_FOO -n foo -c sleep curl http://httpbin.bar:8000/html + $ kubectl exec "$SLEEP_POD_FOO" -n foo -c sleep -- curl http://httpbin.bar:8000/html upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED {{< /text >}} ## Cleanup -* Remove the `istio-system`, `foo` and `bar` namespaces: +* Remove the namespaces and uninstall Istio and cert-manager: {{< text bash >}} - $ kubectl delete ns istio-system $ kubectl delete ns foo $ kubectl delete ns bar + $ istioctl uninstall --purge -y + $ helm delete -n cert-manager cert-manager + $ kubectl delete ns istio-system cert-manager + $ unset ISTIOCA FOOCA BARCA + $ rm -rf istio.yaml proxyconfig-foo.yaml proxyconfig-bar.yaml selfsigned-issuer.yaml {{< /text >}} ## Reasons to use this feature diff --git a/content/en/docs/tasks/security/cert-management/custom-ca-k8s/snips.sh b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/snips.sh new file mode 100644 index 0000000000..d28a2eb447 --- /dev/null +++ b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/snips.sh @@ -0,0 +1,271 @@ +#!/bin/bash +# shellcheck disable=SC2034,SC2153,SC2155,SC2164 + +# Copyright Istio Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +#################################################################################################### +# WARNING: THIS IS AN AUTO-GENERATED FILE, DO NOT EDIT. PLEASE MODIFY THE ORIGINAL MARKDOWN FILE: +# docs/tasks/security/cert-management/custom-ca-k8s/index.md +#################################################################################################### + +snip_deploy_custom_ca_controller_in_the_kubernetes_cluster_1() { +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set featureGates="ExperimentalCertificateSigningRequestControllers=true" --set installCRDs=true +} + +snip_deploy_custom_ca_controller_in_the_kubernetes_cluster_2() { +cat < ./selfsigned-issuer.yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-bar-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: bar-ca + namespace: cert-manager +spec: + isCA: true + commonName: bar + secretName: bar-ca-selfsigned + issuerRef: + name: selfsigned-bar-issuer + kind: ClusterIssuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: bar +spec: + ca: + secretName: bar-ca-selfsigned +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-foo-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: foo-ca + namespace: cert-manager +spec: + isCA: true + commonName: foo + secretName: foo-ca-selfsigned + issuerRef: + name: selfsigned-foo-issuer + kind: ClusterIssuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: foo +spec: + ca: + secretName: foo-ca-selfsigned +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-istio-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: istio-ca + namespace: cert-manager +spec: + isCA: true + commonName: istio-system + secretName: istio-ca-selfsigned + issuerRef: + name: selfsigned-istio-issuer + kind: ClusterIssuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: istio-system +spec: + ca: + secretName: istio-ca-selfsigned +EOF +kubectl apply -f ./selfsigned-issuer.yaml +} + +snip_verify_secrets_are_created_for_each_cluster_issuer_1() { +kubectl get secret -n cert-manager -l controller.cert-manager.io/fao=true +} + +! read -r -d '' snip_verify_secrets_are_created_for_each_cluster_issuer_1_out <<\ENDSNIP +NAME TYPE DATA AGE +bar-ca-selfsigned kubernetes.io/tls 3 3m36s +foo-ca-selfsigned kubernetes.io/tls 3 3m36s +istio-ca-selfsigned kubernetes.io/tls 3 3m38s +ENDSNIP + +snip_export_root_certificates_for_each_cluster_issuer_1() { +export ISTIOCA=$(kubectl get clusterissuers istio-system -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') +export FOOCA=$(kubectl get clusterissuers foo -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') +export BARCA=$(kubectl get clusterissuers bar -o jsonpath='{.spec.ca.secretName}' | xargs kubectl get secret -n cert-manager -o jsonpath='{.data.ca\.crt}' | base64 -d | sed 's/^/ /') +} + +snip_deploy_istio_with_default_certsigner_info_1() { +cat < ./istio.yaml +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + meshConfig: + defaultConfig: + proxyMetadata: + ISTIO_META_CERT_SIGNER: istio-system + caCertificates: + - pem: | +$ISTIOCA + certSigners: + - clusterissuers.cert-manager.io/istio-system + - pem: | +$FOOCA + certSigners: + - clusterissuers.cert-manager.io/foo + - pem: | +$BARCA + certSigners: + - clusterissuers.cert-manager.io/bar + components: + pilot: + k8s: + env: + - name: CERT_SIGNER_DOMAIN + value: clusterissuers.cert-manager.io + - name: EXTERNAL_CA + value: ISTIOD_RA_KUBERNETES_API + - name: PILOT_CERT_PROVIDER + value: k8s.io/clusterissuers.cert-manager.io/istio-system + overlays: + - kind: ClusterRole + name: istiod-clusterrole-istio-system + patches: + - path: rules[-1] + value: | + apiGroups: + - certificates.k8s.io + resourceNames: + - clusterissuers.cert-manager.io/foo + - clusterissuers.cert-manager.io/bar + - clusterissuers.cert-manager.io/istio-system + resources: + - signers + verbs: + - approve +EOF +istioctl install --set values.pilot.env.PILOT_ENABLE_CONFIG_DISTRIBUTION_TRACKING=true --skip-confirmation -f ./istio.yaml +} + +snip_deploy_istio_with_default_certsigner_info_2() { +kubectl create ns bar +kubectl create ns foo +} + +snip_deploy_istio_with_default_certsigner_info_3() { +cat < ./proxyconfig-bar.yaml +apiVersion: networking.istio.io/v1beta1 +kind: ProxyConfig +metadata: + name: barpc + namespace: bar +spec: + environmentVariables: + ISTIO_META_CERT_SIGNER: bar +EOF +kubectl apply -f ./proxyconfig-bar.yaml +} + +snip_deploy_istio_with_default_certsigner_info_4() { +cat < ./proxyconfig-foo.yaml +apiVersion: networking.istio.io/v1beta1 +kind: ProxyConfig +metadata: + name: foopc + namespace: foo +spec: + environmentVariables: + ISTIO_META_CERT_SIGNER: foo +EOF +kubectl apply -f ./proxyconfig-foo.yaml +} + +snip_deploy_istio_with_default_certsigner_info_5() { +kubectl label ns foo istio-injection=enabled +kubectl label ns bar istio-injection=enabled +kubectl apply -f samples/httpbin/httpbin.yaml -n foo +kubectl apply -f samples/sleep/sleep.yaml -n foo +kubectl apply -f samples/httpbin/httpbin.yaml -n bar +} + +snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_1() { +export SLEEP_POD_FOO=$(kubectl get pod -n foo -l app=sleep -o jsonpath={.items..metadata.name}) +} + +snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_2() { +kubectl exec "$SLEEP_POD_FOO" -n foo -c sleep -- curl http://httpbin.foo:8000/html +} + +! read -r -d '' snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_2_out <<\ENDSNIP + + + + + +

Herman Melville - Moby-Dick

+ +
+

+ Availing himself of the mild... +

+
+ +ENDSNIP + +snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_3() { +kubectl exec "$SLEEP_POD_FOO" -n foo -c sleep -- curl http://httpbin.bar:8000/html +} + +! read -r -d '' snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_3_out <<\ENDSNIP +upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED +ENDSNIP + +snip_cleanup_1() { +kubectl delete ns foo +kubectl delete ns bar +istioctl uninstall --purge -y +helm delete -n cert-manager cert-manager +kubectl delete ns istio-system cert-manager +unset ISTIOCA FOOCA BARCA +rm -rf istio.yaml proxyconfig-foo.yaml proxyconfig-bar.yaml selfsigned-issuer.yaml +} diff --git a/content/en/docs/tasks/security/cert-management/custom-ca-k8s/test.sh b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/test.sh new file mode 100644 index 0000000000..0f4761a08d --- /dev/null +++ b/content/en/docs/tasks/security/cert-management/custom-ca-k8s/test.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1090,SC2154 + +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# @setup profile=none + +set -e +set -u +set -o pipefail + +# install cert-manager +snip_deploy_custom_ca_controller_in_the_kubernetes_cluster_1 +snip_deploy_custom_ca_controller_in_the_kubernetes_cluster_2 + +_verify_like snip_verify_secrets_are_created_for_each_cluster_issuer_1 "$snip_verify_secrets_are_created_for_each_cluster_issuer_1_out" + +snip_export_root_certificates_for_each_cluster_issuer_1 + +snip_deploy_istio_with_default_certsigner_info_1 +snip_deploy_istio_with_default_certsigner_info_2 +snip_deploy_istio_with_default_certsigner_info_3 +snip_deploy_istio_with_default_certsigner_info_4 + +# deploy test application +snip_deploy_istio_with_default_certsigner_info_5 +_wait_for_deployment foo sleep +_wait_for_deployment foo httpbin +_wait_for_deployment bar httpbin + + +snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_1 +_verify_contains snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_2 "Herman Melville - Moby-Dick" +_verify_contains snip_verify_the_network_connectivity_between_httpbin_and_sleep_within_the_same_namespace_3 "upstream connect error" + +# @cleanup + +snip_cleanup_1 +