mTLS / Istio : Sécuriser un service exposé à l'exterieur du service mesh
Cet article décrit comment exposer un service à l'extérieur d'Istio en le sécurisant avec du mutual TLS.
Summary
Cet article décrit comment exposer un service à l’extérieur d’Istio en le sécurisant avec du mutual TLS.
Context
Tout le monde connait ou a entendu parler de TLS (anciennement SSL). Ce protocole permet de chiffrer les communications et de s’assurer que le client discute avec le bon serveur, ce dernier s’authentifiant auprès du client en envoyant un certificat.
Le mTLS (ou mutual TLS) est une version étendue du protocole TLS qui, toujours en permettant de chiffrer les communications, permet non seulement au client de s’assurer que le serveur auquel il s’addresse est le bon, mais permet aussi au serveur d’être sûr que le client est bien autorisé à l’appeler.
Dans cette article, nous allons voir comment configurer Istio pour exposer un service à l’extérieur du service mesh en le sécurisant avec le protocole mTLS.
Ce modèle avec authentification mutuelle apporte évidemment un meilleur niveau de sécurité (Merci à notre équipe cybersécurité :))
Quelques rappels sur Istio
L’exposition d’un service au sein d’un service mesh géré avec Istio ce décompose ainsi :
- Une exposition du cluster via un Loadbalancer.
- Un point d’entrée dans le cluster avec terminaison ssl réalisée par l’Ingress Gateway Istio.
- Le certificat est stocké dans un secret dans le cluster.
- La configuration du certificat TLS est réalisée dans la configuration de l’Ingress Gateway Istio.
La configuration de l’Ingress Gateway Istio est réalisée avec :
- Une ressource custom
Gateway
- Une ressource custom
VirtualService
De quoi avons-nous besoin ?
Nous avons besoin :
En plus d’un cluster Kubernetes avec istio d’installé (il est possible d’utiliser microK8s et son plugin istio pour tester. N’ayant dans ce cas pas de Load Balancer, on accédera à la gateway istio en l’exposant en local avec la commande mk8sctl port-forward -n istio-system service/istio-ingressgateway 8080:80
)
- d’une autorité de certification pour valider les certificats lors de la négociation TLS.
- d’un “certificat serveur” pour que le serveur s’identifie auprès du client.
- d’un “certificat client” pour que le client s’identifie auprès du server.
- d’une clé privée pour le client pour chiffrer le premier échange avec le serveur.
- d’une application de test. Nous utiliserons l’appli httpbin fournie comme example avec Istio.
Génération des certificats
Pour réaliser ces tâches, nous allons utiliser OpenSSL.
Génération de l’autorité de certification
On obtient le fichier ca.crt
qui sera à fournir au client et au serveur
pour que les 2 puissent valider les certificats qui vont être générés ci-après.
On obtient aussi le fichier ca.key
contenant la clé privée permettant de signer des certificats avec cette autorité.
Inspection de l’autorité de certification
On voit bien que les champs Issuer et Subject sont les mêmes. Nous avons donc notre autorité de certification.
Génération de la clé et du certificat pour le serveur
Génération de la clé
Création de la Certificate Signing Request (CSR)
Signature du certificat serveur
Génération de la clé et du certificat pour le client
Génération de la clé
Création de la Certificate Signing Request (CSR)
Signature du certificat client
Dans notre cas, nous maîtrisons “à la fois” le client et le serveur. Dans le cas d'une configuration pour appeler un service fourni par un tiers
, celui-ci ne fournira que l’équivalent de notre ca.crt et ne diffusera jamais sa clé privée (le ca.key). Ce certificat seul permet de vérifier un autre certificat mais ne permet pas d’en signer. Il faudra donc lui envoyer la CSR
afin qu’il nous renvoie le certificat client signé.
Pour cet article, nous allons signer notre certificat client nous-même.
Configuration d’Istio
Création du secret
Nous allons créer un secret contenant le certificat serveur et sa clé privée ainsi que le certificat de l’autorité de certification.
Le secret est de type generic
mais il est possible de créer un secret de type tls
. Seule la syntaxe des clés dans le secret change. Voir la documentation d’Istio
L’application déployée ici étant httpbin
, le secret est nommé httpbin-mtls
mais le nom importe peu.
Déploiement de l’application
Contenu du fichier httpbin.yaml
contenant la description du déploiement :
Déploiement
Configuration de l’Ingress Gateway Istio
Nous allons déployer deux ressources custom d’Istio pour configurer l’Ingress Gateway :
- une ressource de type
VirtualService
pour router les requêtes vers notre application. - une ressource de type
Gateway
pour configurer leshosts
traités par l’Ingress Gateway Istio ainsi que la partieTLS
.
Contenu du fichier httpbin-gw-and-vs.yaml
contenant la description du déploiement :
La configuration du mutual TLS tient en ces lignes :
On spécifie le mode MUTUAL
et le nom du secret créé précédemment pour la valeur de credentialName
.
Tests
Avec le l’autorité de certification mais sans utiliser le certificat client
Sans utiliser le certificat client ni l’autorité de certification
Avec le certificat client mais sans utiliser l’autorité de certification
Avec le certificat client et l’autorité de certification