62 votes

Comment savoir si une machine est une instance EC2

Je voudrais exécuter des scripts sur des hôtes qui sont des instances EC2 mais je ne sais pas comment être sûr que l'hôte est vraiment une instance EC2.

J'ai fait quelques tests, mais ce n'est pas suffisant :

  • Tester que le binaire ec2_userdata est disponible (mais ce ne sera pas toujours vrai)
  • Test de disponibilité de " http://169.254.169.254/latest/meta-data "(mais cela sera-t-il toujours vrai ? et qu'est-ce que ce "IP magique" ?)

50voto

Josh Kupershmidt Points 756

Tout d'abord, j'ai ressenti le besoin de poster une nouvelle réponse en raison des problèmes subtils suivants avec les réponses existantes, et après avoir reçu une question sur mon commentaire sur la réponse de @qwertzguy . Voici les problèmes que posent les réponses actuelles :

  1. En réponse acceptée de @MatthieuCerda ne fonctionne pas de manière fiable, du moins pas sur les instances VPC que j'ai vérifiées. (Sur mes instances, j'obtiens un nom de VPC pour hostname -d qui est utilisé pour le DNS interne, et non pour tout ce qui contient "amazonaws.com").
  2. En réponse la plus votée de @qwertzguy ne fonctionne pas sur les nouvelles instances m5 ou c5 qui ne disposent pas de ce fichier. Amazon néglige de documenter ce changement de comportement AFAIK, bien que le fichier page doc sur ce sujet dit bien "... Si /sys/hypervisor/uuid existe ...". J'ai demandé au support AWS si ce changement était intentionnel, voir ci-dessous †.
  3. En réponse de @Jer ne fonctionne pas nécessairement partout car le instance-data.ec2.internal La recherche DNS peut ne pas fonctionner. Sur une instance EC2 VPC Ubuntu sur laquelle je viens de tester, je vois : $ curl http://instance-data.ec2.internal curl: (6) Could not resolve host: instance-data.ec2.internal ce qui amènerait le code s'appuyant sur cette méthode à conclure à tort qu'il n'est pas sur EC2 !
  4. En réponse à utiliser dmidecode de @tamale peut fonctionner, mais repose sur le fait que a.) vous ayez dmidecode disponible sur votre instance, et b.) avoir l'accès root ou sudo sans mot de passe à partir de votre code.
  5. En réponse pour vérifier /sys/devices/virtual/dmi/id/bios_version de @spkane est dangereusement trompeuse ! J'ai vérifié une instance d'Ubuntu 14.04 m5, et j'ai eu une bios_version de 1.0 . Ce fichier n'est pas du tout documenté sur le doc d'Amazon donc je ne m'y fierais vraiment pas.
  6. La première partie de la réponse de @Chris-Montanaro pour vérifier une URL tierce partie non fiable et utiliser whois sur le résultat est problématique à plusieurs niveaux. Notez que l'URL suggérée dans cette réponse est une page 404 à l'heure actuelle ! Même si vous trouviez un service tiers qui fonctionne, il serait relativement peu efficace. très lent (par rapport à la vérification d'un fichier localement) et peut rencontrer des problèmes de limitation de débit ou de réseau, ou encore votre instance EC2 n'a même pas d'accès au réseau extérieur.
  7. La deuxième suggestion de la réponse de @Chris-Montanaro pour vérifier http://169.254.169.254/ est un peu mieux, mais un autre commentateur fait remarquer que d'autres fournisseurs de services en nuage mettent à disposition l'URL des métadonnées de l'instance, et qu'il faut donc faire attention pour éviter les faux positifs. De plus, ce sera toujours beaucoup plus lent qu'un fichier local, j'ai vu cette vérification être particulièrement lente (plusieurs secondes pour revenir) sur des instances très chargées. De plus, vous devez vous rappeler de passer un -m o --max-time à curl pour éviter qu'il ne se bloque pendant un temps très long, surtout sur une instance non-EC2 où cette adresse peut ne mener nulle part et se bloquer (comme dans La réponse de @algal ).

Aussi, je ne vois pas que quelqu'un ait mentionné Documenté par Amazon solution de repli consistant à vérifier le fichier (éventuel) /sys/devices/virtual/dmi/id/product_uuid .

Qui aurait cru que déterminer si l'on fonctionne sur EC2 pouvait être si compliqué ! OK, maintenant que nous avons (la plupart) des problèmes avec les approches listées, voici une suggestion de snippet bash pour vérifier si vous êtes exécuté sur EC2. Je pense que cela devrait fonctionner généralement sur presque toutes les instances Linux, les instances Windows sont un exercice pour le lecteur.

#!/bin/bash

# This first, simple check will work for many older instance types.
if [ -f /sys/hypervisor/uuid ]; then
  # File should be readable by non-root users.
  if [ `head -c 3 /sys/hypervisor/uuid` == "ec2" ]; then
    echo yes
  else
    echo no
  fi

# This check will work on newer m5/c5 instances, but only if you have root!
elif [ -r /sys/devices/virtual/dmi/id/product_uuid ]; then
  # If the file exists AND is readable by us, we can rely on it.
  if [ `head -c 3 /sys/devices/virtual/dmi/id/product_uuid` == "EC2" ]; then
    echo yes
  else
    echo no
  fi

else
  # Fallback check of http://169.254.169.254/. If we wanted to be REALLY
  # authoritative, we could follow Amazon's suggestions for cryptographically
  # verifying their signature, see here:
  #    https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
  # but this is almost certainly overkill for this purpose (and the above
  # checks of "EC2" prefixes have a higher false positive potential, anyway).
  if $(curl -s -m 5 http://169.254.169.254/latest/dynamic/instance-identity/document | grep -q availabilityZone) ; then
    echo yes
  else
    echo no
  fi

fi

Évidemment, vous pourriez étendre ce système avec encore plus de vérifications de repli, et inclure une paranoïa sur la gestion, par exemple, d'un faux positif provenant de /sys/hypervisor/uuid qui commencent par hasard par "ec2" et ainsi de suite. Mais c'est une solution suffisante pour l'illustration et probablement pour la plupart des cas d'utilisation non pathologiques.

[†] J'ai reçu cette explication du support AWS concernant le changement pour les instances c5/m5 :

Les instances C5 et M5 utilisent une nouvelle pile d'hyperviseurs et les pilotes de noyau associés ne créent pas de fichiers dans sysfs (qui est monté dans /sys) comme le font les pilotes Xen. utilisé par les autres types d'instances plus anciennes ne . La meilleure façon de détecter si le système d'exploitation est en cours d'exécution sur une instance EC2 est de prendre en compte les différentes possibilités listées dans la section la documentation que vous avez liée .

46voto

William Lannen Points 4145

Modification de la réponse de Hannes pour éviter les messages d'erreur et inclure un exemple d'utilisation dans script :

if [ -f /sys/hypervisor/uuid ] && [ `head -c 3 /sys/hypervisor/uuid` == ec2 ]; then
    echo yes
else
    echo no
fi

Cela ne fonctionne pas dans les instances Windows. L'avantage par rapport à curl est que c'est presque instantané sur EC2 et non-EC2.

Mise à jour : Pour les nouvelles instances C5/M5, utilisez le fichier /sys/devices/virtual/dmi/id/product_uuid à la place et vérifiez si EC2 au lieu de ec2 . (Merci à Josh et Saumitra dans les commentaires pour avoir mentionné ce point)

17voto

tamale Points 274

Si le but est de savoir s'il s'agit d'une instance EC2 OU d'un autre type d'instance en nuage, comme google, alors dmidecode fonctionne très bien et aucun réseau n'est nécessaire. Je préfère cette méthode à d'autres, car le chemin d'accès à l'URL des métadonnées est différent pour EC2 et GCE.

# From a google compute VM
$ sudo dmidecode -s bios-version
Google

# From an amazon ec2 VM
$ sudo dmidecode -s bios-version
4.2.amazon

14voto

Gur Points 53

Recherchez les métadonnées par le nom de domaine interne EC2 au lieu de l'IP, ce qui renverra un échec rapide du DNS si vous n'êtes pas sur EC2 et cela évite les conflits d'IP et les problèmes de routage :

curl -s http://instance-data.ec2.internal && echo "EC2 instance" || echo "Non EC2 instance"

Sur certaines distros, des systèmes très basiques, ou très tôt dans les phases d'installation. bouclette n'est pas disponible. Utilisation de wget 代わりに

wget -q http://instance-data.ec2.internal && echo "EC2 instance" || echo "Non EC2 instance"

6voto

bruce Points 2537

Les noms d'hôtes sont susceptibles de changer, lancez un whois contre votre IP publique :

if [[ ! -z $(whois $(curl -s shtuff.it/myip/short) | grep -i amazon) ]]; then 
  echo "I'm Amazon"
else 
  echo "I'm not Amazon"
fi

ou cliquez sur l'url des méta-données AWS.

if [[ ! -z $(curl -s http://169.254.169.254/1.0/) ]]; then 
  echo "I'm Amazon"
else 
  echo "I'm not Amazon"
fi

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X