Aller au contenu
English
English
Cloud medium

Images, cloud-init et service de métadonnées

10 min de lecture

Une machine qu'on configure à la main après son démarrage est une machine qu'on ne saura pas recréer. Cette leçon montre comment préparer une instance au moment où elle démarre, avec une image système et un fichier de configuration lu par cloud-init, puis comment elle obtient des identifiants temporaires auprès du service de métadonnées. Elle montre aussi, mesures à l'appui, ce que cette configuration de démarrage laisse derrière elle sur le disque, parce que c'est le point où l'on se croit à tort protégé.

  • Préparer une machine au démarrage avec cloud-init, sans y toucher ensuite.
  • Distinguer ce qui appartient à l'image de ce qui appartient au démarrage.
  • Vérifier ce que cloud-init conserve sur le disque, et qui peut le lire.
  • Protéger le service de métadonnées, cible d'une classe d'attaques connue.

Une image est le disque de départ de votre machine. Trois façons de faire cohabitent, et le choix a des conséquences sur la sécurité comme sur le temps de démarrage.

ApprocheCommentCe qu'elle coûte
Image officielle plus configuration au démarragecloud-init installe et configuredémarrage plus long, dépendances externes
Image préparée par vousconstruite en amont, prête à l'emploiun travail de fabrication, et un cycle de mise à jour
Image officielle plus configuration manuellequelqu'un se connecte et installeà éviter : rien n'est reproductible

La troisième ligne mérite son avertissement. Une machine configurée à la main est une machine que personne ne saura recréer à l'identique, y compris celui qui l'a faite. Le jour où elle tombe, l'incident dure le temps de retrouver ce qui avait été installé, et cette durée ne se budgète pas.

cloud-init est le mécanisme standard, présent sur pratiquement toutes les images Linux officielles, quel que soit le fournisseur. Il lit une configuration que vous fournissez à la création et l'applique au premier démarrage.

#cloud-config
package_update: true
packages:
- nginx
users:
- name: appli
groups: [sudo]
shell: /bin/bash
ssh_authorized_keys:
- ssh-ed25519 AAAA... votre-cle
write_files:
- path: /etc/nginx/conf.d/app.conf
content: |
server { listen 8080; root /var/www/app; }
runcmd:
- systemctl enable --now nginx

Les cinq natures de données qu'une instance reçoit au démarrage

Section intitulée « Les cinq natures de données qu'une instance reçoit au démarrage »

Parler de « métadonnées » au singulier fait perdre la distinction qui compte pour la sécurité. Une instance reçoit cinq choses différentes, qui n'ont ni la même origine, ni la même durée de vie, ni les mêmes droits de lecture.

NatureQui l'écritCe que c'estDurée de vie
metadatale fournisseuridentifiant, zone, type, nom d'hôtetant que l'instance existe
user-datavousla configuration cloud-init que vous fournissezconservée sur le disque après le boot
vendor-datale fournisseurréglages qu'il impose ou propose par défautidem user-data
identifiants temporairesle fournisseurjeton d'accès lié au rôle de l'instancequelques heures, renouvelé
identité d'instancele fournisseurdocument signé prouvant « je suis cette instance »à la demande

La ligne à retenir est la deuxième. Les identifiants temporaires expirent, pas votre user-data : il reste lisible sur le disque, dans le même état qu'au moment de la création de la machine. C'est la seule des cinq natures que vous écrivez, et la seule qui ne se révoque pas.

Que garde cloud-init sur le disque après le premier démarrage ?

Section intitulée « Que garde cloud-init sur le disque après le premier démarrage ? »

cloud-init conserve votre user-data en clair sur le disque, définitivement, et tout ce qu'il conserve n'est pas protégé de la même façon. Mesuré le 20 septembre 2026 sur deux machines virtuelles fraîchement démarrées, AlmaLinux 10.2 avec cloud-init 24.4 et Debian 13 avec cloud-init 25.1.4, toutes deux sur la source de données NoCloud :

FichierDroitsLisible sans privilège
/var/lib/cloud/instance/user-data.txt-rw------- root:rootnon
/run/cloud-init/instance-data-sensitive.json-rw------- root:rootnon
/run/cloud-init/instance-data.json-rw-r--r-- root:rootoui
/var/lib/cloud/seed/nocloud-net/user-data-rw-r--r-- root:rootoui

Les deux premières lignes montrent que cloud-init fait son travail : le user-data recopié dans /var/lib/cloud/instance/ est en 0600, et la variante sensible de l'inventaire aussi. La commande cloud-init query applique la même règle et refuse de servir un compte ordinaire :

/var/lib/cloud/instance/user-data.txt
# Sans privilège, cloud-init caviarde volontairement sa réponse
cloud-init query userdata

La quatrième ligne annule cette protection. Avec la source de données NoCloud, celle que vous obtenez avec libvirt, Incus, Proxmox ou une clé USB, le fichier d'amorçage reste sur le disque en 0644 : n'importe quel compte local relit l'intégralité du user-data, y compris ce que cloud-init s'est donné la peine de protéger deux répertoires plus loin. Sur un cloud public qui sert ses données par le service de métadonnées, il n'y a pas de seed sur le disque et cette ligne disparaît, mais les trois autres restent vraies.

Le service de métadonnées : ce que votre machine sait d'elle-même

Section intitulée « Le service de métadonnées : ce que votre machine sait d'elle-même »

Chaque machine du cloud peut interroger une adresse locale spéciale qui lui répond sur sa propre configuration, et, surtout, lui remet des identifiants temporaires. C'est le mécanisme qui rend possible l'identité attachée à la ressource décrite dans le principe API-first : l'application n'embarque aucun mot de passe, elle demande un jeton au moment de s'en servir.

Cette adresse est locale au serveur physique : elle n'est pas routée depuis l'extérieur, elle ne répond qu'aux processus de la machine elle-même, et la réponse lui est propre. C'est justement ce qui en fait une cible : tout ce qui parvient à émettre une requête depuis la machine parle au service de métadonnées avec les droits de la machine.

Comment protéger le service de métadonnées d'un détournement SSRF ?

Section intitulée « Comment protéger le service de métadonnées d'un détournement SSRF ? »

La menace principale est la falsification de requête côté serveur, ou SSRF. Une application qui accepte une URL fournie par l'utilisateur et va la chercher peut être détournée pour interroger l'adresse de métadonnées et renvoyer le jeton dans sa réponse. Des compromissions majeures ont eu exactement cette cause, et aucune n'a demandé d'accès préalable à la machine.

Quatre protections, à appliquer ensemble plutôt qu'à choisir :

ProtectionCe qu'elle casseOù elle se règle
Version durcie du protocolela requête simple qui suffisait à lire le jeton : il faut d'abord obtenir un jeton de session par une requête préalableà la création de l'instance, puis rendue obligatoire par politique
Limite de sauts réseaula réponse qui ressortait du serveur vers un conteneur ou un proxymême réglage, côté fournisseur
Rôle le plus étroit possiblel'ampleur des dégâts : un rôle qui ne lit qu'un seul seau limite la fuite à ce seaudans la politique d'accès attachée à l'instance
Blocage depuis les conteneursl'accès des charges non fiables, qui n'ont aucune raison d'interroger l'adressedans l'orchestrateur, la plupart offrent le réglage

Le contrôle est immédiat, et il se fait depuis la machine : une requête vers l'adresse de métadonnées sans jeton de session préalable doit être refusée si la version durcie est bien imposée. Si elle répond, le réglage n'est pas appliqué, quelle que soit la case cochée dans la console.

  • L'image porte ce qui est stable, le démarrage porte ce qui est propre à la machine. Mélanger les deux produit une image qu'on ne sait plus reconstruire.
  • cloud-init conserve votre user-data en clair sur le disque, dans /var/lib/cloud/instance/user-data.txt, bien après le premier démarrage.
  • Les droits sont corrects là où cloud-init les pose, 0600, et cloud-init query caviarde sa sortie pour un compte ordinaire.
  • Avec la source NoCloud, le seed reste en 0644 et rend le user-data lisible par tout compte local. Vérifiez-le, ne le supposez pas.
  • Un secret dans user-data est un secret publié : il part dans les sauvegardes et les images dérivées. Utilisez un rôle d'instance et un gestionnaire de secrets.
  • Le service de métadonnées se protège par la version durcie du protocole, un rôle étroit et le blocage depuis les conteneurs, les trois ensemble.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens ce site gratuitement, sans publicité, sans profilage et sans compte à créer. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn