Comment Slack a modernisé le suivi de sa flotte AWS EC2

Slack AWS EC2

Slack revient sur son passage à la v2 d’IMDS (service des métadonnées d’instance), opéré à renfort d’outils AWS… et de technos internes.

Qui n’a pas encore migré vers IMDSv2 ? Depuis un an, les initiatives s’accélèrent chez AWS pour favoriser la montée de version. Slack fait partie des entreprises à avoir finalisé la démarche. Son équipe Cloud Foundations en a récemment rendu compte.

IMDS (Instant Metadata Service) permet d’accéder à des informations de configuration statiques et dynamiques. Attaché localement à chaque instance, il est exposé via une adresse IP spécifique (169.254.169.254 ou fd00:ec2::254).

La version originale d’IMDS utilise une méthode requête/réponse, sans authentification ou vérification particulière. Elle laisse donc la porte ouverte, entre autres, à des attaques par l’intermédiaire d’applications vulnérables.
La v2, lancée en 2019, colmate la brèche en utilisant une méthode orientée session (récupération d’un token par requête PUT, puis utilisation de ce token dans les requêtes GET).

Si IMDSv1 reste prise en charge, AWS pousse la v2. Amazon Linux 2023, par exemple, l’utilise par défaut. Même chose depuis quelques semaines pour tous les lancements effectués sur la console avec des AMI Quick Start. En février 2024, une fonction API devrait permettre de contrôler l’usage de la v1 au niveau des comptes. Puis, à partir de mi-2024, les nouveaux types d’instances ne supporteront, par défaut, qu’IMDSv2.

Des outils made in AWS…

Pour migrer, Slack a exploité une partie des outils qu’AWS met à disposition. Il y a couplé des technologies internes.

L’entreprise dispose de comptes AWS par environnement (sandbox, dev, prod) et par équipe… ainsi que, parfois, par application. Tous sont membres d’une organisation racine. Lorsqu’elle en crée un, les informations sont écrites dans une table DynamoDB accessible par une API interne nommée Archipelago.

Avant de migrer, il a fallu déterminer combien d’instances utilisaient IMDSv1. Ici, on a exploité la méthode recommandée : la métrique CloudWatch MetadataNoToken. Une application interne (imds-cw-metric-collector) associe ces éléments aux identifiants d’instances, appelle les services de provisionnement pour collecter des informations telles que les ID de propriétaires et les rôles Chef (pour les instances configurées par ce biais), puis envoie le tout à un dashboard Prometheus. C’est sur cette base que les équipes travaillent à la migration vers IMDSv2.

Pour comprendre quels processus au sein des instances effectuaient les appels IMDSv1, Slack a recouru à ImdsPacketAnalyzer, un outil de journalisation open source made in AWS. Il l’a packagé en .deb et intégré à son dépôt APT, afin que ses équipes puissent l’installer à la demande (la plupart des instances utilisent Ubuntu ou Amazon Linux).
Pour les instances reposant sur une version ancienne d’Ubuntu (18.04 en l’occurrence), il a fallu passer par des outils tiers comme lsof et netlogs.

… et des développements internes

Conformément à ce que recommande AWS, Slack a d’abord mis à jour ses scripts bash, son CLI et ses kits SDK vers des versions compatibles IMDSv2.

L’entreprise s’est ensuite tournée vers son principal outil de provisionnement : Terraform. Pour faciliter les changements, ses équipes utilisent des modules partagés. Problème : pour la migration IMDS, on ne souhaitait pas appliquer les changements sur tous les comptes en même temps. Solution retenue : un filtrage par le biais d’un module imbriqué (accounts_using_imdsv1).

Pour empêcher le lancement d’instances avec IMDSv1, Slack a mis à jour ses SCP (politiques de contrôle des services). Là aussi, en filtrant avec son module Terraform.
Les SCP n’ont cependant pas fonctionné partout. Elles ne se sont, en particulier, pas appliquées au compte racine. Ni aux rôles liés à un service (les VM que lance le service d’autoscaling échappent par exemple aux SCP).
De même, Slack n’est pas parvenu à empêcher ses équipes de créer des modèles de lancement ne forçant pas l’usage d’IMDSv2.

Faute de pouvoir éviter à 100 % le lancement d’instances en v1, un système de notification utilisant EventBridge et Lambda a été mis en place. Une règle capture les requêtes à l’API EC2 ; l’autre capture les réponses. Les événements correspondant à IMDSv1 sont centralisés dans un bus et se voient associer une fonction Lambda. Celle-ci utilise l’ID de compte et l’API Archipelago pour envoyer une notification Slack à l’équipe concernée. Un modèle similaire est en place pour contrôler l’activation d’IMDSv1 sur des instances existantes.

Pour couper IMDSv1 sur les instances existantes, Slack a déployé un service spécifique sur EKS et y a associé un rôle à privilèges restreints (les authentifiants sont obtenus via un provider OIDC). Il utilise lui aussi Archipelago pour analyser les instances et forcer l’activation d’IMDSv2 si nécessaire.

Illustration principale © metamorworks – Adobe Stock