Etape 0 : contexte et objectifs
Le Wavegame est un challenge inter-école créé en 2019 qui vise à promouvoir l’expertise cybersécurité et le métier du conseil. La compétition comporte deux volets, le premier étant réservé aux étudiants en commerce et le second aux étudiants en informatique. La partie technique consiste en 2 exercices de qualification et un événement final. Cet article aborde le deuxième exercice où, dans sa saison 2023, 33 équipes se sont affrontées autour de la sécurisation d’une infrastructure Cloud AWS.
Sur fond d’une intrigue futuriste, les étudiants devenus consultants ont été mandatés par France Fusion, une entreprise chargée d’exploiter les premières usines à fusion nucléaire du pays. France Fusion souhaitait mettre au point une plateforme de supervision dans le Cloud. Pour ce faire, les données d’équipements industriels collectées, relevant de la propriété intellectuelle de France Fusion, devaient être analysées au travers d’une base de données ElasticSearch.
Démarré sous la forme d’un Proof of Concept (PoC) en marge des équipes sécurité, une équipe de développeurs est parvenue à déployer une architecture fonctionnelle sur AWS. Les étudiants sont alors amenés à sécuriser l’infrastructure en respectant les politiques Cloud public de France Fusion. Le défi technique était de taille : déployer une infrastructure vulnérable en libre-service sur 33 comptes AWS. Il s’agissait également d’accorder aux étudiants un accès administrateur et les autorisations nécessaires pour effectuer des modifications directement depuis la console AWS, le tout avec un budget limité compte tenu du nombre de participants.
Dans cet article, nous allons vous partager la recette qui a permis de faire de ce défi une réalité.
Etape 1 : Mettre sur le papier une architecture portant une dimension pédagogique
Avant de nous lancer dans le développement du coding game, nous avons pris en compte 4 contraintes :
- La population cible : s’agissant d’étudiants, il est primordial de tenir compte de l’hétérogénéité en matière de connaissances Cloud. Par conséquent, nous nous sommes concentrés sur l’utilisation des services essentiels AWS (e.g., S3, EC2, Lambda), car ce sont des ressources bien documentées et parce que les étudiants sont susceptibles de les avoir abordés en classe ou dans le cadre de projets personnels.
- Le thème : c’est un élément crucial pour immerger les étudiants dans un contexte de mission client. Nous avons donc cherché à créer une architecture aussi réaliste que possible. Ainsi, le choix de déployer une suite ELK (Elasticsearch, Logstash, Kibana) sur une instance EC2 nous a paru pertinent pour un PoC lié à de la supervision.
- Les coûts : sachant que l’infrastructure doit être accessible par des étudiants pendant 2 semaines et qu’elle doit être répliquée sur 33 comptes AWS, nous avions tout intérêt à optimiser les coûts. Pour y parvenir, nous avons utilisé le calculateur de tarification AWS pour estimer les coûts, opté pour une région à faible coût et construit l’infrastructure autour de services « paiement à l’utilisation » tels que les fonctions Lambda.
- Les échéances : pour faire face à un calendrier rapproché, nous avons défini des objectifs et des jalons avec une marge suffisante pour surmonter les éventuelles contraintes techniques. Les principales étapes du projet sont le développement, les tests, la création de comptes et le déploiement.
Le schéma d’architecture « vulnérable » ci-dessous reflète ces 4 contraintes (Figure 1). L’équipement industriel est simulé par une fonction Lambda (Datalake) qui va générer des logs et les envoyer dans un bucket S3 (Datalake). Une seconde fonction Lambda (ELK) est alors déclenchée par une notification S3. Elle va récupérer le fichier de logs et l’envoyer dans la base ElasticSearch (image Docker dans une instance EC2). Enfin, l’interface Kibana est accessible depuis Internet pour l’analyse des logs.
Figure 1 : schéma d’architecture initiale du Wavegame 2023
Etape 2 : Concevoir une architecture sécurisée basée sur des politiques sécurité du Cloud public
Maintenant que nous avons notre scénario initial, il s’agit de concevoir des politiques du Cloud public qui vont fixer les exigences sécurité et les critères d’évaluation. Pour cela, nous avons adapté des bonnes pratiques de sécurité mises en œuvre chez nos clients dont voici un extrait :
- AWS-01 : Toutes les ressources AWS doivent utiliser des rôles IAM spécifiques à leurs besoins et respectant le principe du moindre privilège.
- AWS-02 : Toutes les ressources AWS doivent être connectées et/ou attachées à un réseau privé (VPC).
- AWS-03 : Les instances EC2 ne doivent pas être accessibles au public via Internet.
- AWS-04 : Tous les logs d’infrastructure générés par les services AWS doivent être envoyés à CloudWatch.
- AWS-05 : Le volume Amazon EBS racine doit être chiffré sur toutes les instances EC2.
- AWS-06 : les données dans le bucket S3 doivent être chiffrées.
À partir des politiques du Cloud public, nous avons élaboré l’architecture sécurisée suivante (Figure 2) :
Figure 2: schéma d’architecture cible du Wavegame 2023
En résumé, l’ensemble des ressources Calcul sont positionnées dans un sous-réseau privé, le bucket S3 est accédé via un point de terminaison VPC, la plateforme de supervision ELK est accédée via une machine virtuelle de rebond. Les services Cloudwatch et CloudTrail sont activés pour le monitoring et la supervision. Des security groups sont attachés aux ressources pour n’autoriser que les communications entrantes strictement nécessaires.
Etape 3 : passer du design au développement en Terraform
Pour construire le coding game, nous avons créé et maintenu 2 architectures distinctes, représentées par 2 branches distinctes dans Github. La première étant l’architecture vulnérable qui sera déployée initialement, et la seconde étant la solution qui sert de garantie de faisabilité. Cette « garantie de faisabilité » signifie que 3 points obligatoires sont remplis :
- Les permissions IAM doivent être suffisantes pour permettre au système de fonctionner correctement.
- La configuration finale de l’infrastructure doit prendre en compte les cycles de vie des objets et leurs interactions.
- L’expertise requise pour compléter le coding game doit être adaptée à la montée en compétence des étudiants sur une période de 2 semaines.
Concernant le cycle de développement, plutôt que de suivre une approche linéaire, où l’on créerait d’abord le code pour l’infrastructure initiale, puis pour l’infrastructure cible, nous avons opté pour une approche agile avec la définition de blocs fonctionnels. Pour illustrer cette idée, le bloc « Lambda (ELK) -> S3 » vise à concevoir une fonction Lambda déclenchée dès qu’une notification S3 PutObject est générée, avec ou sans point de terminaison VPC. Bien que nous devions maintenir 2 configurations Terraform simultanément, cette approche nous a donné une plus grande agilité pour réévaluer nos choix techniques. Pour réduire davantage la redondance et assurer la maintenabilité, nous nous sommes aussi concentrés sur le développement de modules Terraform pour les objets Lambda et S3.
Pour automatiser le déploiement des ressources dans notre Sandbox et dans nos comptes étudiants, nous avons créé une chaîne CI/CD simplifiée dans Github. Elle est constituée de 2 Github Actions. A travers une syntaxe YAML, les Github Actions permettent d’exécuter des tâches intégrées à AWS ou Hashicorp. Dans notre cas de figure, nous avions une tâche pour exécuter la commande terraform apply et une tâche pour appliquer la commande inverse terraform destroy.
L’un des avantages des Github Actions est le fait de pouvoir stocker les identifiants d’accès à AWS dans Github Secrets au lieu du code source ou d’un fichier local. De plus, le stockage des états Terraform dans un bucket S3 facilite la collaboration. Un état Terraform est un fichier qui garde une trace de la configuration actuelle. Ainsi, chaque développeur configure sa clé S3 dans sa branche Github qui deviendra la référence de son état.
Au fur et à mesure que le développement avançait, nous nous sommes rendu compte de l’ampleur de l’écart entre l’architecture initiale et l’architecture cible. La raison principale est que les logiques IAM et réseau sont très différentes. En conséquence, il est devenu essentiel d’effectuer des tests en conditions réelles, c’est-à-dire à partir de la console AWS, afin d’identifier les ruptures, les politiques bloquantes et d’évaluer la complexité. A titre d’exemple, l’un des tests nous a rappelé que le script de démarrage d’un EC2 appelé user-data n’est pas persistant après un redémarrage. Par conséquent, ce comportement a empêché la mise en œuvre de la politique de sécurité relative au chiffrement du volume racine Amazon EBS (AWS-05).
Etape 4 : Déployer les environnements de manière sécurisée
Dans le cadre de ce défi, nous étions sur le point d’accorder un accès privilégié à des étudiants dans un environnement pendant deux semaines pour lequel une surveillance ou une assistance individuelle constante est impossible. Bien que cette approche représente une meilleure opportunité d’apprentissage, elle soulève des scénarios de sécurité spécifiques que nous devons anticiper et atténuer. Parmi ceux-ci, le dépassement de budget était une préoccupation majeure, étant donné l’accès illimité et les ressources à leur disposition. Une autre menace importante est la possibilité pour les étudiants de s’élever au sein de l’organisation, d’obtenir des accès non prévus ou de se compromettre les uns avec les autres. Enfin, le risque de détournement des ressources à des fins non autorisées ou malveillantes n’est pas négligeable. Chacune de ces menaces doit faire l’objet d’un examen attentif afin de garantir un déploiement sûr et responsable.
Pour ce coding game, nous avons opté pour une conception AWS multicomptes afin d’isoler les environnements de chaque équipe. Grâce à l’organisation AWS, nous avons simplifié l’administration, amélioré le contrôle des coûts et pu mettre en place des garde-fous à l’aide de politiques de contrôle de la sécurité (SCP). Dans la Figure 3, nous présentons notre organisation AWS, composée d’un compte admin et d’une Unité d’Organisation (UO) Wavegame qui héberge les comptes des équipes où l’infrastructure est déployée. Nous avons mis en place 3 SCP spécifiques pour :
- Restreindre l’accès aux services AWS en dehors de la région désignée, us-east-1, en définissant une liste d’opérations autorisées.
- Renforcer l’utilisation des types d’instance Amazon EC2 à du t2.micro ou t2.large (contrainte liée à l’environnement ElasticSearch).
- Interdire aux comptes étudiants de supprimer ou de modifier une ressource dont la balise est « protected« .
Par ailleurs, pour mieux gérer les coûts, en particulier pour une durée de deux semaines, nous avons mis en place une fonction Lambda pour fermer automatiquement les instances EC2 après 2 heures d’activité. Pour éviter toute modification non autorisée par les étudiants, cette fonction Lambda était l’une des ressources sécurisées avec la balise « protected« .
Figure 3: Organisation AWS pour le Wavegame 2023
Enfin, en plus de notre utilisateur IAM qui est administrateur de l’UO Wavegame via un rôle IAM, nous avons créé un utilisateur IAM avec le rôle AdministratorAccess pour chaque compte AWS, afin de donner de l’autonomie aux étudiants pendant le challenge. Ils ont notamment suffisamment de droits pour se créer des comptes nominatifs.
Etape 5 : Se préparer au RUN et à la correction
Une fois le coup d’envoi donné, les étudiants ont 2 semaines pour sécuriser les ressources dans leur compte AWS en suivant nos politiques sécurité du Cloud public. Avec autant de permissions, des erreurs de configuration cassantes peuvent vite survenir. Par exemple, un groupe a créé une politique S3 « Deny All« , ce qui l’a conduit à s’exclure lui-même, ainsi que toute autre personne, puisqu’aucun d’entre nous n’a les privilèges du compte racine.
Pour faire face à ce genre de situation, nous avons mis en place le système de communication suivant : chaque équipe dispose d’un coach chargé de signaler les problèmes techniques à l’équipe organisatrice qui nous remonte ensuite les incidents. Nous avons ainsi pu enquêter et résoudre les problèmes ou communiquer rapidement avec eux sans recevoir trop de messages pour des questions simples auxquelles les coachs pouvaient répondre.
Outre la gestion des incidents, notre rôle consistait également à surveiller les dépassements de budget. Pour ce faire, nous avons mis en place des alertes de coûts pour chaque compte AWS. Nous avons également développé un script pour suivre l’évolution du budget des équipes en temps réel. Cet outil s’est avéré très utile pour fournir une estimation du temps passé par les étudiants sur le défi et réagir en cas de dépenses anormales. Par exemple, deux jours après le début du défi, une alerte a été déclenchée en raison d’une défaillance de la fonction Lambda destinée à éteindre la machine virtuelle.
Une fois que le défi s’est terminé avec peu d’incidents et que l’accès des étudiants a été révoqué, il était temps de procéder à l’évaluation pour déclarer les gagnants. Pour rappel, les étudiants devaient configurer leur compte AWS en conformité avec les politiques du Cloud public. Pour leur évaluation, nous avons utilisé deux mécanismes de notation :
- Une évaluation automatique grâce au déploiement de règles gérées AWS Config à la fin du défi. Amazon fournit un ensemble de règles couvrant un pourcentage significatif des exigences. Par exemple, une règle permet de vérifier si le bucket S3 est chiffré (AWS-06).
- Une évaluation manuelle basée sur des critères attendus et des étapes de vérification clairement documentées.
Pour conclure, organiser un coding game est un challenge ambitieux qui nécessite des compétences Cloud public et Terraform, une organisation solide et des capacités de réaction face à des événements inattendus. Malgré les défis, c’est une opportunité exceptionnelle d’apprentissage. Pour les participants, le Wavegame offre une introduction immersive à la sécurité dans le Cloud public. Pour les organisateurs, le Wavegame est une expérience pratique sur le design, la conception et le maintien en condition opérationnelle d’une infrastructure dans le Cloud public.