diff --git a/bin/init.sh b/bin/init.sh index 3856a97a5c..6f3273b552 100755 --- a/bin/init.sh +++ b/bin/init.sh @@ -62,8 +62,9 @@ cp -a "${ISTIO_OUT}/release/istioctl-linux-amd64" /gobin/istioctl popd > /dev/null # Copy install/samples files over from Istio. These are needed by the tests. -rm -rf "${ISTIOIO_GO}/samples" "${ISTIOIO_GO}/tests/integration" "${ISTIOIO_GO}/manifests" +rm -rf "${ISTIOIO_GO}/samples" "${ISTIOIO_GO}/tools" "${ISTIOIO_GO}/tests/integration" "${ISTIOIO_GO}/manifests" cp -a "${ISTIO_GO}/samples" "${ISTIOIO_GO}/samples" +cp -a "${ISTIO_GO}/tools" "${ISTIOIO_GO}/tools" mkdir "${ISTIOIO_GO}/tests/integration/" cp -a "${ISTIO_GO}/tests/integration/iop-integration-test-defaults.yaml" "${ISTIOIO_GO}/tests/integration/" cp -a "${ISTIO_GO}/manifests" "${ISTIOIO_GO}/manifests" diff --git a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/ca-hierarchy.svg b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/ca-hierarchy.svg new file mode 100644 index 0000000000..d4087e2952 --- /dev/null +++ b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/ca-hierarchy.svg @@ -0,0 +1,398 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + Cluster 1 + + + Intermediate CA + + + + + + Workload + + + + Cluster 2 + + + Intermediate CA + + + + + + Workload + + + + + Root CA + + + + Manually provision certs + + diff --git a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/index.md b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/index.md index 4516932eee..41e5beb398 100644 --- a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/index.md +++ b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/index.md @@ -1,6 +1,6 @@ --- -title: Plugging in existing CA Certificates -description: Shows how system administrators can configure Istio's CA with an existing root certificate, signing certificate and key. +title: Plug in CA Certificates +description: Shows how system administrators can configure Istio's CA with a root certificate, signing certificate and key. weight: 80 keywords: [security,certificates] aliases: @@ -9,47 +9,98 @@ owner: istio/wg-security-maintainers test: yes --- -This task shows how administrators can configure the Istio certificate authority with an existing root certificate, signing certificate and key. +This task shows how administrators can configure the Istio certificate authority (CA) with a root certificate, +signing certificate and key. By default, Istio's CA generates a self-signed root certificate and key, and uses them to sign the workload certificates. Istio's CA can also sign workload certificates using an administrator-specified certificate and key, and with an -administrator-specified root certificate. This task demonstrates how to plug such certificates and key into Istio's CA. +administrator-specified root certificate. -## Plugging in existing certificates and key +A root CA is used by all workloads within a mesh as the root of trust. Each Istio CA uses an intermediate CA +signing key and certificate, signed by the root CA. When multiple Istio CAs exist within a mesh, this establishes a +hierarchy of trust among the CAs. -Suppose we want to have Istio's CA use an existing signing (CA) certificate `ca-cert.pem` and key `ca-key.pem`. -Furthermore, the certificate `ca-cert.pem` is signed by the root certificate `root-cert.pem`. -We would like to use `root-cert.pem` as the root certificate for Istio workloads. +{{< image width="80%" + link="ca-hierarchy.svg" + caption="CA Hierarchy" + >}} -In the following example, -Istio CA's signing (CA) certificate (`ca-cert.pem`) is different from the root certificate (`root-cert.pem`), -so the workload cannot validate the workload certificates directly from the root certificate. -The workload needs a `cert-chain.pem` file to specify the chain of trust, -which should include the certificates of all the intermediate CAs between the workloads and the root CA. -In our example, it contains Istio CA's signing certificate, so `cert-chain.pem` is the same as `ca-cert.pem`. -Note that if your `ca-cert.pem` is the same as `root-cert.pem`, the `cert-chain.pem` file should be empty. +This task demonstrates how to generate and plug in the certificates and key for Istio's CA. These steps can be repeated +to provision certificates and keys for any number of Istio CAs. -These files are ready to use in the `samples/certs/` directory. +## Plug in certificates and key into the cluster {{< tip >}} -The default Istio CA installation configures the location of certificates and keys based on the -predefined secret and file names used in the command below (i.e., secret named `cacerts`, root certificate -in a file named `root-cert.pem`, Istio CA's key in `ca-key.pem`, etc.). -You must use these specific secret and file names, or reconfigure Istio's CA when you deploy Istio. +For production cluster setup, it is a good practice to do the following on an offline machine with good +security protection. The root private key should be exposed to as few people and processes as possible. {{< /tip >}} -The following steps plug in the certificates and key into a Kubernetes secret, -which will be read by Istio's CA: +1. Create a directory for holding certificates and keys: + + {{< text bash >}} + $ mkdir -p certs + $ pushd certs + {{< /text >}} + +1. Generate the root certificate and key: + + {{< text bash >}} + $ make -f ../tools/certs/Makefile.selfsigned.mk root-ca + {{< /text >}} + + This will generate the following files: + + * `root-cert.pem`: the generated root certificate + * `root-key.pem`: the generated root key + * `root-ca.conf`: the configuration for `openssl` to generate the root certificate + * `root-cert.csr`: the generated CSR for the root certificate + +1. Generate an intermediate certificate and key: + + {{< text bash >}} + $ make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts + {{< /text >}} + + This will generate the following files in a directory named `cluster1`: + + * `ca-cert.pem`: the generated intermediate certificates + * `ca-key.pem`: the generated intermediate key + * `cert-chain.pem`: the generated certificate chain which is used by istiod + * `root-cert.pem`: the root certificate + * `intermediate.conf`: the configuration for `openssl` to generate the intermediate certificate + * `cluster-ca.csr`: the generated CSR for the intermediate certificate + + {{< tip >}} + You can replace `cluster1` with a string of your choosing. For example, `make mycluster-certs` will + result in the creation of a directory called `mycluster`. + {{< /tip >}} + + {{< tip >}} + To configure additional Istio CAs, you can repeat this step with different cluster/directory names. + {{< /tip >}} + + If you are doing this on an offline machine, copy the generated directory to a machine with access to the + clusters. 1. Create a secret `cacerts` including all the input files `ca-cert.pem`, `ca-key.pem`, `root-cert.pem` and `cert-chain.pem`: {{< text bash >}} $ kubectl create namespace istio-system - $ kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem \ - --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem \ - --from-file=samples/certs/cert-chain.pem + $ kubectl create secret generic cacerts -n istio-system \ + --from-file=cluster1/ca-cert.pem \ + --from-file=cluster1/ca-key.pem \ + --from-file=cluster1/root-cert.pem \ + --from-file=cluster1/cert-chain.pem {{< /text >}} +1. Return to the top-level directory of the Istio installation: + + {{< text bash >}} + $ popd + {{< /text >}} + +## Deploy Istio + 1. Deploy Istio using the `demo` profile. Istio's CA will read certificates and key from the secret-mount files. @@ -106,7 +157,7 @@ openssl command is expected. 1. Verify the root certificate is the same as the one specified by the administrator: {{< text bash >}} - $ openssl x509 -in samples/certs/root-cert.pem -text -noout > /tmp/root-cert.crt.txt + $ openssl x509 -in certs/cluster1/root-cert.pem -text -noout > /tmp/root-cert.crt.txt $ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt $ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical @@ -115,7 +166,7 @@ openssl command is expected. 1. Verify the CA certificate is the same as the one specified by the administrator: {{< text bash >}} - $ openssl x509 -in samples/certs/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt + $ openssl x509 -in certs/cluster1/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt $ openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt $ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical @@ -124,13 +175,19 @@ openssl command is expected. 1. Verify the certificate chain from the root certificate to the workload certificate: {{< text bash >}} - $ openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.pem) ./proxy-cert-1.pem + $ openssl verify -CAfile <(cat certs/cluster1/ca-cert.pem certs/cluster1/root-cert.pem) ./proxy-cert-1.pem ./proxy-cert-1.pem: OK {{< /text >}} ## Cleanup -* To remove the secret `cacerts`, and the `foo` and `istio-system` namespaces: +* Remove the certificates, keys, and intermediate files from your local disk: + + {{< text bash >}} + $ rm -rf certs + {{< /text >}} + +* Remove the secret `cacerts`, and the `foo` and `istio-system` namespaces: {{< text bash >}} $ kubectl delete secret cacerts -n istio-system diff --git a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/snips.sh b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/snips.sh index 57c34ea903..466b6a5647 100644 --- a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/snips.sh +++ b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/snips.sh @@ -20,14 +20,33 @@ # docs/tasks/security/cert-management/plugin-ca-cert/index.md #################################################################################################### -snip_plugging_in_existing_certificates_and_key_1() { -kubectl create namespace istio-system -kubectl create secret generic cacerts -n istio-system --from-file=samples/certs/ca-cert.pem \ - --from-file=samples/certs/ca-key.pem --from-file=samples/certs/root-cert.pem \ - --from-file=samples/certs/cert-chain.pem +snip_plug_in_certificates_and_key_into_the_cluster_1() { +mkdir -p certs +pushd certs } -snip_plugging_in_existing_certificates_and_key_2() { +snip_plug_in_certificates_and_key_into_the_cluster_2() { +make -f ../tools/certs/Makefile.selfsigned.mk root-ca +} + +snip_plug_in_certificates_and_key_into_the_cluster_3() { +make -f ../tools/certs/Makefile.selfsigned.mk cluster1-cacerts +} + +snip_plug_in_certificates_and_key_into_the_cluster_4() { +kubectl create namespace istio-system +kubectl create secret generic cacerts -n istio-system \ + --from-file=cluster1/ca-cert.pem \ + --from-file=cluster1/ca-key.pem \ + --from-file=cluster1/root-cert.pem \ + --from-file=cluster1/cert-chain.pem +} + +snip_plug_in_certificates_and_key_into_the_cluster_5() { +popd +} + +snip_deploy_istio_1() { istioctl install --set profile=demo } @@ -59,7 +78,7 @@ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter } snip_verifying_the_certificates_3() { -openssl x509 -in samples/certs/root-cert.pem -text -noout > /tmp/root-cert.crt.txt +openssl x509 -in certs/cluster1/root-cert.pem -text -noout > /tmp/root-cert.crt.txt openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt } @@ -69,7 +88,7 @@ Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical ENDSNIP snip_verifying_the_certificates_4() { -openssl x509 -in samples/certs/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt +openssl x509 -in certs/cluster1/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt } @@ -79,7 +98,7 @@ Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical ENDSNIP snip_verifying_the_certificates_5() { -openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.pem) ./proxy-cert-1.pem +openssl verify -CAfile <(cat certs/cluster1/ca-cert.pem certs/cluster1/root-cert.pem) ./proxy-cert-1.pem } ! read -r -d '' snip_verifying_the_certificates_5_out <<\ENDSNIP @@ -87,6 +106,10 @@ openssl verify -CAfile <(cat samples/certs/ca-cert.pem samples/certs/root-cert.p ENDSNIP snip_cleanup_1() { +rm -rf certs +} + +snip_cleanup_2() { kubectl delete secret cacerts -n istio-system kubectl delete ns foo istio-system } diff --git a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/test.sh b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/test.sh index 66c5d0705b..71d4261cd2 100644 --- a/content/en/docs/tasks/security/cert-management/plugin-ca-cert/test.sh +++ b/content/en/docs/tasks/security/cert-management/plugin-ca-cert/test.sh @@ -21,8 +21,13 @@ set -o pipefail # @setup profile=none -snip_plugging_in_existing_certificates_and_key_1 -echo y | snip_plugging_in_existing_certificates_and_key_2 +snip_plug_in_certificates_and_key_into_the_cluster_1 +snip_plug_in_certificates_and_key_into_the_cluster_2 +snip_plug_in_certificates_and_key_into_the_cluster_3 +snip_plug_in_certificates_and_key_into_the_cluster_4 +snip_plug_in_certificates_and_key_into_the_cluster_5 + +echo y | snip_deploy_istio_1 _wait_for_deployment istio-system istiod # create_ns_foo_with_httpbin_sleep @@ -55,3 +60,4 @@ _verify_same snip_verifying_the_certificates_5 "$snip_verifying_the_certificates # @cleanup set +e # ignore cleanup errors snip_cleanup_1 +snip_cleanup_2