Implémenter TLS dans Kubernetes
Rubaiat Hossain
31 juillet 2023
0 minutes de lectureÀ mesure que les technologies cloud évoluent, la demande en Kubernetes explose. La sécurité est donc devenue une priorité absolue pour les développeurs qui cherchent à protéger les données de leurs applications. C’est là qu’intervient TLS (Transport Layer Security). TLS est essentiel pour sécuriser la connexion entre vos applications et Internet.
TLS utilise des techniques de cryptographie asymétrique et symétrique pour protéger vos données en transit et au repos. Le certificat TLS utilisé dans Kubernetes est généralement un certificat à clé publique délivré par une autorité de certification (CA) de confiance. Il contient des informations sur l’identité du serveur, la clé publique utilisée pour le chiffrement et la signature numérique de l’autorité qui l’a délivré.
Cet article vous guide dans la mise en place d’une connexion TLS pour vos applications sur un cluster Kubernetes et vous aide à comprendre en profondeur TLS ainsi que son importance pour la sécurité de vos applications et de vos données.
Mise en œuvre de TLS pour les workloads Kubernetes
Lorsque des requêtes entrantes sont adressées à une application exécutée dans un cluster Kubernetes, elles passent par un composant réseau qui sert de passerelle au trafic entrant. Selon la configuration de votre application, ce composant réseau peut être un contrôleur Ingress Kubernetes, un service d’équilibrage de charge, un service ClusterIP ou un service NodePort.
Kubernetes ne fournit pas d’implémentation TLS par défaut pour chiffrer les communications entre le client et le composant réseau. Les requêtes sont donc traitées via HTTP, et non HTTPS. Vous pouvez toutefois configurer facilement votre application Kubernetes pour utiliser HTTPS et sécuriser les communications avec TLS.
Kubernetes propose également des fonctionnalités telles que les Secrets et les ConfigMaps, qui permettent de gérer de manière sécurisée vos certificats TLS et les autres données sensibles nécessaires à votre application.
Historiquement, TLS (et son prédécesseur, SSL) était mis en œuvre entre les systèmes et les utilisateurs qui nécessitaient des communications sécurisées. Avec la multiplication des systèmes distribués, la forte baisse des coûts et de l’impact sur les performances liés à la mise en œuvre de TLS — sans oublier les préoccupations croissantes en matière de confidentialité —, la plupart des experts recommandent désormais de chiffrer tout le trafic. Voici quelques cas d’usage courants du chiffrement réseau :
Systèmes de paiement : Si votre application traite des données de paiement, comme des coordonnées bancaires ou des numéros de carte bancaire, vous devez mettre en œuvre TLS. Il s’agit d’une exigence réglementaire indispensable pour garantir la sécurité des données des utilisateurs en transit. Le chiffrement des données de paiement renforce également la confiance de vos clients et leur permet d’utiliser vos services en toute sérénité.
Chiffrement des données de bout en bout avec un maillage de services : En utilisant un mécanisme de chiffrement des données de bout en bout avec un maillage de services comme Istio, TLS peut sécuriser les communications entre les différents microservices d’un cluster Kubernetes. Cette approche est très répandue dans les architectures modernes de microservices distribués.
IoT et edge computing : Les applications Kubernetes qui interagissent avec des appareils IoT ou des systèmes d’edge computing doivent mettre en œuvre TLS afin de sécuriser la transmission des données entre les appareils et le cloud et d’empêcher tout accès non autorisé aux données générées par les appareils IoT.
Réseaux de diffusion de contenu (CDN) : Si vos applications utilisent des CDN pour mettre en cache et diffuser du contenu, la mise en œuvre de TLS peut contribuer à sécuriser la transmission du contenu et à empêcher toute altération des données ou tout accès non autorisé.
Configurer TLS dans Kubernetes
Dans les sections suivantes, vous allez mettre en œuvre TLS pour une application Kubernetes simple, à l’aide d’un projet Node.js qui simule une application de traitement des paiements. Le code de l’application et la configuration Kubernetes nécessaire sont disponibles dans ce dépôt GitHub.
Prérequis
Pour suivre ce tutoriel, vous aurez besoin des éléments suivants :
Un moteur d’exécution de conteneurs : Pour cet article, nous partons du principe que Docker est installé et configuré sur votre poste de travail.
Une distribution Kubernetes : Vous devez installer une distribution Kubernetes pour créer le cluster Kubernetes et les autres ressources nécessaires, comme les déploiements et les services. Ce tutoriel utilise kind (v0.18.0), mais vous pouvez choisir une autre distribution Kubernetes, comme minikube ou K3s.
kubectl : Cette interface en ligne de commande permet de communiquer avec votre cluster Kubernetes et de lui envoyer des commandes. Ce tutoriel utilise la version 1.26.
mkcert : Cet outil permet d’obtenir un certificat TLS de confiance associé à un nom de domaine personnalisé pour votre machine de développement. Vous pouvez installer
mkcertsur votre machine de développement en suivant les instructions officielles.Git et Helm : Vous devez installer Git pour utiliser le projet de démonstration en local, ainsi que Helm, le gestionnaire de packages pour Kubernetes. Ce guide utilise Helm v3.11.2.
Dans les sections suivantes, vous allez mettre en œuvre TLS pour une application de paiement de démonstration déployée sur un cluster Kubernetes local. Vous allez d’abord déployer l’application sur votre cluster kind et vérifier qu’elle utilise HTTP plutôt que HTTPS. Vous générerez ensuite un certificat TLS autosigné et configurerez votre application de paiement pour l’utiliser. Enfin, vous créerez un certificat TLS de confiance à l’aide de mkcert et vérifierez que votre application Kubernetes est accessible via HTTPS.
Déployer l’application de paiement sur Kubernetes
Pour commencer à mettre en œuvre TLS dans votre application Kubernetes d’exemple, clonez l’application sur votre machine locale en exécutant la commande suivante :
Accédez ensuite au répertoire du projet à l’aide de cette commande :
Une fois dans le répertoire du projet, vous pouvez déployer l’application sur votre cluster Kubernetes.
Exécutez la commande suivante pour créer votre cluster kind :
Remarque : Le fichier config.yaml associe quelques ports des nœuds kind à votre machine locale. C’est nécessaire avec les installations de Docker Desktop, car les conteneurs kind s’exécutent en réalité dans une machine virtuelle (VM). Si vous utilisez un poste de travail Linux avec Docker installé directement (sans VM Docker Desktop), vous pouvez omettre l’option --config.
Ensuite, nous allons créer l’image du conteneur et la charger dans notre cluster kind.
Remarque : Vous pouvez également envoyer cette image vers un registre au lieu d’utiliser kind load. Dans ce cas, vous devrez aussi modifier le fichier deployment.yaml utilisé ci-dessous pour y indiquer les informations de votre registre et définir imagePullPolicy sur « Always » afin que l’image soit téléchargée.
Une fois le cluster créé, déployez l’application à l’aide des commandes suivantes :
Patientez quelques minutes, le temps que Kubernetes crée les pods et les autres ressources nécessaires. Vous pouvez vérifier l’état de vos ressources à l’aide de ces commandes :
Votre projet de démonstration expose l’application de paiement à l’aide d’un service nodePort sur le port 30080. Lorsque vous définissez un service Kubernetes sans spécifier le champ type, Kubernetes lui attribue le type de service par défaut : ClusterIP.
Cependant, l’adresse IP exposée par ClusterIP n’est accessible que depuis le réseau du cluster. Vous ne pouvez donc pas afficher l’application exécutée dans votre cluster à l’aide d’un client externe, comme votre navigateur Web. En production, vous pouvez utiliser un service LoadBalancer afin que votre fournisseur cloud fournisse un équilibreur de charge externe avec une adresse IP accessible publiquement.
Utilisez ces commandes pour afficher les services de cette application de démonstration :
Selon votre environnement d’exécution, vous pouvez accéder à l’application de démonstration de l’une des deux façons suivantes :
Avec une VM (par exemple, Docker Desktop) :
Pour accéder à l’application de démonstration depuis votre navigateur, utilisez le mappage de ports kind défini dans le fichier config.yaml et saisissez simplement localhost:30080.
Sans VM (par exemple, Linux sans Docker Desktop) :
Pour accéder à l’application de démonstration depuis votre navigateur, vous devez trouver l’adresse IP exposée par le nodePort à l’aide de la commande suivante :
Cette commande devrait afficher l’INTERNAL-IP du plan de contrôle Kubernetes (c.-à-d. 172.18.0.2). Vous pouvez alors accéder à l’application de paiement comme suit :
Veillez à remplacer l’adresse IP par l’INTERNAL-IP réelle du plan de contrôle Kubernetes ou par localhost, conformément aux instructions ci-dessus.
En ouvrant votre navigateur à l’adresse IP et au port indiqués ci-dessus, vous accédez à la page de paiement, où vous pouvez saisir les informations de votre carte. Comme il s’agit d’une application simulée, aucun traitement réel n’est effectué et les données ne sont enregistrées nulle part :

Selon votre navigateur, un indicateur Non sécurisé devrait apparaître près de la barre d’adresse, signalant que cette application est servie via HTTP et non HTTPS. Vous pouvez le vérifier en cliquant sur l’avertissement :

Mettre en œuvre un certificat TLS autosigné pour votre application
Vous allez maintenant mettre en œuvre TLS pour l’application Kubernetes d’exemple. Créez un certificat autosigné et une clé privée :
Créez ensuite un Secret Kubernetes contenant le certificat et la clé privée :
Vous devez maintenant installer le contrôleur Nginx Ingress afin qu’il redirige les requêtes entrantes vers votre application de paiement en HTTPS. Comme l’application est exposée via nodePort, vous devez installer Ingress à l’aide d’un fichier de valeurs personnalisé qui définit le type de service sur NodePort.
Créez un fichier nommé ingress-values.yaml avec le contenu suivant :
Installez ensuite le contrôleur Nginx Ingress à l’aide de Helm et du fichier de valeurs personnalisé :
Créez un fichier ingress.yaml avec le contenu suivant :
Appliquez ensuite ce fichier manifeste à l’aide de la commande suivante :
Ajoutez l’entrée suivante à votre fichier /etc/hosts :
Veillez à remplacer <control_plane_IP> par 127.0.0.1 si vous utilisez Docker Desktop, ou par l’adresse IP obtenue avec la commande kubectl get nodes -o wide dans le cas contraire.
Vous pouvez maintenant accéder à l’application de paiement via HTTPS en saisissant https://my-demo-app.local:32443 dans votre navigateur. Lors de votre première visite, votre navigateur devrait afficher un avertissement et vous permettre d’accepter le risque pour continuer. Vous pourrez ensuite accéder au site en HTTPS :

Cette erreur s’affiche dans votre navigateur parce que le certificat TLS est autosigné. La partie HTTPS de l’URL est d’ailleurs barrée.
Mettre en œuvre un certificat TLS de confiance pour votre application
Pour remédier à cela, vous pouvez utiliser mkcert afin de créer un certificat de confiance pour votre environnement de développement. Pour ce faire, créez une autorité de certification locale et générez un certificat de confiance pour votre domaine local :
Supprimez le Secret précédent et créez-en un nouveau pour mkcert :
Enfin, redéployez la ressource Ingress en exécutant la commande suivante :
Vérifier TLS pour votre application Kubernetes
À ce stade, vous devriez pouvoir accéder à votre application de paiement avec un certificat TLS de confiance. Redémarrez votre navigateur, puis accédez à https://my-demo-app.local:32443 pour que le nouveau certificat soit pris en compte. Cette fois, aucun avertissement ne devrait s’afficher et la partie HTTPS de l’URL ne devrait pas être barrée, comme sur les sites Web habituels sécurisés par TLS :

Cliquez sur l’icône de cadenas dans la barre d’adresse pour vérifier que votre navigateur considère le certificat TLS comme fiable et que la connexion est sécurisée :

Vous trouverez les exemples de code mis à jour sur la branche solution de notre dépôt GitHub du projet.
Conclusion
Lorsque vous traitez des données sensibles, TLS vous apporte la sécurité dont vous avez besoin. Toutefois, sa mise en œuvre peut s’avérer difficile si vous ne savez pas comment procéder.
Dans ce tutoriel, vous avez appris à mettre en œuvre TLS pour une application déployée sur un cluster Kubernetes local. Vous pouvez également appliquer ces principes aux applications hébergées sur site ou chez un fournisseur cloud.
Pour déployer TLS sur un système en production, pensez à utiliser un certificat public délivré par une autorité de certification (AC) de confiance, comme Let's Encrypt. Vous devez avoir accès au domaine de votre site, mais vous pouvez mettre en place des configurations supplémentaires, par exemple utiliser un service d’équilibrage de charge pour exposer votre application ou gérer plusieurs certificats avec un gestionnaire de certificats comme cert-manager. Exposer votre application via un équilibreur de charge améliore sa disponibilité, sa scalabilité et sa résilience. Et un gestionnaire de certificats facilite considérablement le provisionnement et la gestion de vos certificats de cluster à l’avenir.
Sécurisez votre infrastructure dès la source
Snyk automatise la sécurité et la conformité de l’IaC dans vos workflows, et détecte les ressources dont la configuration a dérivé ou qui sont manquantes.



