K3S/Wordpress - A (long) way to DevSecOps - Épisode 4
Rappel de la saga : A long way to DevSecOps : Épisode 1, Épisode 2, Épisode 3, Épisode 4, Épisode 5, Épisode 6, Épisode 7, Épisode 8.
Comme je l’avais annoncé précédemment j’ai effectué une première migration de Blogger à WordPress. Le jour où j’écris ces lignes le blog WordPress est auto-hébergé et fonctionne dans un conteneur, mais pas dans un cluster Kubernetes.
La sécurité de départ
WordPress
Déjà, vous allez me dire qu’utiliser WordPress c’est un peu aimer le risque. On estime que WordPress c’est en 2019 environ 35% des sites Web. Ce qui est déjà conséquent, même trop. On imagine assez facilement le niveau d’exposition, et le nombre de sites qui ne sont pas à jour. Cela me rappelle un certain ver Santy.A qui touchait les forums phpBB. De plus c’est sans compter sur tous les modules additionnels que l’on peut ajouter dans ce CMS. Chaque module utilisé peut potentiellement porter des vulnérabilités et doivent être mis à jour au fur et à mesure des releases, parfois de manière indépendante et parfois de manière liée comme pour les thèmes.
Les conteneurs
Utiliser des conteneurs alors que leur sécurité est très fortement décriée, c’est aller au suicide ? Je pense qu’effectivement, il faudra bien vérifier la sécurité du socle avant de partager des ressources entre différents utilisateurs (aller un ptit lien vers la présentation SSTIC sur la sécurité K8S). Pour ma part, je reste le seul administrateur de ma plate-forme. Les utilisateurs utiliseront les services et passeront tous par l’Ingress de K3S.
Comme je l’avais dit dans l’épisode 1, une des problématiques qui apparait en premier est de savoir quelles sont les images collectées et quel est le contenu de ces images. Avant de les déployer sur l’infra il faut savoir si ces images suivent les bonnes pratiques de sécurité. On commence ici à mettre un pied dans le process de DevSecOps, et ce n’est pas le sujet pour le moment. On reviendra dans le pipeline de développement par la suite, comme je l’ai déjà dit : la route est longue.
Je ne vais pas faire un article complet sur la sécurité des conteneurs. Pour résumer très vite, les droits d’exécution peuvent parfois être plus élevés que nécessaire. C’est ce cheminement vers la sécurité qui a donné naissance à Podman, à Docker en rootless mode (encore abordé à la DockerCon cette année), ou encore à une approche encore plus extrême avec les Kata Containers. Bon l’avantage c’est qu’à l’intérieur du conteneur (qui doit être minimal), l’exposition est réduite. Mais doit être mis à jour à chaque fois qu’une vulnérabilité touche cette base.
Durcissement mail
Dans l’épisode précédent nous avons déployé un service mail. J’ai depuis « durci », en ouvrant sur l’extérieur que les ports nécessaires (super !). Cette mise à jour s’est effectuée de manière transparente en redéfinissant le déploiement et les ports exposés au niveau du conteneur (par défaut si ce n’est pas déclaré, les ports sont fermés). De plus c’est redéfini au niveau de la description du service, qui est exposé à l’intérieur du cluster (voir les services commentés dans le code dispo ici).
Nous avons vu rapidement un des premiers avantages du fichier Manifest YAML, et nous avons pu en quelques lignes faire des modifications n’ayant aucun impact fonctionnel sur le service rendu. Nous allons voir que c’est cette accélération qui est importante et qui va nous apporter un avantage considérable sur la vision du S.I. traditionnel (même si aucun principe au niveau sécurité n’est remis en cause).
Une projection de la sécurité
D’un certain point de vue, je pense que JCVD avait raison, sur la cristallisation d’un état futur, participant à la réussite de son projet. On aurait tout aussi bien pu entendre des mots comme « traçabilité des exigences », « BDD » (Behavior Driven Development), ou plus récemment « DSC » chez Microsoft (Desired State Configuration).
Disclaimer
Je tiens évidemment à refaire un disclaimer au beau milieu de ma réflexion. Car évidemment j’écris ces lignes sans avoir composé de plan particulier, sans savoir ou tout cela va me mener. La forme du discours est lui même contradictoire au fond et au message que j’aimerais faire passer. Mais j’aurais le temps de venir corriger certaines choses, et le plus important est de toujours tenter de s’améliorer. Donc, ce que je vais essayer d’expliquer n’est évidemment que mon point de vue et ce n’est certainement pas partagé par tout le monde. Tous conseils, « vérités » doivent être replacés dans le contexte de ce que l’on veut accomplir…
IaC
« Je code donc je suis« , pourrait dès à présent être remplacé par « Je code ce que j’ai envie d’être ». Dans ces belles déclarations philosophiques, ce qui est intéressant c’est de pouvoir agir à un seul endroit sur le fonctionnel, le service, et la sécurité. C’est aussi peut-être réconcilier au sein d’une même équipe le développeur, l’opérationnel et la sécurité (jusqu’à aujourd’hui c’était difficile).
Découpage en couches
L’avantage du cluster Kubernetes c’est sa faible adhérence au socle d’infra utilisé. Dans mon cas j’ai choisi de le faire fonctionner sur un « compute node » sur un fournisseur Cloud (j’en ferais certainement un billet). Le fournisseur Cloud se charge de maintenir à jour sa base de virtualisation, je dois me charger de maintenir à jour l’OS virtualisé ainsi que la base K3S. Les applicatifs (conteneurs) n’ont aussi que peu d’adhérence avec l’infra de conteneurisation. Tout peut être mis à jour indépendamment de chaque couche. K3S possède aussi une procédure pour se mettre à jour automatiquement, mais n’ayant pas de contrainte de disponibilité je ne l’utiliserais peut-être pas.
Jusqu’à aujourd’hui le principal frein à la mise à jour de l’applicatif, était les fortes dépendances et les impacts forts en production. Le coût estimé était parfois trop lourd vis à vis du risque pris d’arrêter et de redémarrer les services (ou même vis à vis du coût de revient de l’applicatif en production).
Déploiement de WordPress
Manifest YAML
Il suffit de s’inspirer du repo :
wordpress-k3s (ce lien s’ouvre dans une nouvelle fenêtre) par kyzdev (ce lien s’ouvre dans une nouvelle fenêtre)
A kubectl YAML to deploy WordPress on Kubernetes
Architecture n-tiers
Avec un fichier de déploiement tel que celui utilisé pour WordPress on peut voir que celui-ci utilise deux applications/conteneurs principa(les/aux) :
- WordPress (Application PHP fonctionnant sur Apache)
- Base de donnée MySQL
Avec K3S la sécurité reste minimale car la couche réseau utilisée est aussi minimaliste. Il est possible d’aller plus loin avec des implémentations comme Calico ou Cilium. Et de définir des règles réseau supplémentaires pour les déploiement des services. Je pense que cela pourra faire l’objet d’un article plus approfondi, notamment dans cette volonté de consolider toujours un peu plus notre cluster K3S. On peut voir aussi qu’avec les « Network Policies » ce sont des fichiers YAML qui seront intégrés au projet, et donc que les problématiques de sécurité adhèrent au projet. L’application de ces règles n’impactent pas le service (sauf si des règles viennent à couper des flux nécessaires). Je ne résiste pas à mettre un lien SSTIC intéressant aussi sur eBPF sur Kubernetes.
En première étape, ce qu’il est important de noter, c’est que depuis l’extérieur en passant par Traefik, il est impossible d’accéder directement à la base de données, que les services ne sont pas directement exposés. En deuxième étape, nous verrons plus tard…
La donnée
Toute la donnée importante de ce déploiement est située dans des volumes Kubernetes. L’utilisation d’applicatifs en conteneur répond facilement à une des questions importantes pour un DPO : Où sont situées mes données ? Et personnellement, pour le stockage, la sauvegarde, voir l’archivage des données c’est beaucoup simple : il suffit de sauvegarder tous les volumes persistants du cluster. En réalité, ça fait beaucoup moins de données que si on sauvegarde l’intégralité d’un cluster VMware avec Veeam, beaucoup moins de ressources utilisés et des problématiques de compression et de déduplication qui s’envolent. Il faut noter que des données de configuration sont stockées dans des objets ConfigMap, ou Secrets directement au sein du cluster, et qu’il ne faut pas les oublier…
Conclusion
Je crois que vous avez fini par comprendre où je voulais en venir. Mon but n’était pas technique, sur la toile on trouve suffisamment de ressources pour déployer telle ou telle application. J’avoue que parfois comme les technos vont assez vite, tout n’est pas tout à fait à jour. J’ai essayé de pointer du doigt certaines portes d’entrées, que l’on ose ou pas prendre. J’entends trop de questions ou d’affirmations sur les conteneurs ou Kubernetes qui me font sourire ou pleurer… « Kubernetes ce n’est pas pour nous », « Les conteneurs en production c’est mal », « Docker ce n’est pas secure », etc…
Je pense qu’il faut prendre un peu de recul, et surtout que l’accélération possible offerte par ces technologies est plutôt une opportunité (si vous partez sur les ressources que j’ai fourni, il faut moins de 15 minutes pour avoir des services qui tournent). Il faut se poser les bonnes questions avant de démarrer, mais les possibilités de test, de reproductibilité et d’infrastructure immutable sont de réels avantages pour un expert sécurité qui voudra apporter du hardening par petites touches.
Je pense continuer à apporter des petits compléments dans cette série d’épisodes, mais on peut dire que dès à présent la majorité du message est passé. Si vous avez des commentaires, des compléments, n’hésitez pas : ici ou sur Twitter, c’est permis !!!