Mutual TLS communication between Istio mesh
Mutual TLS communication is about trusting each other between client and server. It is different from standard TLS that only client need to trust the server. In mutual TLS, server also need to trust client.
In Istio mesh, this type of communication can be archive directly because all of the proxy share same root CA. Also mutual TLS communication between multiple Istio mesh also can be archive by sharing the root CA via multicluster configuration. But what should we do when we cannot share the root CA to other?
This article give you another prespective how to archive mutual TLS communication between Istio mesh using 3rd root CA that both of the mesh agree and trust, as shown in picture below:
Environment
- two Kubernetes cluster with Istio mesh enabled
- a domain (that use to access the service) that resolve to istio-ingressgateway (that should be public, we can simulate using dnsmasq but I am to lazy to do that)
- step & step-ca to generate certificate
Configuration
Certificate
Before configuring the cluster, we need to generate 3rd root CA, client & server certificate that will be use to make mutual TLS, we will using step certificate for that.
Note: I still need more context how we define the subject alternative name, will comeback here to fix this if necessary. Because we will using helloworld.zufar.io
as the service domain.
Cluster A
Cluster A will act as client side of the mutual TLS communication.
- Create namespace client
- Create certificate for client
- Create client deployment and mount the certificate via Istio annotation
This annotation will mount certificate inside a secret to istio-proxy
sidecar in the /etc/cluster-a-client
.
- Create VirtualService object
virtualService will upgrade HTTP connection to HTTPS connection when accessing helloworld.zufar.io
VirtualService add a subset name tls-origination
to HTTPS connection. This subset will be used by DestinationRule
.
- Create ServiceEntry object
ServiceEntry object will enable Istio control feature when accessing helloworld.zufar.io
. We will inject certificate so we need the Istio control feature
- Create DestinationRule object
DestinationRule object will inject certificate that require by mutual TLS
Thats all on the client side, for making mutual TLS communication, client can use HTTP communication http://helloworld.zufar.io
and no code change. Istio sidecar will upgrade to HTTPS and enable mutual TLS!
Cluster B
Cluster B will act as server side, have service helloworld inside. The traffic will enter istio-ingressgateway and terminate mutual TLS there. Istio then forward traffic as plain http to helloworld service.
- Create certificate for istio-ingressgateway
The certificate must be on istio-system
namespace. Or if you have custom istio-ingressgateway, it must place in the same namespace as the istio-ingressgateway.
- Create namespace service
- Create deployment and service for helloworld
- Create Gateway object
Gateway object will serve the HTTPS communication and add the certificate to istio-ingressgateway.
Note: I need more context about why the hosts should asterisk (*). Currently, my understanding is because the root CA is created without any DNS attach to it. I will get back as I get more understanding about this.
- Create VirtualService object
VirtualService object will match host helloworld.zufar.io
from service-gateway
and route to the correct helloworld
service in service
namespace.
Testing
We cannot se the mutual TLS communication because it is abstracted by Istio sidecar and Istio-ingressgateway. Client can use HTTP communication http://helloworld.zufar.io
and Istio sidecar will upgrade to HTTPS and enable mutual TLS. To see the packet, we can use wireshark with sniff to capture the packet. We can capture packet inside sidecar (istio-proxy) with this command from cluster A:
Conclusion
Mutual TLS enabled trust between client and server. Mutual TLS can be archive by difference approach, via Istio multicluster or via this way. Thank you!