Skip to main content

Implémenter TLS dans Kubernetes

Écrit par
Headshot of Rubaiat Hossain

Rubaiat Hossain

feature kubernetes polp

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 mkcert sur 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 :

git clone https://github.com/snyk-snippets/tls-in-k8s.git

Accédez ensuite au répertoire du projet à l’aide de cette commande :

cd k8s-tls-demo

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 :

kind create cluster --config=config.yaml

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.

docker build -t demo-payment-app .
kind load docker-image demo-payment-app

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 :

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

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 :

kubectl get deployments
kubectl get pods

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 :

kubectl get services

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 :

kubectl get nodes -o wide

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 :

http://172.18.0.2:30080

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 :

Fenêtre de navigateur affichant un formulaire de page de paiement avec des champs pour le numéro de carte, la date d’expiration et le cryptogramme visuel, ainsi qu’un bouton « Payer ».

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 :

Le navigateur affiche un formulaire de paiement avec un avertissement indiquant que la connexion au site n’est pas sécurisée.

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 :

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=my-demo-app.local"

Créez ensuite un Secret Kubernetes contenant le certificat et la clé privée :

kubectl create secret tls my-demo-app-tls --key tls.key --cert tls.crt

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 :

controller:
  service:
    type: NodePort
    nodePorts:
      http: 32080
      https: 32443

Installez ensuite le contrôleur Nginx Ingress à l’aide de Helm et du fichier de valeurs personnalisé :

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx -f ingress-values.yaml

Créez un fichier ingress.yaml avec le contenu suivant :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-payment-app-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - my-demo-app.local
    secretName: my-demo-app-tls
  rules:
  - host: my-demo-app.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo-payment-app
            port:
              number: 80

Appliquez ensuite ce fichier manifeste à l’aide de la commande suivante :

kubectl apply -f ingress.yaml

Ajoutez l’entrée suivante à votre fichier /etc/hosts :

<control_plane_IP> my-demo-app.local

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 :

Navigateur affichant un formulaire de paiement avec des champs pour le numéro de carte, la date d’expiration et le CVV ; la barre d’adresse indique un avertissement HTTPS « Non sécurisé ».

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 :

mkcert -install
mkcert my-demo-app.local

Supprimez le Secret précédent et créez-en un nouveau pour mkcert :

kubectl delete secret my-demo-app-tls
kubectl create secret tls my-demo-app-tls --key 
my-demo-app.local-key.pem --cert my-demo-app.local.pem

Enfin, redéployez la ressource Ingress en exécutant la commande suivante :

kubectl delete ingress demo-payment-app-ingress
kubectl apply -f ingress.yaml

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 :

Fenêtre de navigateur affichant une page de paiement avec des champs pour le numéro de carte, la date d’expiration et le cryptogramme visuel, ainsi qu’un bouton « Payer ».

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 :

Navigateur affichant un formulaire de paiement avec des champs pour le numéro de carte, la date d’expiration et le CVV, ainsi qu’un panneau de sécurité confirmant 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.

Lire la suite

feature customer snowflake
Article

Sécuriser dès la conception : découvrez l’intégration de Snyk Studio à Snowflake Cortex Code

Snyk Studio s’intègre à Snowflake Cortex Code pour analyser le code généré par l’IA, les dépendances et les conteneurs à la recherche de vulnérabilités, dès le développement.

feature insights announcement
Blog

Compromission de la chaîne d’approvisionnement Node-gyp : un ver npm à propagation autonome dissimulé dans binding.gyp

Un nouveau ver npm détourne binding.gyp pour déclencher node-gyp lors de l’installation et permettre à des packages malveillants d’exécuter du code sans scripts de cycle de vie. Il vole des identifiants, s’installe durablement sur GitHub et se propage de mainteneur en mainteneur.

Article

Attaque de la chaîne d’approvisionnement Miasma : du code malveillant découvert dans les packages npm @redhat-cloud-services

Un ver de la chaîne d’approvisionnement baptisé Miasma a été découvert dans des dizaines de versions npm de @redhat-cloud-services. Le hook malveillant preinstall vole des identifiants, explore les identités cloud et peut republier d’autres packages.