MTLS in Istio
Setup Mutual TLS in Istio Service Mesh by plugging in existing CA Certificates
Mutual TLS Authentication refers to two parties authenticating each other at the same time. Which means that mtls ensures that traffic is secured in both the directions between client and server. In this case, the server only accepts the connections for the clients registered with the server certificate authority. This is what pretty much happens in mtls, where the connection of both the sides verify the certificates.
How to configure MTLS in Istio?
In Istio MTLS is enabled by default when istio is installed in your Kubernetes Cluster. MTLS modes are of two types in Istio.
- Permissive: By default the mode of MTLS in Istio is Permissive. The permissive mode can accept both plain and text and mutual TLS traffic.
- Strict: This mode makes sure that mtls traffic is enabled between workloads. All the plain traffic would be dropped off when the Strict mode is enabled.
Plugging in our own CA certificates in Istio.
By default, Istio generates a self-signed root certificate and key and uses them to sign the certificates of all the other workloads. But in an Organization, you wouldn't want to use them, you would be having your own CA and you would want to get it signed by your own CA. You would want to use your own certificates instead of third party certificates. Thanks to Istio for giving us an option to Plugin existing CA certificates to sign the workloads.
For this demo let’s see how we can generate our own CA and Plug them into Istio.
So let’s create a CA certificate that would be used to sign other workload certificates.
I have used these commands to generate a sample CA certificate. However, this is not applicable to production environments, as we would not be using self-signed certificates in production environments.
CONFIG="
[req]
distinguished_name=dn
[ dn ]
[ ext ]
basicConstraints=CA:TRUE,pathlen:0
"openssl req -config <(echo "$CONFIG") -new -newkey rsa:2048 -nodes \
-subj "/C=IN/O=Pavan-Solutions/OU=Cloud-DevOps/ST=AP/CN=cluster.local/emailAddress=pavan@istio-medium.com" -x509 -extensions ext -keyout root-key.pem -out root-cert.pemcp root-cert.pem ca-cert.pem
cp root-key.pem ca-key.pem
cp ca-cert.pem cert-chain.pem
Now let us create a secret that would be used by istiod to sign the workloads. This assumes that istio is not installed in the cluster.
kubectl create ns istio-system kubectl create secret generic cacerts -n istio-system - from-file=ca-cert.pem - from-file=ca-key.pem - from-file=root-cert.pem
- from-file=cert-chain.pem
After you create the secret let us Install istio in our Cluster. You may follow this guide to Install istio in your cluster.
Before you actually test out the mtls. Let’s deploy the policy that would enforce all the traffic between the workloads should be mtls only. Let us deploy the policy now.
Let’s deploy a sample application and verify the certificates.
Let us deploy a service for this pod.
Once after the pod is up and running let us verify the certificates by executing a command in the envoy container of the httpd-v1 pod
kubectl exec httpd-v1 -c istio-proxy -n default — openssl s_client -showcerts -connect web-service:80
If you examine the certs precisely you could find that the certs are actually plugged by you. You can also use the method specified in this page to verify your certificates.
What if you already have istio up and running and you want to change the certificates? How will your deployments pick up the new certificates? In this case to avoid downtime of your pods/applications you can perform a rolling restart on your deployment so that the pods pick up the new certificates.
kubectl rollout restart deployment <deployment_name>
Let us now visualize the same using kiali
istioctl dashboard kiali
Now if you clearly see the snapshot you can see the padlock symbol between workloads which indicates that all the traffic flowing between the workloads is encrypted.