Reputation: 2400
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:
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.
Mounted these at a well-defined location inside a pod (the sleep
pod in Istio samples actually) running in mesh-apps
.
Deployed an app inside legacy
and exposed it using a ClusterIP service called mymtls-app
on port 8443.
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
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:
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
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