Itinéraire de consultant : découvrez les coulisses d’un projet AWS
Quel est le quotidien de nos consultants en mission ? Quels sont les challenges techniques qu’ils doivent relever et quelles solutions sont apportées ? Derrière une mise en production réussie, un déploiement ou un Proof of Concept, il y a des consultants, une équipe, des technologies et beaucoup d’expertise et d’intelligence collective ! Cette série d’articles vise à vous dévoiler l’envers du décor, à travers le témoignage de nos consultants.
Passionné de sciences en général et particulièrement de physique et d’astronomie, Jérémie baigne dans l’informatique depuis l’âge de 12 ans. Après plusieurs années dans l’administration système et le scripting en Powershell, Jérémie a rejoint D2SI pour monter en compétence sur le Cloud AWS. Aujourd’hui titulaire de 5 certifications AWS, Jérémie a travaillé sur des projets d’automatisation des workloads Microsoft.
Jérémie partage son retour d’expérience sur un projet full AWS, sur lequel il a travaillé sur des problématiques de sécurité en s’appuyant sur AWS KMS, CloudHSM et Lambda : chiffrement et compliance des Security Groups.
Peux-tu présenter le projet sur lequel tu travailles ?
J’interviens dans le contexte de la construction d’une plateforme Cloud AWS, qui portera tous les projets d’entreprise à venir et la migration de plusieurs centaines d’applications (lift&shift, replatforming, création d’applications cloud native). Etant donné le secteur de l’entreprise, les contraintes de sécurité sont très fortes, notamment sur la question de la souveraineté des données. Afin de minimiser le risque de fuites des données dans le cadre d’un “gag order”, le choix a été fait de chiffrer toutes les données stockées sur le Cloud, et d’utiliser AWS Key Management Service (KMS), service de gestion des clés de chiffrement, intégré avec AWS Identity and Access Management (IAM).
Quel type de données sont chiffrées ?
Des volumes d’instances, des instances RDS, des données sur S3, DynamoDB, etc. Comme KMS est un service managé, et pour répondre aux enjeux de souveraineté des données, il nous a été demandé de coupler KMS avec CloudHSM, un module de sécurité matérielle (Hardware Security Module). Ce boitier physique de sécurité permet de gérer des clés de chiffrement. Après la configuration des utilisateurs autorisés et des mots de passe, les clés sont générées et le système est réputé inviolable : l’accès physique au boîtier ne donne pas accès aux clés qu’il contient, et AWS ne peut pas non plus y accéder. C’est un système similaire au Trusted Platform Module (TPM) présent sur les ordinateurs portables depuis quelques années.
Comment fonctionnent KMS et Cloud HSM ?
Pour que les clés de chiffrement soient en sécurité, elle sont générées dans CloudHSM et on a besoin qu’elles soient sorties et copiées dans KMS pour chiffrer une instance : on copie la clé, on démarre l’instance, on enlève la clé. Comme CloudHSM garde toujours la clef, on a la possibilité en cas de soupçon de fuite des données de supprimer la clé côté KMS à tout moment. Les clés de chiffrement peuvent donc être rendues inaccessibles en urgence en cas de soupçon de fuite de données. Dans ce cas, il est impossible de déchiffrer les données, le temps d’éclaircir la situation.
Quelle était ton expérience sur le sujet avant de travailler sur le projet ?
J’ai toujours été très intéressé par le chiffrement, c’est un sujet que je connais très bien à titre personnel, mais il a été plus compliqué de comprendre le fonctionnement du service CloudHSM. C’est un service de très bas niveau, les API de communication fournies sont minimalistes, mal documentées, et le challenge de ce projet a été l’interfaçage avec CloudHSM.
Tu as donc développé une API pour communiquer entre KMS et Cloud HSM ?
Le développement de cette API s’est fait en Java. A ce moment, la librairie Java n’était presque pas documentée, et donc j’ai un peu tâtonné au début. L’API Java sert à faire l’import de la clé, en quelque sorte elle sert de passe-plat entre CloudHSM et KMS.
Sur quoi as-tu travaillé ensuite ?
Il y a ensuite eu un gros chantier sur les Security Groups, c’est-à-dire les firewalls virtuels devant chaque machine et chaque élément d’un VPC (lambas, load balancer, autres…). Les Security Groups listent les ports accessibles et les sources de connexion autorisées. La première option était de complètement couper l’accès dans la console AWS et de faire passer les utilisateurs par la plateforme, mais cela aurait supposé un développement très lourd pour arriver à un résultat très en dessous de ce que propose AWS. Nous avons donc opté pour une solution en deux parties selon que l’accès soit interne ou externe. Les utilisateurs peuvent créer des Security Groups au sein de leur application, entre leurs machines et/ou leurs services, tant que ça reste en interne de leur VPC. En revanche pour autoriser des accès depuis l’extérieur, toute connexion devant être tracée et validée, il devront passer par la plateforme.
Quelles sont les implications de ce choix ?
Cela impliquait de développer une compliance : politique de nommage, interdiction de certaines règles (ouvertures internes uniquement). La complexité est venue de la gestion des cas d’exception. Par exemple, comment s’assurer qu’un Security Group ouvert à l’extérieur ne puisse être déplacé sur une autre machine ou load balancer ? Il n’est pas possible d’interdire au niveau IAM à un utilisateur d’associer ou désassocier un Security Group en particulier. La maîtrise des associations des Security Group ne peut donc pas se faire avec IAM.
Quelle solution a été choisie ?
J’ai développé une Lambda chargée de vérifier les affections des Security Group, de vérifier qu’il n’y a pas eu d’associations ou désassociations non autorisées. Un Security Group dont l’association doit rester fixe a un tag qui liste les élément auxquels il doit être attaché. La Lambda checke ce tag sur tous les Security Groups et vérifie les Security Groups de chaque network interface (puisque les Security Groups sont associés aux network interfaces). Le service s’assure donc que chaque network interface ait les bons Security Groups.
Comment fonctionne cette Lambda ?
Quand les security groups d’une network interface sont modifiés, il y a un événement appelé “ModifyNetworkInterfaceAttribute”, mais on ne sait pas s’il y a eu retrait ou ajout de security group : on ne voit que la nouvelle liste de security group. Pour faire notre vérification, il faut donc parcourir tous les Security Groups et toutes les interfaces, et c’est ce que fait la Lambda pour vérifier la conformité des Security Groups. Le problème est que certains services créent une network interface managée, qui ne peut pas être modifiée directement. C’est par exemple le cas avec RDS et tous les services managés (Lambda, loadbalancing, VpcEndpoint…). Il faut donc faire les modifications sur le service RDS, qui à son tour les répercute sur ses network interfaces. Au total, la Lambda (développée en Python) fait 1000 lignes, dont environ 800 sont entièrement consacrées à la gestion des associations des Security Groups. La Lambda s’exécute sur des événements en particulier, et toutes les heures elle parcourt tout le compte et vérifie tout.
Quels sont les cas particuliers traités par la Lambda ?
Par exemple un utilisateur lance une instance RDS, et associe un Security Group non autorisé via le launch wizard. Pour supprimer le Security Group la Lambda doit le désassocier, et pour cela il faut que l’instance RDS soit en mode disponible. Or RDS met du temps à démarrer, il faut environ 10mn avant que l’instance soit disponible, et la Lambda ne peut pas faire la modification immédiatement. Dans ce cas la Lambda essaie de faire une modification alors que ce n’est pas encore possible et échoue. C’est une des raisons pour lesquelles un check complet est effectué toutes les heures.
Comment as-tu découvert ces cas particuliers ?
On ne peut s’en rendre compte que par l’expérience, les tutoriels n’abordent pas ce genre de cas. C’est en faisant des tests que je m’en suis aperçu; quand je scripte j’ai rapidement envie de savoir si ça fonctionne, et c’est ainsi que je me suis aperçu que je ne pouvais pas modifier certaines networks interface (celles qui sont managées). Mais c’est aussi ce qui me plaît, arriver sur une problématique, ébaucher une solution, itérer en fonction des imprévus… Avoir une bonne connaissance générale du Cloud AWS permet de savoir où chercher quand il y a des erreurs.
Comment est gérée la compliance des Security Groups pour les accès externes ?
Afin que les utilisateurs puissent créer des Security Groups autorisant un accès depuis d’autres applications ou Internet, nous avons choisi de les faire passer par la plateforme développée en interne. Cette plateforme est le point d’entrée des clients internes sur AWS. Pour créer les comptes de façon conforme et automatisée, gérer la partie réseau (VPC) et l’interfacer avec le réseau du client nous utilisons un pipeline CI/CD basé sur Jenkins. Pour la compliance des Security Groups, chaque application déclare les ports dédiés au trafic externe, et par ailleurs nous connaissons tous les subnets de toutes les applications puisque nous les créons : on sait sur quel port l’application B reçoit du trafic, on connaît les subnets de l’appli A, donc on popule le security group avec les bonnes sources et le bon port pour l’application B.
Qu’as tu appris sur cette mission ?
J’ai appris beaucoup de choses, y compris sur KMS qui est un service que je connaissais via les certifications, mais que j’ai découvert en profondeur. Je ne connaissais pas CloudHSM, donc là aussi j’ai beaucoup appris. J’ai aussi progressé sur la partie Serverless et sur l’écriture de Lambdas. Je connaissais Python, mais pas dans le contexte serverless : comment gérer les applications via des événements de Cloudrail, comment traiter ce que la lambda reçoit, etc. Il y a un an quand je suis arrivé chez D2SI, je n’avais jamais fait d’AWS, donc j’ai beaucoup progressé sur ce sujet, et j’en suis très content.
Découvrez le parcours de Jérémie sur le Cloud AWS :