Egress Gateway TLS Origination Test Suite (#7501)

* add missing cleanup for vs nginx

* Add test for Gateway TLS Origination

* fix copyright

* Add Gateway mTLS origination

* replace <password> with password

* fix lint and autogen yes response

* oops typos

* make gen

* escape SC2154 :)

* apply suggestions and fix lint

* squash commits and cleanup branch

wrong quotes

more typos

make snips again

linter :'(

make linter happy

newline blocks

make gen 2

tab linting

try this

change service deletion

oops was deploying sleep twice

ignore nginx version lines for expected response

add update snips

lint again

make snips 3

redo check

do some magic

do some magic 2

lint tabs

remove incorrect snip matching

hack tls origination sleep deployment

hack 2

* this test is super flaky

* delete virtual service

* move scripts

* move scripts

* move to new testing framework

end file with newline and cleanup

typo

* content length shouldn't be included in snips

* comment out the final HTTP check

* Update content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/mtls_test.sh

Co-authored-by: Frank Budinsky <frankb@ca.ibm.com>

* Update content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/tls_test.sh

Co-authored-by: Frank Budinsky <frankb@ca.ibm.com>

* Update content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/tls_test.sh

Co-authored-by: Frank Budinsky <frankb@ca.ibm.com>

* ignore cleanup errors

* add source back in

Co-authored-by: Frank Budinsky <frankb@ca.ibm.com>
This commit is contained in:
Navraj Singh Chhina 2020-06-12 13:04:06 -04:00 committed by GitHub
parent 1d7a2383bd
commit 3f6e0312cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 809 additions and 32 deletions

View File

@ -5,7 +5,7 @@ weight: 40
keywords: [traffic-management,egress] keywords: [traffic-management,egress]
aliases: aliases:
- /docs/examples/advanced-gateways/egress-gateway-tls-origination/ - /docs/examples/advanced-gateways/egress-gateway-tls-origination/
test: no test: yes
--- ---
The [TLS Origination for Egress Traffic](/docs/tasks/traffic-management/egress/egress-tls-origination/) The [TLS Origination for Egress Traffic](/docs/tasks/traffic-management/egress/egress-tls-origination/)
@ -80,13 +80,11 @@ be done by the egress gateway, as opposed to by the sidecar in the previous exam
1. Verify that your `ServiceEntry` was applied correctly by sending a request to [http://edition.cnn.com/politics](https://edition.cnn.com/politics). 1. Verify that your `ServiceEntry` was applied correctly by sending a request to [http://edition.cnn.com/politics](https://edition.cnn.com/politics).
{{< text bash >}} {{< text bash >}}
$ kubectl exec $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics $ kubectl exec "${SOURCE_POD}" -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
HTTP/1.1 301 Moved Permanently HTTP/1.1 301 Moved Permanently
... ...
location: https://edition.cnn.com/politics location: https://edition.cnn.com/politics
... ...
command terminated with exit code 35
{{< /text >}} {{< /text >}}
Your `ServiceEntry` was configured correctly if you see _301 Moved Permanently_ in the output. Your `ServiceEntry` was configured correctly if you see _301 Moved Permanently_ in the output.
@ -180,11 +178,9 @@ be done by the egress gateway, as opposed to by the sidecar in the previous exam
1. Send an HTTP request to [http://edition.cnn.com/politics](https://edition.cnn.com/politics). 1. Send an HTTP request to [http://edition.cnn.com/politics](https://edition.cnn.com/politics).
{{< text bash >}} {{< text bash >}}
$ kubectl exec $SOURCE_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics $ kubectl exec "${SOURCE_POD}" -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
HTTP/1.1 200 OK HTTP/1.1 200 OK
... ...
content-length: 150793
...
{{< /text >}} {{< /text >}}
The output should be the same as in the [TLS Origination for Egress Traffic](/docs/tasks/traffic-management/egress/egress-tls-origination/) The output should be the same as in the [TLS Origination for Egress Traffic](/docs/tasks/traffic-management/egress/egress-tls-origination/)
@ -215,6 +211,12 @@ $ kubectl delete destinationrule originate-tls-for-edition-cnn-com
$ kubectl delete destinationrule egressgateway-for-cnn $ kubectl delete destinationrule egressgateway-for-cnn
{{< /text >}} {{< /text >}}
Remove the sleep service and deployment:
{{< text bash >}}
$ kubectl delete -f @samples/sleep/sleep.yaml@
{{< /text >}}
## Perform mutual TLS origination with an egress gateway ## Perform mutual TLS origination with an egress gateway
Similar to the previous section, this section describes how to configure an egress gateway to perform Similar to the previous section, this section describes how to configure an egress gateway to perform
@ -244,10 +246,10 @@ TLS origination.
{{< /text >}} {{< /text >}}
1. Generate the certificates for `nginx.example.com`. 1. Generate the certificates for `nginx.example.com`.
Use any password with the following command: Run the following command, replacing `password` with your choice of password:
{{< text bash >}} {{< text bash >}}
$ ./generate.sh nginx.example.com <password> $ ./generate.sh nginx.example.com password
{{< /text >}} {{< /text >}}
Select `y` for all prompts that appear. Select `y` for all prompts that appear.
@ -289,7 +291,7 @@ the Istio service mesh, i.e., in a namespace without Istio sidecar proxy injecti
1. Create a configuration file for the NGINX server: 1. Create a configuration file for the NGINX server:
{{< text bash >}} {{< text bash >}}
$ cat <<EOF > ./nginx.conf $ cat <<\EOF > ./nginx.conf
events { events {
} }
@ -524,22 +526,9 @@ to hold the configuration of the NGINX server:
Normally, a DNS entry exists for the destination hostname and you would not use the `--resolve` option of `curl`. Normally, a DNS entry exists for the destination hostname and you would not use the `--resolve` option of `curl`.
{{< text bash >}} {{< text bash >}}
$ kubectl exec $SOURCE_POD -c sleep -- curl -v --resolve nginx.example.com:443:1.1.1.1 --cacert /etc/nginx-ca-certs/ca-chain.cert.pem --cert /etc/nginx-client-certs/tls.crt --key /etc/nginx-client-certs/tls.key https://nginx.example.com $ kubectl exec "${SOURCE_POD}" -c sleep -- curl -v --resolve nginx.example.com:443:1.1.1.1 --cacert /etc/nginx-ca-certs/ca-chain.cert.pem --cert /etc/nginx-client-certs/tls.crt --key /etc/nginx-client-certs/tls.key https://nginx.example.com
...
Server certificate:
subject: C=US; ST=Denial; L=Springfield; O=Dis; CN=nginx.example.com
start date: 2018-08-16 04:31:20 GMT
expire date: 2019-08-26 04:31:20 GMT
common name: nginx.example.com (matched)
issuer: C=US; ST=Denial; O=Dis; CN=nginx.example.com
SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.35.0
> Host: nginx.example.com
... ...
< HTTP/1.1 200 OK < HTTP/1.1 200 OK
< Server: nginx/1.15.2
... ...
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -551,13 +540,14 @@ to hold the configuration of the NGINX server:
1. Verify that the server requires the client's certificate: 1. Verify that the server requires the client's certificate:
{{< text bash >}} {{< text bash >}}
$ kubectl exec $(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) -c sleep -- curl -k --resolve nginx.example.com:443:1.1.1.1 https://nginx.example.com $ kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -k --resolve nginx.example.com:443:1.1.1.1 https://nginx.example.com
...
<html> <html>
<head><title>400 No required SSL certificate was sent</title></head> <head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white"> <body>
<center><h1>400 Bad Request</h1></center> <center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center> <center>No required SSL certificate was sent</center>
<hr><center>nginx/1.15.2</center> ...
</body> </body>
</html> </html>
{{< /text >}} {{< /text >}}
@ -629,7 +619,7 @@ to hold the configuration of the NGINX server:
1. Verify that the key and the certificate are successfully loaded in the `istio-egressgateway` pod: 1. Verify that the key and the certificate are successfully loaded in the `istio-egressgateway` pod:
{{< text bash >}} {{< text bash >}}
$ kubectl exec -it -n istio-system $(kubectl -n istio-system get pods -l istio=egressgateway -o jsonpath='{.items[0].metadata.name}') -- ls -al /etc/istio/nginx-client-certs /etc/istio/nginx-ca-certs $ kubectl exec -it -n istio-system "$(kubectl -n istio-system get pods -l istio=egressgateway -o jsonpath='{.items[0].metadata.name}')" -- ls -al /etc/istio/nginx-client-certs /etc/istio/nginx-ca-certs
{{< /text >}} {{< /text >}}
`tls.crt` and `tls.key` should exist in `/etc/istio/nginx-client-certs`, while `ca-chain.cert.pem` in `tls.crt` and `tls.key` should exist in `/etc/istio/nginx-client-certs`, while `ca-chain.cert.pem` in
@ -745,7 +735,7 @@ to hold the configuration of the NGINX server:
1. Send an HTTP request to `http://nginx.example.com`: 1. Send an HTTP request to `http://nginx.example.com`:
{{< text bash >}} {{< text bash >}}
$ kubectl exec $SOURCE_POD -c sleep -- curl -s --resolve nginx.example.com:80:1.1.1.1 http://nginx.example.com $ kubectl exec "${SOURCE_POD}" -c sleep -- curl -s --resolve nginx.example.com:80:1.1.1.1 http://nginx.example.com
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -770,7 +760,7 @@ to hold the configuration of the NGINX server:
1. Remove created Kubernetes resources: 1. Remove created Kubernetes resources:
{{< text bash >}} {{< text syntax=bash snip_id=mutual_tls_cleanup_1 >}}
$ kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external $ kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external
$ kubectl delete secret nginx-client-certs nginx-ca-certs $ kubectl delete secret nginx-client-certs nginx-ca-certs
$ kubectl delete secret nginx-client-certs nginx-ca-certs -n istio-system $ kubectl delete secret nginx-client-certs nginx-ca-certs -n istio-system
@ -780,6 +770,7 @@ to hold the configuration of the NGINX server:
$ kubectl delete namespace mesh-external $ kubectl delete namespace mesh-external
$ kubectl delete gateway istio-egressgateway $ kubectl delete gateway istio-egressgateway
$ kubectl delete serviceentry nginx $ kubectl delete serviceentry nginx
$ kubectl delete virtualservice nginx
$ kubectl delete virtualservice direct-nginx-through-egress-gateway $ kubectl delete virtualservice direct-nginx-through-egress-gateway
$ kubectl delete destinationrule originate-mtls-for-nginx $ kubectl delete destinationrule originate-mtls-for-nginx
$ kubectl delete destinationrule egressgateway-for-nginx $ kubectl delete destinationrule egressgateway-for-nginx
@ -787,13 +778,13 @@ to hold the configuration of the NGINX server:
1. Delete the directory of certificates and the repository used to generate them: 1. Delete the directory of certificates and the repository used to generate them:
{{< text bash >}} {{< text syntax=bash snip_id=mutual_tls_cleanup_2 >}}
$ rm -rf nginx.example.com mtls-go-example $ rm -rf nginx.example.com mtls-go-example
{{< /text >}} {{< /text >}}
1. Delete the generated configuration files used in this example: 1. Delete the generated configuration files used in this example:
{{< text bash >}} {{< text syntax=bash snip_id=mutual_tls_cleanup_3 >}}
$ rm -f ./nginx.conf ./istio-egressgateway.yaml $ rm -f ./nginx.conf ./istio-egressgateway.yaml
{{< /text >}} {{< /text >}}

View File

@ -0,0 +1,93 @@
#!/usr/bin/env bash
# shellcheck disable=SC1090,SC2154
# Copyright 2020 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 "${REPO_ROOT}/content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/snips.sh"
# Generate Certificates for service outside the mesh to use for mTLS
snip_generate_client_and_server_certificates_and_keys_1
snip_generate_client_and_server_certificates_and_keys_2
set +e # suppress harmless "No such file or directory:../crypto/bio/bss_file.c:72:fopen('1_root/index.txt.attr','r')" error
yes | snip_generate_client_and_server_certificates_and_keys_3
set -e
snip_generate_client_and_server_certificates_and_keys_4
snip_generate_client_and_server_certificates_and_keys_5
# Deploy a new namespace to mimic an external mesh
snip_deploy_a_mutual_tls_server_1
# Create k8s secret with Server and CA certificates
snip_deploy_a_mutual_tls_server_2
# Setup nginx config
snip_deploy_a_mutual_tls_server_3
# Create configMap for nginx config
snip_deploy_a_mutual_tls_server_4
# Create nginx deployment in external mesh
snip_deploy_a_mutual_tls_server_5
# Generate ServiceEntry and VirtualService for the external service
snip_deploy_a_mutual_tls_server_6
# Generate Secret to hold client certificates
snip_deploy_a_container_to_test_the_nginx_deployment_1
# Deploy sleep sample service with certificates mounted and export SOURCE_POD
set +e
kubectl delete pods -l app=sleep --force
set -e
snip_deploy_a_container_to_test_the_nginx_deployment_2
_wait_for_deployment default sleep
snip_deploy_a_container_to_test_the_nginx_deployment_3
# Verify that mTLS connection is set up properly
_verify_elided snip_deploy_a_container_to_test_the_nginx_deployment_4 "$snip_deploy_a_container_to_test_the_nginx_deployment_4_out"
# Verify that without client certificate request is rejected
_verify_contains snip_deploy_a_container_to_test_the_nginx_deployment_5 "400 No required SSL certificate was sent"
# Store Client and CA certificates using k8s secret
snip_redeploy_the_egress_gateway_with_the_client_certificates_1
# Redeploy and patch Egress Gateway using client cert secrets
snip_redeploy_the_egress_gateway_with_the_client_certificates_2
snip_redeploy_the_egress_gateway_with_the_client_certificates_3
# TODO: verify tls certs are successfully loaded in istio-egressgateway pod
# Direct traffic through egress gateway by creating necessary Gateway, DR, and Virtual Service
snip_configure_mutual_tls_origination_for_egress_traffic_1
snip_configure_mutual_tls_origination_for_egress_traffic_2
# TODO: Verify HTTP connection to nginx
# _verify_contains snip_configure_mutual_tls_origination_for_egress_traffic_3 "Welcome to nginx!"
#TODO: verify request is actually being routed through egress gateway
# @cleanup
set +e # ignore cleanup errors
snip_mutual_tls_cleanup_1
snip_mutual_tls_cleanup_2
snip_mutual_tls_cleanup_3
snip_cleanup_1

View File

@ -0,0 +1,641 @@
#!/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/traffic-management/egress/egress-gateway-tls-origination/index.md
####################################################################################################
snip_before_you_begin_1() {
kubectl apply -f samples/sleep/sleep.yaml
}
snip_before_you_begin_2() {
kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml)
}
snip_before_you_begin_3() {
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
}
snip_perform_tls_origination_with_an_egress_gateway_1() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: cnn
spec:
hosts:
- edition.cnn.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
EOF
}
snip_perform_tls_origination_with_an_egress_gateway_2() {
kubectl exec "${SOURCE_POD}" -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
}
! read -r -d '' snip_perform_tls_origination_with_an_egress_gateway_2_out <<\ENDSNIP
HTTP/1.1 301 Moved Permanently
...
location: https://edition.cnn.com/politics
...
ENDSNIP
snip_perform_tls_origination_with_an_egress_gateway_3() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http-port-for-tls-origination
protocol: HTTP
hosts:
- edition.cnn.com
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-cnn
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: cnn
EOF
}
snip_perform_tls_origination_with_an_egress_gateway_4() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-cnn-through-egress-gateway
spec:
hosts:
- edition.cnn.com
gateways:
- istio-egressgateway
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: cnn
port:
number: 80
weight: 100
- match:
- gateways:
- istio-egressgateway
port: 80
route:
- destination:
host: edition.cnn.com
port:
number: 443
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-tls-for-edition-cnn-com
spec:
host: edition.cnn.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE # initiates HTTPS for connections to edition.cnn.com
EOF
}
snip_perform_tls_origination_with_an_egress_gateway_5() {
kubectl exec "${SOURCE_POD}" -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics
}
! read -r -d '' snip_perform_tls_origination_with_an_egress_gateway_5_out <<\ENDSNIP
HTTP/1.1 200 OK
...
ENDSNIP
snip_perform_tls_origination_with_an_egress_gateway_6() {
kubectl logs -l istio=egressgateway -c istio-proxy -n istio-system | tail
}
snip_cleanup_the_tls_origination_example_1() {
kubectl delete gateway istio-egressgateway
kubectl delete serviceentry cnn
kubectl delete virtualservice direct-cnn-through-egress-gateway
kubectl delete destinationrule originate-tls-for-edition-cnn-com
kubectl delete destinationrule egressgateway-for-cnn
}
snip_cleanup_the_tls_origination_example_2() {
kubectl delete -f samples/sleep/sleep.yaml
}
snip_generate_client_and_server_certificates_and_keys_1() {
git clone https://github.com/nicholasjackson/mtls-go-example
}
snip_generate_client_and_server_certificates_and_keys_2() {
cd mtls-go-example
}
snip_generate_client_and_server_certificates_and_keys_3() {
./generate.sh nginx.example.com password
}
snip_generate_client_and_server_certificates_and_keys_4() {
mkdir ../nginx.example.com && mv 1_root 2_intermediate 3_application 4_client ../nginx.example.com
}
snip_generate_client_and_server_certificates_and_keys_5() {
cd ..
}
snip_deploy_a_mutual_tls_server_1() {
kubectl create namespace mesh-external
}
snip_deploy_a_mutual_tls_server_2() {
kubectl create -n mesh-external secret tls nginx-server-certs --key nginx.example.com/3_application/private/nginx.example.com.key.pem --cert nginx.example.com/3_application/certs/nginx.example.com.cert.pem
kubectl create -n mesh-external secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
}
snip_deploy_a_mutual_tls_server_3() {
cat <<\EOF > ./nginx.conf
events {
}
http {
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log;
server {
listen 443 ssl;
root /usr/share/nginx/html;
index index.html;
server_name nginx.example.com;
ssl_certificate /etc/nginx-server-certs/tls.crt;
ssl_certificate_key /etc/nginx-server-certs/tls.key;
ssl_client_certificate /etc/nginx-ca-certs/ca-chain.cert.pem;
ssl_verify_client on;
}
}
EOF
}
snip_deploy_a_mutual_tls_server_4() {
kubectl create configmap nginx-configmap -n mesh-external --from-file=nginx.conf=./nginx.conf
}
snip_deploy_a_mutual_tls_server_5() {
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: my-nginx
namespace: mesh-external
labels:
run: my-nginx
spec:
ports:
- port: 443
protocol: TCP
selector:
run: my-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
namespace: mesh-external
spec:
selector:
matchLabels:
run: my-nginx
replicas: 1
template:
metadata:
labels:
run: my-nginx
spec:
containers:
- name: my-nginx
image: nginx
ports:
- containerPort: 443
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx
readOnly: true
- name: nginx-server-certs
mountPath: /etc/nginx-server-certs
readOnly: true
- name: nginx-ca-certs
mountPath: /etc/nginx-ca-certs
readOnly: true
volumes:
- name: nginx-config
configMap:
name: nginx-configmap
- name: nginx-server-certs
secret:
secretName: nginx-server-certs
- name: nginx-ca-certs
secret:
secretName: nginx-ca-certs
EOF
}
snip_deploy_a_mutual_tls_server_6() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: nginx
spec:
hosts:
- nginx.example.com
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
resolution: DNS
endpoints:
- address: my-nginx.mesh-external.svc.cluster.local
ports:
https: 443
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- nginx.example.com
tls:
- match:
- port: 443
sniHosts:
- nginx.example.com
route:
- destination:
host: nginx.example.com
port:
number: 443
weight: 100
EOF
}
snip_deploy_a_container_to_test_the_nginx_deployment_1() {
kubectl create secret tls nginx-client-certs --key nginx.example.com/4_client/private/nginx.example.com.key.pem --cert nginx.example.com/4_client/certs/nginx.example.com.cert.pem
kubectl create secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
}
snip_deploy_a_container_to_test_the_nginx_deployment_2() {
kubectl apply -f - <<EOF
# Copyright 2017 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.
##################################################################################################
# Sleep service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: sleep
labels:
app: sleep
spec:
ports:
- port: 80
name: http
selector:
app: sleep
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
selector:
matchLabels:
app: sleep
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: tutum/curl
command: ["/bin/sleep","infinity"]
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nginx-client-certs
mountPath: /etc/nginx-client-certs
readOnly: true
- name: nginx-ca-certs
mountPath: /etc/nginx-ca-certs
readOnly: true
volumes:
- name: nginx-client-certs
secret:
secretName: nginx-client-certs
- name: nginx-ca-certs
secret:
secretName: nginx-ca-certs
EOF
}
snip_deploy_a_container_to_test_the_nginx_deployment_3() {
export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
}
snip_deploy_a_container_to_test_the_nginx_deployment_4() {
kubectl exec "${SOURCE_POD}" -c sleep -- curl -v --resolve nginx.example.com:443:1.1.1.1 --cacert /etc/nginx-ca-certs/ca-chain.cert.pem --cert /etc/nginx-client-certs/tls.crt --key /etc/nginx-client-certs/tls.key https://nginx.example.com
}
! read -r -d '' snip_deploy_a_container_to_test_the_nginx_deployment_4_out <<\ENDSNIP
...
< HTTP/1.1 200 OK
...
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
ENDSNIP
snip_deploy_a_container_to_test_the_nginx_deployment_5() {
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -k --resolve nginx.example.com:443:1.1.1.1 https://nginx.example.com
}
! read -r -d '' snip_deploy_a_container_to_test_the_nginx_deployment_5_out <<\ENDSNIP
...
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
...
</body>
</html>
ENDSNIP
snip_redeploy_the_egress_gateway_with_the_client_certificates_1() {
kubectl create -n istio-system secret tls nginx-client-certs --key nginx.example.com/4_client/private/nginx.example.com.key.pem --cert nginx.example.com/4_client/certs/nginx.example.com.cert.pem
kubectl create -n istio-system secret generic nginx-ca-certs --from-file=nginx.example.com/2_intermediate/certs/ca-chain.cert.pem
}
snip_redeploy_the_egress_gateway_with_the_client_certificates_2() {
cat > gateway-patch.json <<EOF
[{
"op": "add",
"path": "/spec/template/spec/containers/0/volumeMounts/0",
"value": {
"mountPath": "/etc/istio/nginx-client-certs",
"name": "nginx-client-certs",
"readOnly": true
}
},
{
"op": "add",
"path": "/spec/template/spec/volumes/0",
"value": {
"name": "nginx-client-certs",
"secret": {
"secretName": "nginx-client-certs",
"optional": true
}
}
},
{
"op": "add",
"path": "/spec/template/spec/containers/0/volumeMounts/1",
"value": {
"mountPath": "/etc/istio/nginx-ca-certs",
"name": "nginx-ca-certs",
"readOnly": true
}
},
{
"op": "add",
"path": "/spec/template/spec/volumes/1",
"value": {
"name": "nginx-ca-certs",
"secret": {
"secretName": "nginx-ca-certs",
"optional": true
}
}
}]
EOF
}
snip_redeploy_the_egress_gateway_with_the_client_certificates_3() {
kubectl -n istio-system patch --type=json deploy istio-egressgateway -p "$(cat gateway-patch.json)"
}
snip_redeploy_the_egress_gateway_with_the_client_certificates_4() {
kubectl exec -it -n istio-system "$(kubectl -n istio-system get pods -l istio=egressgateway -o jsonpath='{.items[0].metadata.name}')" -- ls -al /etc/istio/nginx-client-certs /etc/istio/nginx-ca-certs
}
snip_configure_mutual_tls_origination_for_egress_traffic_1() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
spec:
selector:
istio: egressgateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- nginx.example.com
tls:
mode: MUTUAL
serverCertificate: /etc/certs/cert-chain.pem
privateKey: /etc/certs/key.pem
caCertificates: /etc/certs/root-cert.pem
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: egressgateway-for-nginx
spec:
host: istio-egressgateway.istio-system.svc.cluster.local
subsets:
- name: nginx
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: ISTIO_MUTUAL
sni: nginx.example.com
EOF
}
snip_configure_mutual_tls_origination_for_egress_traffic_2() {
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: direct-nginx-through-egress-gateway
spec:
hosts:
- nginx.example.com
gateways:
- istio-egressgateway
- mesh
http:
- match:
- gateways:
- mesh
port: 80
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: nginx
port:
number: 443
weight: 100
- match:
- gateways:
- istio-egressgateway
port: 443
route:
- destination:
host: nginx.example.com
port:
number: 443
weight: 100
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: originate-mtls-for-nginx
spec:
host: nginx.example.com
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
portLevelSettings:
- port:
number: 443
tls:
mode: MUTUAL
clientCertificate: /etc/istio/nginx-client-certs/tls.crt
privateKey: /etc/istio/nginx-client-certs/tls.key
caCertificates: /etc/istio/nginx-ca-certs/ca-chain.cert.pem
sni: nginx.example.com
EOF
}
snip_configure_mutual_tls_origination_for_egress_traffic_3() {
kubectl exec "${SOURCE_POD}" -c sleep -- curl -s --resolve nginx.example.com:80:1.1.1.1 http://nginx.example.com
}
! read -r -d '' snip_configure_mutual_tls_origination_for_egress_traffic_3_out <<\ENDSNIP
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
ENDSNIP
snip_configure_mutual_tls_origination_for_egress_traffic_4() {
kubectl logs -l istio=egressgateway -n istio-system | grep 'nginx.example.com' | grep HTTP
}
snip_mutual_tls_cleanup_1() {
kubectl delete secret nginx-server-certs nginx-ca-certs -n mesh-external
kubectl delete secret nginx-client-certs nginx-ca-certs
kubectl delete secret nginx-client-certs nginx-ca-certs -n istio-system
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 gateway istio-egressgateway
kubectl delete serviceentry nginx
kubectl delete virtualservice nginx
kubectl delete virtualservice direct-nginx-through-egress-gateway
kubectl delete destinationrule originate-mtls-for-nginx
kubectl delete destinationrule egressgateway-for-nginx
}
snip_mutual_tls_cleanup_2() {
rm -rf nginx.example.com mtls-go-example
}
snip_mutual_tls_cleanup_3() {
rm -f ./nginx.conf ./istio-egressgateway.yaml
}
snip_cleanup_1() {
kubectl delete service sleep
kubectl delete deployment sleep
}

View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
# shellcheck disable=SC1090,SC2154
# Copyright 2020 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 "${REPO_ROOT}/content/en/docs/tasks/traffic-management/egress/egress-gateway-tls-origination/snips.sh"
# Deploy sleep sample and set up variable pointing to it
set +e
kubectl delete pods -l app=sleep --force
set -e
snip_before_you_begin_2
_wait_for_deployment default sleep
snip_before_you_begin_3
# Apply ServiceEntry for external workload and verify 301
snip_perform_tls_origination_with_an_egress_gateway_1
_verify_elided snip_perform_tls_origination_with_an_egress_gateway_2 "$snip_perform_tls_origination_with_an_egress_gateway_2_out"
# Create Gateway and DR to forward sidecar requests to egress gateway
snip_perform_tls_origination_with_an_egress_gateway_3
# Create VirtualService to direct traffic through gateway and deploy DR to originate Simple TLS
snip_perform_tls_origination_with_an_egress_gateway_4
# Verify HTTP request to external service returns 200
_verify_elided snip_perform_tls_origination_with_an_egress_gateway_5 "$snip_perform_tls_origination_with_an_egress_gateway_5_out"
# TODO: verify that the request was routed through egressgateway
# @cleanup
set +e # ignore cleanup errors
snip_cleanup_the_tls_origination_example_1
snip_cleanup_the_tls_origination_example_2