CppNoob
CppNoob

Reputation: 2400

Istio: DestinationRule for a legacy service outside the mesh

I have a k8s cluster with Istio deployed in the istio-system namespace, and sidecar injection enabled by default in another namespace called mesh-apps. I also have a second legacy namespace which contains certain applications that do their own TLS termination. I am trying to setup mTLS access between services running inside the mesh-apps namespace and those running inside legacy.

For this purpose, I have done the following:

  1. Created a secret in the mesh-apps namespace containing the client cert, key and CAcert to be used to connect with an application in legacy via mTLS.

  2. Mounted these at a well-defined location inside a pod (the sleep pod in Istio samples actually) running in mesh-apps.

  3. Deployed an app inside legacy and exposed it using a ClusterIP service called mymtls-app on port 8443.

  4. Created the following destination rule in the mesh-apps namespace, hoping that this enables mTLS access from mesh-apps to legacy.

    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: originate-mtls
    spec:
      host: mymtls-app.legacy.svc.cluster.local
      trafficPolicy:
        portLevelSettings:
        - port:
            number: 8443
          tls:
            mode: MUTUAL
            clientCertificate: /etc/sleep/tls/server.cert
            privateKey: /etc/sleep/tls/server.key
            caCertificates: /etc/sleep/tls/ca.pem
            sni: mymtls-app.legacy.svc.cluster.local
    

Now when I run the following command from inside the sleep pod, I would have expected the above DestinationRule to take effect:

kubectl exec sleep-37893-foobar -c sleep -- curl http://mymtls-app.legacy.svc.cluster.local:8443/hello

But instead I just get the error:

Client sent an HTTP request to an HTTPS server.

If I add https in the URL, then this is the error:

curl: (56) OpenSSL SSL_read: error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate, errno 0
command terminated with exit code 56

Upvotes: 0

Views: 740

Answers (1)

CppNoob
CppNoob

Reputation: 2400

I figured my own mistake. I needed to correctly mount the certificate, private key, and CA chain in the sidecar, not in the app container. In order to mount them in the sidecar, I performed the following actions:

  1. Created a secret with the cert, private key and CA chain.

    kubectl create secret generic sleep-secret -n mesh-apps \
      --from-file=server.key=/home/johndoe/certs_mtls/client.key \
      --from-file=server.cert=/home/johndoe/certs_mtls/client.crt \
      --from-file=ca.pem=/home/johndoe/certs_mtls/server_ca.pem
    
  2. Modified the deployment manifest for the sleep container thus:

      template:
        metadata:
          annotations:
            sidecar.istio.io/userVolumeMount: '[{"name": "secret-volume", "mountPath": "/etc/sleep/tls", "readonly": true}]'
            sidecar.istio.io/userVolume: '[{"name": "secret-volume", "secret": {"secretName": "sleep-secret"}}]'
    

Actually I had already created the secret earlier, but it was mounted in the app container (sleep) instead of the sidecar, in this way:

spec:
  volumes:
  - name: <secret_volume_name>
    secret:
      secretName: <secret_name>
      optional: true
  containers:
  - name: ...
    volumeMounts:
    - mountPath: ...
      name: <secret_volume_name>

Upvotes: 2

Related Questions