Istio adventures — disabling mTLS for one namespace

Imagine you have an Istio installation where mTLS is enabled for the whole cluster. You should have something like this:

Kiali shows some mTLS hints — graph edges and lock in the masthead.

In terms of configuration, you should have the following pieces:

  1. One MeshPolicy enabling services to receive connections in mTLS mode.
apiVersion: “authentication.istio.io/v1alpha1”
kind: “MeshPolicy”
metadata:
name: “default”
spec:
peers:
— mtls: {}

2. One DestinationRule enabling all the clients* of your service mesh to start communications in mTLS.

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "default"
namespace: "default"
spec:
host: "*.local"
trafficPolicy:
tls:
mode: ISTIO_MUTUAL

*We usually call workloads clients. Workloads are all the entities on the service mesh that are able to start communications with other services or ServiceEntries (endpoints outside the service mesh).

For more information about the integrity of both rules, Kiali have the Istio Config Section. There you can list all the Istio Objects that are living in your cluster. Thanks to the filtering, you can easily find both pieces of config described just above.

I want to disable mTLS for one namespace, what should I do?

Two different things need to be done. We will have to change the behavior for both clients and services again.

  1. In order to enable services to receive non-mTLS connections, we need to create a policy as follows:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "default"
namespace: "bookinfo"
spec:
peers:
- mtls:
mode: PERMISSIVE

The PERMISSIVE mode allows services to receive all kinds of connections: plaintext or TLS. In addition to the mode, one interesting thing to note here is that the Policy must be named as “default” as it doesn’t have a targets field.

It is important to apply the Policy first in order to allow all services to receive both plain and mTLS connections. If you apply the DestinationRule first, you would have all the workloads starting connections in plain but any service would be available to respond.

2. Regarding clients, we need to define a new DestinationRule overriding the trafficPolicy declared in the mesh-wide one.

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "disable-mtls"
namespace: "bookinfo"
spec:
host: "*.bookinfo.svc.cluster.local"
trafficPolicy:
tls:
mode: DISABLE

The overriding mechanism of Istio has nothing to do with the names of the config names. In the snippet above I change the DestinationRule’s name for one more self-explanatory (disable-mtls) and it works.

Once both configs are published in the Service Mesh, this is what you should see:

IstioMesh start to transition from mTLS to plain connections

Open lock in the edges of your service mesh shows that either part or all of the traffic is unencrypted (not using mTLS). Right after applying the previous configs most of the traffic still uses mTLS. Nevertheless, locks on the edges warn that there is unencrypted traffic going through. The exact amount of mTLS traffic is displayed in the right hand side panel.

24% of the last minute request traffic used mTLS

After some time with mTLS disabled for the namespace, the graph snould be fully green with full traffic unencrypted. However, your mesh-wide mTLS is still enabled.

100% of traffic is not using mTLS

As a final check, I strongly suggest that you go to the Istio Config section and see if there are any warnings coming from Kiali’s validation system.

List of object filtered by bookinfo namespace. No validations found.

One common mistake

When you have a Mesh Policy defining mTLS in STRICT mode, you are saying that all the traffic within your service mesh has to use the mTLS protocol. Therefore, when you want to disable traffic for either a namespace or a service you do not want to have traffic using mTLS. So this goes against the MeshPolicy definition.

Look what happens when you only specify the Destination Rule that disables mTLS (and don’t have any namespace-wide Policy defined):

Istio Config — Mesh-wide mTLS enabled, Destination Rule disabling mTLS traffic

As we can see, our service mesh has:

  • disable-mtls DestinationRule disabling mTLS for bookinfo namespace.
  • default DestinationRule enabling mTLS for whole connection in the service mesh.
  • default MeshPolicy STRICTLY allowing mTLS on all the services.

The important point here is that the DestinationRule has a problem. Also important: Kiali warns you. See below:

Kiali validation suggest to add a permissive Policy allowing non-mTLS traffic

Kiali says MeshPolicy enabling mTLS found, permissive policy is needed It means that the MeshPolicy is forcing mTLS traffic, so disabling mTLS here will lead to a wrong configuration. Also, Kiali suggests that you add a permissive policy.

In order to fix that, you have two options: either set MeshPolicy to permissive mode (which is not good practice) or add a Policy in permissive mode to bookinfo namespace (as we saw in the first part of this article).