Document Egress mTLS origination at sidecar using credentialName in DR (#11301)

* Documentation for egress mTLS origination at sidecar using credentialName in DR

The feature is already merged. So trying to add a documentation for the same.

Signed-off-by: Faseela K <faseela.k@est.tech>

* Remove duplicate code and point to the existing documentation

Signed-off-by: Faseela K <faseela.k@est.tech>

* Fix test failures

Signed-off-by: Faseela K <faseela.k@est.tech>

* Fix test failures

Signed-off-by: Faseela K <faseela.k@est.tech>

* Add tests for mTLS origination at sidecar

Signed-off-by: Faseela K <faseela.k@est.tech>
This commit is contained in:
Faseela K 2022-05-19 17:16:58 +02:00 committed by GitHub
parent 75b3537412
commit db2b88790e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 274 additions and 9 deletions

View File

@ -194,17 +194,138 @@ are being sent by inspecting [Server Name Indication (SNI)](https://en.wikipedia
The _SNI_ field is sent unencrypted during the TLS handshake. Using HTTPS prevents the attackers from knowing specific
topics and articles but does not prevent an attackers from learning that `edition.cnn.com` is accessed.
## Cleanup
### Cleanup the TLS origination configuration
1. Remove the Istio configuration items you created:
Remove the Istio configuration items you created:
{{< text bash >}}
$ kubectl delete serviceentry edition-cnn-com
$ kubectl delete destinationrule edition-cnn-com
{{< /text >}}
1. Shutdown the [sleep]({{< github_tree >}}/samples/sleep) service:
## Mutual TLS origination for egress traffic
This section describes how to configure a sidecar to perform TLS origination for an external service, this time using a
service that requires mutual TLS. This example is considerably more involved because it requires the following setup:
1. Generate client and server certificates
1. Deploy an external service that supports the mutual TLS protocol
1. Configure the client (sleep pod) to use the credentials created in Step 1
Once this setup is complete, you can then configure the external traffic to go through the sidecar which will perform
TLS origination.
### Generate client and server certificates and keys
Follow [these steps](/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/#generate-client-and-server-certificates-and-keys)
in the Egress Gateway TLS Origination task.
### Deploy a mutual TLS server
Follow [these steps](/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/#deploy-a-mutual-tls-server) in the Egress Gateway TLS Origination task.
### Configure the client (sleep pod)
1. Create Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) to hold the client's certificates:
{{< text bash >}}
$ kubectl delete -f @samples/sleep/sleep.yaml@
$ kubectl create secret generic client-credential --from-file=tls.key=client.example.com.key \
--from-file=tls.crt=client.example.com.crt --from-file=ca.crt=example.com.crt
{{< /text >}}
The secret **must** be created in the same namespace as the client pod is deployed in, `default` in this case.
1. Create required `RBAC` to make sure the secret created in the above step is accessible to the client pod, which is `sleep` in this case.
{{< text bash >}}
$ kubectl create role client-credential-role --resource=secret --verb=get,list,watch
$ kubectl create rolebinding client-credential-role-binding --role=client-credential-role --serviceaccount=default:sleep
{{< /text >}}
### Configure mutual TLS origination for egress traffic at sidecar
1. Add a `DestinationRule` to perform mutual TLS origination
{{< text bash >}}
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-mtls-for-nginx
spec:
workloadSelector:
matchLabels:
app: sleep
host: my-nginx.mesh-external.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: MUTUAL
credentialName: client-credential # this must match the secret created earlier to hold client certs, and works only when DR has a workloadSelector
sni: my-nginx.mesh-external.svc.cluster.local
EOF
{{< /text >}}
1. Send an HTTP request to `http://my-nginx.mesh-external.svc.cluster.local`:
{{< text bash >}}
$ kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -sS http://my-nginx.mesh-external.svc.cluster.local:443
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
{{< /text >}}
1. Check the log of the `sleep` pod for a line corresponding to our request.
{{< text bash >}}
$ kubectl logs -l app=sleep -c istio-proxy | grep 'my-nginx.mesh-external.svc.cluster.local'
{{< /text >}}
You should see a line similar to the following:
{{< text plain>}}
[2022-05-19T10:01:06.795Z] "GET / HTTP/1.1" 200 - via_upstream - "-" 0 615 1 0 "-" "curl/7.83.1-DEV" "96e8d8a7-92ce-9939-aa47-9f5f530a69fb" "my-nginx.mesh-external.svc.cluster.local:443" "10.107.176.65:443"
{{< /text >}}
### Cleanup the mutual TLS origination configuration
1. Remove created Kubernetes resources:
{{< text bash >}}
$ kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external
$ kubectl delete secret client-credential
$ kubectl delete configmap nginx-configmap -n mesh-external
$ kubectl delete service my-nginx -n mesh-external
$ kubectl delete deployment my-nginx -n mesh-external
$ kubectl delete namespace mesh-external
$ kubectl delete serviceentry originate-mtls-for-nginx
$ kubectl delete destinationrule originate-mtls-for-nginx
{{< /text >}}
1. Delete the certificates and private keys:
{{< text bash >}}
$ rm example.com.crt example.com.key my-nginx.mesh-external.svc.cluster.local.crt my-nginx.mesh-external.svc.cluster.local.key my-nginx.mesh-external.svc.cluster.local.csr client.example.com.crt client.example.com.csr client.example.com.key
{{< /text >}}
1. Delete the generated configuration files used in this example:
{{< text bash >}}
$ rm ./nginx.conf
{{< /text >}}
## Cleanup common configuration
Delete the `sleep` service and deployment:
{{< text bash >}}
$ kubectl delete service sleep
$ kubectl delete deployment sleep
{{< /text >}}

View File

@ -0,0 +1,74 @@
#!/usr/bin/env bash
# shellcheck disable=SC1090,SC2154
# Copyright 2022 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=demo
set -e
set -u
set -o pipefail
source "content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/snips.sh"
source "tests/util/samples.sh"
# Make sure automatic sidecar injection is enabled
kubectl label namespace default istio-injection=enabled || true
# Deploy sleep sample
# Deploy sample and set up variable pointing to it
startup_sleep_sample
snip_before_you_begin_3
# Generate Certificates for service outside the mesh to use for mTLS
set +e # suppress harmless "No such file or directory:../crypto/bio/bss_file.c:72:fopen('1_root/index.txt.attr','r')" error
snip_generate_client_and_server_certificates_and_keys_1
snip_generate_client_and_server_certificates_and_keys_2
snip_generate_client_and_server_certificates_and_keys_3
set -e
# Create mesh-external namespace
snip_deploy_a_mutual_tls_server_1
# Setup sever with certs and config
snip_deploy_a_mutual_tls_server_2
snip_deploy_a_mutual_tls_server_3
snip_deploy_a_mutual_tls_server_4
snip_deploy_a_mutual_tls_server_5
# Wait for nginx
_wait_for_deployment mesh-external my-nginx
# Configure sleep pod
snip_configure_the_client_sleep_pod_1
snip_configure_the_client_sleep_pod_2
# Configure mTLS for egress traffic from sidecar to external service
snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_1
_wait_for_istio destinationrule default originate-mtls-for-nginx
# Verify that mTLS connection is set up properly
_verify_contains snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_2 "Welcome to nginx!"
# Verify request is hitting the sidecar
_verify_contains snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_3 "GET / HTTP/1.1"
# @cleanup
kubectl label namespace default istio-injection-
snip_cleanup_the_mutual_tls_origination_configuration_1
snip_cleanup_the_mutual_tls_origination_configuration_2
snip_cleanup_the_mutual_tls_origination_configuration_3
cleanup_sleep_sample

View File

@ -118,11 +118,81 @@ HTTP/2 200
...
ENDSNIP
snip_cleanup_1() {
snip_cleanup_the_tls_origination_configuration_1() {
kubectl delete serviceentry edition-cnn-com
kubectl delete destinationrule edition-cnn-com
}
snip_cleanup_2() {
kubectl delete -f samples/sleep/sleep.yaml
snip_configure_the_client_sleep_pod_1() {
kubectl create secret generic client-credential --from-file=tls.key=client.example.com.key \
--from-file=tls.crt=client.example.com.crt --from-file=ca.crt=example.com.crt
}
snip_configure_the_client_sleep_pod_2() {
kubectl create role client-credential-role --resource=secret --verb=get,list,watch
kubectl create rolebinding client-credential-role-binding --role=client-credential-role --serviceaccount=default:sleep
}
snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_1() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-mtls-for-nginx
spec:
workloadSelector:
matchLabels:
app: sleep
host: my-nginx.mesh-external.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: MUTUAL
credentialName: client-credential # this must match the secret created earlier to hold client certs, and works only when DR has a workloadSelector
sni: my-nginx.mesh-external.svc.cluster.local
EOF
}
snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_2() {
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -sS http://my-nginx.mesh-external.svc.cluster.local:443
}
! read -r -d '' snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_2_out <<\ENDSNIP
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
ENDSNIP
snip_configure_mutual_tls_origination_for_egress_traffic_at_sidecar_3() {
kubectl logs -l app=sleep -c istio-proxy | grep 'my-nginx.mesh-external.svc.cluster.local'
}
snip_cleanup_the_mutual_tls_origination_configuration_1() {
kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external
kubectl delete secret client-credential
kubectl delete configmap nginx-configmap -n mesh-external
kubectl delete service my-nginx -n mesh-external
kubectl delete deployment my-nginx -n mesh-external
kubectl delete namespace mesh-external
kubectl delete serviceentry originate-mtls-for-nginx
kubectl delete destinationrule originate-mtls-for-nginx
}
snip_cleanup_the_mutual_tls_origination_configuration_2() {
rm example.com.crt example.com.key my-nginx.mesh-external.svc.cluster.local.crt my-nginx.mesh-external.svc.cluster.local.key my-nginx.mesh-external.svc.cluster.local.csr client.example.com.crt client.example.com.csr client.example.com.key
}
snip_cleanup_the_mutual_tls_origination_configuration_3() {
rm ./nginx.conf
}
snip_cleanup_common_configuration_1() {
kubectl delete service sleep
kubectl delete deployment sleep
}

View File

@ -48,5 +48,5 @@ _verify_elided snip_curl_origination_http "$snip_curl_origination_http_out"
_verify_elided snip_curl_origination_https "$snip_curl_origination_https_out"
# @cleanup
snip_cleanup_1
snip_cleanup_2
snip_cleanup_the_tls_origination_configuration_1
cleanup_sleep_sample