Enforce Encryption with Mutual TLS
The Platform Owner can define global policies for all applications in the TSE platform, such as 'mTLS required'
The TSE platform owner can define global polices that apply to all services running in the TSE platform. In this exercise, we'll see how to test a service, and we'll require that all services in the TSE mesh use mTLS exclusively:
- When Enforce mTLS is not active, clients anywhere can access services within the mesh using plain HTTP
- When Enforce mTLS is active, clients must use HTTPS and must authenticate using credentials issued by the mesh
Prerequisites
- You have installed TSE and onboarded a cluster
- You have installed the Bookinfo App and verified it is working
- You have disabled the Deny-All setting in the TSE Administration Settings
Apply and Test 'Enforce mTLS'
The bookinfo app is installed in a TSE-managed mesh. We will use the sleep application to send test traffic to the bookinfo services.
Deploy the sleep Test Client
Deploy the sleep app in a bare (no sidecar injection) sleep namespace.
Test with HTTP and HTTPS traffic
Test connectivity for HTTP and HTTPS requests.
Join the Mesh
Add the sleep client to the mesh and re-test.
Deploy the sleep Test Client
First, we will deploy the sleep app in a bare (no sidecar injection) sleep namespace. This will allow us to test traffic from outside the mesh.
kubectl create namespace sleep
kubectl apply -n sleep -f https://raw.githubusercontent.com/istio/istio/master/samples/sleep/sleep.yaml
Test with HTTP and HTTPS traffic
Disable the requirement for mTLS
First, ensure that mTLS is not required globally. Navigate to the Basic Organizational Settings:
Turn off the Enforce mTLS toggle.
Test with and without Enforce mTLS
-
Test with a plain HTTP request, from the sleep container outside the mesh:
kubectl exec deploy/sleep -n sleep -- curl -sS "http://productpage.bookinfo:9080/productpage" | grep "<title>"
You should see the output
<title>Simple Bookstore App</title>
. -
Now Enforce mTLS and repeat the test:
kubectl exec deploy/sleep -n sleep -- curl -sS "http://productpage.bookinfo:9080/productpage" | grep "<title>"
The request will fail because you now require all services in the mesh to be addressable with mTLS only:
curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56 -
Repeat with an HTTPS request (note
-k
andhttps://
):kubectl exec deploy/sleep -n sleep -- curl -sSk "https://productpage.bookinfo:9080/productpage" | grep "<title>"
The request fails because the mesh also requires HTTPS clients to authenticate themselves with a client certificate:
curl: (56) OpenSSL SSL_read: OpenSSL/1.1.1t: error:1409445C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required, errno 0
command terminated with exit code 56
Join the Mesh
If you redeploy the sleep pod with the mesh sidecar injected, then HTTP requests will succeed:
Relabel the sleep namespace so that pods deployed within are added to the mesh, and redeploy the sleep pod:
kubectl label ns sleep istio-injection=enabled
kubectl rollout restart -n sleep deploy sleep
Confirm that the new sleep pod now consists of two containers ('READY: 2/2'):
kubectl get pod -n sleep
Submit an HTTP request; this will be intercepted and proxied by the sidecar to the other mesh services:
kubectl exec deploy/sleep -n sleep -- curl -sS "http://productpage.bookinfo:9080/productpage" | grep "<title>"
What have we achieved?
We have seen how TSE can easily enforce a security policy that mesh-hosted services can only be accessed by clients who are also in the mesh.
We'll see in a later exercise how to configure an Ingress Gateway to allow external traffic into the mesh in a controlled manner.
Cleaning Up
Remove the sleep namespace and pod as follows:
kubectl delete -n sleep -f https://raw.githubusercontent.com/istio/istio/master/samples/sleep/sleep.yaml
kubectl delete namespace sleep