Skip to main content
logoTetrate Service ExpressVersion: Latest

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

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.

  1. Deploy the sleep Test Client

    Deploy the sleep app in a bare (no sidecar injection) sleep namespace.

  2. Test with HTTP and HTTPS traffic

    Test connectivity for HTTP and HTTPS requests.

  3. 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:

TSE Organizational Settings - disable 'Enforce mTLS'

Turn off the Enforce mTLS toggle.

Test with and without Enforce mTLS

  1. 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>.

  2. 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
  3. Repeat with an HTTPS request (note -k and https://):

    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