TLS configuration example¶
In previous module we deployed an HTTP application, now it will get upgraded to a secure hosted application. Let's imagine that helloworld-v1
didn't handle any sensitive data, but helloworld-v2
requires customers to provide they personal information and if intercepted - the damage by malicious actors can be done.
in this exercise we will demonstrate how an application can be upgraded for plain HTTP to TLS encrypted HTTPS connection. The steps will include:
- creation of HTTPS certificate and key and storing them as Kubernetes secret
- modification of existing Istio VS (virtual service) and GW (gateway) objects
- running
curl
tests to demonstrate the behavior
More to learn and explore¶
Istio introduces a lot of different ways of the certificate usage. mTLS protection of the data is a use-case where Istio has a lot to offer. mTLS is covered in many blog articles that are listed on resources page. In this exercise we're focusing on HTTPS, standard industry approach of certificate protected websites that is applicable for both Istio and traditional workloads.
The prepared certificates can be downloaded from here This is self signed certs, that might expire, we also included a script
Creating secret¶
For this step you have 3 choices:
-
use the prepared secret:
OR
-
download and extract the tarball archive, make sure your Kubernetes context is in the right cluster, create the secret with kubectl command:
OR
-
use the script provided to create your own certificate (we would use it in case the pre-generated certificates are expired):
Modifying Existing Istio Manifests¶
First we'll add the https
section to tid-helloworld
gateway object that previously created.
The following is added - secure port, hostname (note that helloworld.tetrate.io
will match the FQDN created in previous step) and credentials section that is referring to kubernetes secret demo-credentials
, which is also created in the previous step.
Below is the newly added section to the existing tid-helloworld
gateway (the full yaml is available for your consumption):
- port: # mtls block starts here
number: 443
name: https
protocol: HTTPS
hosts:
- helloworld.tetrate.io
tls:
mode: SIMPLE
credentialName: demo-credentials
We will modify virtual service the way that the queries to the plain http calls will go to v1
(green) of helloworld
application while https calls will land on v2
(blue) of helloworld
. Below is the modified spec
portion of the virtual service, while full one is downloadable from here:
spec:
gateways:
- tid-helloworld
hosts:
- helloworld.tetrate.io
http: # the routes are simplified comparing to the previous exercise
- match:
- port: 80
route: # plain http requests will go to v1 (green) helloworld
- destination:
host: helloworld.green.svc.cluster.local
- match: # this part is added for HTTPS
- port: 443
route: # encrypted https requests will go to v2 (blue) helloworld
- destination:
host: helloworld.blue.svc.cluster.local
Confirming the traffic is distributed¶
Step 1 Obtain the public FQDN of AWS LoadBalancer and assign to a variable
ADDR=$(kubectl -n tid-ingress-ns get service tid-ingressgateway -o=jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
validation will be helpful
Step 2A All requests to HTTP helloworld.tetrate.io
server are expected to be going to v1
microservice:
for i in {1..5}; \
do \
curl $ADDR/hello -H "Host: helloworld.tetrate.io"; \
curl $ADDR/hello -H "Host: helloworld.tetrate.io" -H "blue-version: on"; \
done
in response you should only see v1
:
Step 2B All requests to HTTPS helloworld.tetrate.io
server are expected to be going to v2
microservice:
for i in {1..5}; \
do \
curl -k --connect-to helloworld.tetrate.io:443:${ADDR} https://helloworld.tetrate.io/hello; \
curl -k --connect-to helloworld.tetrate.io:443:${ADDR} https://helloworld.tetrate.io/hello -H "blue-version: on"; \
done
NOTES:
-
flag
-k
is used to tell curl that we're calling the site with self-signed certificate and identity validation will not be checked. You can extend command and use--cacert
flag instead: -
we also use
--connect-to
instead of header from previous exercise - it allows resolution to be happen before traffic reaches the HTTPS server. If FQDN is not resolved before - server will not be able to deterministically say what host is being called and what is the matching certificate for this server
in response you should only see v2
:
In this exercise we've demonstrated how traffic can be directed to the the endpoint that presents verifiable TLS certificate.
the video is also available
The last exercise is optional and will allow us to demonstrate how another type of AWS LB can be configured.