Where to mount mTLS certs referred to in DestinationRule

My DestinationRule is not related to any particular workload, but matches a host on a ServiceEntry (external service). To setup Mutual TLS to that external service, I have something like the following defined:

  tls:
    mode: MUTUAL
    clientCertificate: /etc/certs/tls.crt
    privateKey: /etc/certs/tls.key

But where do these certs need to be mounted – on what pod? (We are trying to forward ingress traffic directly to the external service, without any pods inside the mesh getting involved.)

I’m surprised no one has been able to answer this? Any help would be appreciated.

I’ve been able to make everything work properly for regular TLS (non-mutual), but the mTLS has really stymied me.

What workload do the tls cert locations normally refer to? Is it something in the istio-system namespace?

You can mount the certificate directly via annotation in deployment/pod yaml.
you can using something like

  annotations:                                                                                       
    sidecar.istio.io/userVolumeMount: '[{"name":"your-secret-name", "mountPath":"path-in-istio-proxy", "readonly":true}]'
    sidecar.istio.io/userVolume: '[{"name":"your-secret-name", "secret":{"secretName":"your-secret-name"}}]'

see my blog if you want, https://zufardhiyaulhaq.com/Istio-mutual-TLS-between-clusters/

1 Like

Thanks very much @Zufar_Dhiyaulhaq! I will give this a try and let you know!

Hi @Zufar_Dhiyaulhaq, in your blog article you are mounting those certificates via annotation to the sleep pod, which is your client.

In my scenario there is no client pod – the caller is outside of Istio. For example I call through POSTMAN using a Host header with a value like “test-sandbox-service-mesh.mycompany.com”, and my VirtualService (which matches that host) forwards the traffic, but there are no pods involved. It’s like we’re using Istio as a reverse proxy.

Here is my VirtualService. The system/console route works exactly as desired, using SIMPLE TLS. But for the other route, important-api/v1, which needs to use MUTUAL TLS, I don’t know where to mount the certs.

  apiVersion: networking.istio.io/v1alpha3
  kind: VirtualService
  metadata:
    name: api-dev-virtualservice
    namespace: test-sandbox
  spec:
    gateways:
    - service-mesh-mycompany-gateway
    hosts:
    - test-sandbox-service-mesh.mycompany.com
    http:
    - match:
      - uri:
          prefix: /important-api/v1
      route:
      - destination:
          host: apiserver-dev.mycompany.com
          port:
            number: 11443 # mutual TLS port
    - match:
      - uri:
          prefix: /system/console
      route:
      - destination:
          host: apiserver-dev.mycompany.com
          port:
            number: 443 # simple TLS port

I dont know using postman, but using curl, you can use option --cacert, --cert, and --key.

Yes, but in my scenario the client is untrusted and does not have access to the TLS certs. (Postman or curl are just test clients representing a real front-end app.) We want Istio to manage the Mutual TLS to the back-end server.

Front-end app makes plain HTTP(S) call --> Istio forwards traffic to back-end service and originates mTLS --> back-end service handles request

I have this all working with regular TLS, it’s just the mutual TLS that’s causing an issue.

Okay, I finally figured it out. For my scenario the certs needed to be mounted on the istio-ingressgateway workload (this is in the istio-system namespace). Now both regular TLS and mTLS are working properly.

Thanks for your help as I worked through this @Zufar_Dhiyaulhaq.

One important thing: Be sure to limit that destinationRule to its namespace by explicitly setting the exportTo parameter to ‘.’

Otherwise it will be active in all namespaces by default, and require all istio-sidecars in all pods of all namespaces to mount those secrets, otherwise the pods won’t start.

(At least that’s what happened in my case with caCertificates)

1 Like