머신이 EC2 인스턴스인지 확인하는 방법


43

EC2 인스턴스 인 호스트에서 일부 스크립트를 실행하고 싶지만 호스트가 실제로 EC2 인스턴스 인지 확인하는 방법을 모르겠습니다 .

몇 가지 테스트를했지만 충분하지 않습니다.

  • 바이너리 ec2_userdata가 사용 가능한지 테스트하십시오 (그러나 항상 해당되는 것은 아님).
  • " http://169.254.169.254/latest/meta-data "의 가용성을 테스트하십시오.


실제로 APIPA 주소이며 메타 데이터 검색과 같은 중요한 서비스에 대한 참조로 사용하는 것은 매우 이상합니다.
Matthieu Cerda

2
EC2의 IP 범위는 공개적입니다 (때로는 다름). 현재 목록을 유지하면 해당 범위에 대해 인스턴스 IP를 확인할 수 있습니다.
Karma Fusebox

2
EC2를 원하고 유칼립투스와 같은 EC2 유사 시스템 지원하는 경우 169.254.169.254에 의존하지 마십시오 . engage.eucalyptus.com/customer/portal/articles/...
ceejayoz

1
호스트에 루트가 있고 공격자가 자신의 악의적 인 목적을위한 EC2 인스턴스라고 생각하도록 스푸핑하려는 공격자에 대해 작동하는 방법이 필요합니까? 그렇게하면 훨씬 더 어려워집니다.
Mike Scott

답변:


3

실제로 호스트가 EC2 인스턴스인지 감지하는 매우 간단한 방법이 있습니다. 퍼블릭 IP의 역방향 조회를 확인하십시오. EC2 반전은 놓치기 매우 어렵습니다.

또한 수정하지 않은 경우 호스트 이름이 반대로되어 더 쉽게 찾을 수 있습니다.

EC2 인스턴스 태그를 가져 오는 표준 방법이므로 실제로 "매직 IP"를 사용할 수도 있지만 EC2 네트워크에 있지 않은 경우 일반적으로 그렇지 않은 타임 아웃을 기다려야합니다. 바람직한...

이러한 방법으로 충분하지 않은 경우 IP를 만든 후 Amazon EC2 IP 블록 내에 있는지 확인하십시오.

편집 :이 작은 쉘 비트를 사용할 수 있습니다 :

#!/bin/bash
LOCAL_HOSTNAME=$(hostname -d)
if [[ ${LOCAL_HOSTNAME} =~ .*\.amazonaws\.com ]]
then
        echo "This is an EC2 instance"
else
        echo "This is not an EC2 instance, or a reverse-customized one"
fi

하지만 [[는 bashism입니다. Python 또는 Perl uniline YMMV를 사용할 수도 있습니다.


13
VPC 또는 호스트 이름을 변경 한 환경에서는 작동하지 않습니다. 예. 컴퓨터가 domain.local에있는 경우
Preflightsiren

2
호스트 이름 비트가 실패 할 수밖에 없습니다.
Dan Pritts

3
hostname -d반환eu-west-1.compute.internal
Bulletmagnet

42

오류 메시지를 피하고 스크립트에 사용 예를 포함시키기 위해 Hannes의 답변을 변경했습니다.

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

Windows 인스턴스에서는 작동하지 않습니다. 컬에 비해 이점은 EC2와 비 EC2 모두에서 순간에 가깝다는 것입니다.



3
나는이 방법을 좋아한다. 하이퍼 바이저에서 실행되는 비 EC2 시스템 ec2은 오 탐지로 시작하는 UUID를 생성 할 수 있습니다. 해당 파일을 채우는 하이퍼 바이저를 사용하는 경우에만 (256-in-256 기회) 가능성은 없습니다. 그렇기 때문에 위에 링크 된 설명서에 " EC2 인스턴스를보고 있을 것 "이라고 나와 있습니다.
Nate

1
@Nate, 좋은 지적이지만 4096 확률의 1이 아니어야합니까? (16 x 16 x 16)
와일드 카드

2
@Wildcard : 내 의견을 편집 할 수는 없지만 맞습니다.
Nate

7
위험! 이 방법은 최근까지도이 파일이없는 최신 c5 및 m5 유형을 사용하여 수년 동안 안정적으로 작동했습니다 . 따라서 해당 인스턴스를 처리 하려면 169.254.169.254 의 폴백 검사를 추가해야 합니다.
Josh Kupershmidt

20

먼저 기존 답변에 대한 다음과 같은 미묘한 문제로 인해 @qwertzguy의 답변에 대한 내 의견에 대한 질문을받은 후 새로운 답변을 게시해야한다고 생각했습니다 . 현재 답변과 관련된 문제는 다음과 같습니다.

  1. 허용 대답 @MatthieuCerda에서 확실히 이상하지 나에 대해 검사 어떤 VPC 인스턴스에 안정적으로 작동하지 않습니다. (내 경우 hostname -d에는 "amazonaws.com"이없는 내부 DNS에 사용되는에 대한 VPC 이름을 얻 습니다.)
  2. @qwertzguy 의 최고 투표 답변 은이 파일이없는 새 m5 또는 c5 인스턴스 에서 작동하지 않습니다. 있지만,이 행동 변화 AFAIK를 문서화하는 무시 아마존 문서 페이지 이 주제에 대한 말을 않는 "... 하면 / SYS / 하이퍼 바이저 / UUID 존재 ...". 이 변경이 의도적인지 AWS 지원에 요청했습니다. 아래 †를 참조하십시오.
  3. DNS 조회가 작동하지 않을 수 있기 때문에 @Jer답변이 모든 곳에서 반드시 작동하는 것은 아닙니다 instance-data.ec2.internal. 방금 테스트 한 Ubuntu EC2 VPC 인스턴스 $ curl http://instance-data.ec2.internal curl: (6) Could not resolve host: instance-data.ec2.internal 에서이 방법에 의존하는 코드가 EC2에 있지 않다고 잘못 판단하게됩니다!
  4. @tamale 에서 사용dmidecode 하는 대답 은 효과가있을 수 있지만 a.) dmidecode인스턴스에서 사용할 수 있고 b.) sudo코드 내에서 루트 또는 암호가없는 기능 이 있어야 합니다.
  5. 대답은 / SYS / 장치를 확인 / 가상 / DMI / ID / bios_version @spkane에서 위험하게 오해의 소지가있다! 나는 1 개 우분투 14.04 M5 인스턴스를 확인하고있어 bios_version1.0. 이 파일은 Amazon의 doc에 전혀 문서화되어 있지 않으므로 실제로 의존하지는 않습니다.
  6. 신뢰할 수없는 타사 URL을 확인 하고 결과에 사용하는 @ Chris-Montanaro답변 중 첫 번째 부분은 whois여러 수준에서 문제가 있습니다. 해당 답변에서 제안 된 URL은 현재 404 페이지입니다. 당신이 일을했던 제 3 자 서비스를 발견했다하더라도, 그것은 비교적 것이 매우 (로컬 파일을 확인 비해) 느리고 가능 속도 제한 문제 또는 네트워크 문제로 실행, 또는 아마도 당신의 EC2 인스턴스도 가지고 있지 않습니다 외부 네트워크 액세스.
  7. @ Chris-Montanarohttp://169.254.169.254/ 를 확인 하는 대답에 대한 두 번째 제안은 조금 낫지 만 다른 클라우드 제공 업체는 다른 클라우드 공급자 가이 인스턴스 메타 데이터 URL을 사용할 수 있다고 언급하므로 거짓을 피해야합니다. 긍정적. 또한 로컬 파일보다 훨씬 느릴 것입니다.로드가 많은 인스턴스 에서이 검사가 특히 느리게 (수 초) 반환되는 것을 보았습니다. 또한, 특히 @ algal 's answer 에서와 같이이 주소가 아무데도 멈추거나 중단 될 수있는 EC2가 아닌 인스턴스에서 매우 오랫동안 중단되지 않도록 컬에 인수 -m또는 --max-time인수 를 전달 해야합니다 .

또한 (가능한) 파일 확인에 대한 아마존의 문서화 된 폴백을 언급 한 사람은 아무도 없습니다 /sys/devices/virtual/dmi/id/product_uuid.

EC2에서 실행 중인지 판단하는 것이 너무 복잡하다는 것을 누가 알았습니까?! 이제 나열된 접근법에 대한 문제가 대부분 있었으므로 EC2에서 실행 중인지 확인하기 위해 제안 된 bash 스 니펫이 있습니다. 나는 이것이 거의 모든 Linux 인스턴스에서 일반적으로 작동해야한다고 생각합니다 .Windows 인스턴스는 독자에게 연습입니다.

#!/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

분명히, 더 많은 폴백 검사를 통해이를 확장 할 수 /sys/hypervisor/uuid있으며 우연히 "ec2"로 시작 하는 오 탐지 등의 처리에 대한 편집증을 포함시킬 수 있습니다. 그러나 이것은 예시 목적으로 사용되며 거의 모든 병리학 적 사용 사례에 대한 충분한 솔루션입니다.

[†] c5 / m5 인스턴스 변경에 대한 AWS 지원의 설명을 다음에서 확인하십시오.

C5 및 M5 인스턴스는 새로운 하이퍼 바이저 스택 을 사용하며 관련 커널 드라이버는 다른 / 이전 인스턴스 유형에서 사용 하는 Xen 드라이버가 그렇듯이 sysfs (/ sys에 마운트 됨)에 파일을 만들지 않습니다 . 운영 체제가 EC2 인스턴스에서 실행 중인지 여부를 감지하는 가장 좋은 방법은 연결설명서에 나열된 다양한 가능성을 설명하는 것 입니다.


4
예, 2018 년 동료 여행자 ... 이것은 당신이 찾고있는 대답입니다.
russellpierce

/ sys / devices / virtual / dmi / id / product_uuid를 읽으려면 루트 권한이 필요합니다
Thayne

@Thayne correct-이것이 해당 elif블록 위의 주석이 말한 것이므로 elif테스트에서 -r테스트 연산자를 사용 하여 파일이 있는지 여부와 파일에 대한 읽기 권한이 있는지 확인합니다.
Josh Kupershmidt

169.254.169.254 메타 데이터 에 대한 추가 참고 사항 -부팅시 항상 준비되지는 않습니다. 부트 스크립트에 해당 메타 데이터가 필요한 경우 준비가 될 때까지 폴링을 유지해야합니다. 인스턴스가 cloud-init 부트 스크립트를 실행하기 시작한 후 최대 30 초가 소요되는 것을 보았습니다.
vacri

15

IP 대신 EC2 내부 도메인 이름으로 메타 데이터를 찾으십시오. 그러면 EC2에 있지 않은 경우 빠른 DNS 오류가 발생하고 IP 충돌 또는 라우팅 문제가 발생하지 않습니다.

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

일부 배포판에서는 매우 기본적인 시스템 또는 설치 단계 초기에 컬을 사용할 수 없습니다. 사용 wget과 대신 :

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

4
불행히도 VPC에서 실패한 것으로 보입니다!
애쉬

2
또한 큰 따옴표 안에 느낌표 문자를 사용하지 마십시오 . 에코 가 울릴 수 있습니다 -bash: !": event not found. echo대신 작은 따옴표를 사용하십시오 .
Josh Kupershmidt

1
이것은 아마도 서버가 여전히 ec2.internal 영역에 대해 알고있는 EC2s DNS 서버를 사용하고 있고 아무도 /etc/resolv.conf를 8.8.8.8로 변경하거나 자체 DNS 인프라를 롤링하지 않은 것으로 가정합니다.
lamont

1
AWS가이를 위반 한 것으로 보입니다. 더 이상 instance-data.ec2.internal을 해결할 수 없습니다. 하지만 현재로서는 instance-data.us-west-2.compute.internal이 작동합니다.
Bryan Larsen

14

목표가 EC2 인스턴스인지 아니면 Google과 같은 다른 종류의 클라우드 인스턴스인지를 알리는 것이라면 dmidecode매우 잘 작동하며 네트워킹이 필요하지 않습니다. EC2와 GCE의 메타 데이터 URL 경로가 다르기 때문에 다른 접근 방식과 비교하여이 방법을 선호합니다.

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

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

다른 VM 환경과 실제 하드웨어에서도이 기능이 제대로 작동 할 것으로 기대합니다. 하드웨어 공급 업체에서 BIOS 버전이 "amazon"이라고 표시된 시스템을 제공 할 것으로 기대하지는 않습니다.
Guss

내 Ubuntu EC2 인스턴스에서 이것은 1.0아무것도 언급하지 않습니다 amazon.
네이트

5

호스트 이름이 변경 될 수 있습니다. 퍼블릭 IP에 대해 whois를 실행하십시오.

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

또는 AWS 메타 데이터 URL을 누르십시오

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

2
EC2에서 실행 중이 아닌 경우 --connect-timeout 1을 두 번째 curl 문에 추가하여 빠르게 실패합니다.
Jonathan Oliver

1
FWIW는, 메타 데이터 URL을 사용하여 할 수 는 클라우드 인스턴스로 실행중인 표시하지만, 특별히 EC2의 경우 결정적으로 확인할 수 없습니다. OpenStack과 Eucalyptus도 동일한 메타 데이터 URI를 사용합니다. 나는 이것이 니트를 선택하고 있다는 것을 알고 있지만 클라우드 공급 업체가 중요한 내 작업에 적합합니다.
EmmEff

5

이것은 ec2의 Linux 호스트에서도 잘 작동하며 네트워크 및 관련 시간 초과가 필요하지 않습니다.

grep -q amazon /sys/devices/virtual/dmi/id/bios_version

아마존 이이 항목을 다음과 같이 정의하기 때문에 작동합니다.

$ cat /sys/devices/virtual/dmi/id/bios_version 4.2.amazon


2018-05-01; Ubuntu를 실행하는 M5 인스턴스에서 유효하지 않은 것으로 보입니다.
russellpierce

내 Ubuntu EC2 인스턴스에서이 반환합니다 1.0. 에 대한 언급이 없습니다 amazon.
네이트

3
test -f /sys/hypervisor/uuid -a `head -c 3 /sys/hypervisor/uuid` == ec2 && echo yes

그러나 나는 이것이 배포판에서 얼마나 이식 가능한지 모르겠다.


2
글쎄, 확실히 Windows EC2 인스턴스에서는 작동하지 않을 것입니다.
ceejayoz 2016 년

1
이 방법은 모든 종류의 이유로 중단 될 수있는 네트워크 상호 작용을 포함하지 않기 때문에 선호합니다. 정지를 막기 위해 HTTP 교환에 시간 종료를 사용한다고 보장되지는 않습니다. Windows 인스턴스는 신경 쓰지 않습니다.
Hannes

바로 내가 필요한 것입니다! 무언가를 컬링하는 것보다 훨씬 낫습니다. 감사합니다!
qwertzguy

1
다른 공급 업체의 하이퍼 바이저 UUID가 "ec2"로 시작하는 경우를 대비하여 전체 UUID 사용을 고려하십시오. 그 일이 일어날 확률은 4096에서 1이며 무시할 수 없습니다.
Hannes

1
실제로, 여러 다른 하이퍼 바이저 UUID를 야생에서 보았으므로 전체 UUID를 비교할 수 없습니다. 그러나 모두 "ec2"로 시작하므로이 답변은 그대로 작동합니다.
Hannes

3

빠른 답변 :

if [[ -f /sys/devices/virtual/dmi/id/product_uuid ]] && \
    grep -q "^EC2" /sys/devices/virtual/dmi/id/product_uuid
then
    echo "IS EC2"
else
    echo "NOT EC2"
fi

나는 1 년 넘게 여기에 게시 된 답변 중 하나를 사용했지만 새로운 'c5'인스턴스 유형에서는 작동하지 않습니다 (지금 'c4'에서 업그레이드하는 중입니다).

나는이 솔루션이 나중에 깨질 가능성이 가장 적은 것처럼 보이기 때문에 좋아합니다.

이전 인스턴스 유형과 최신 인스턴스 유형에서이 파일은 존재하며 'EC2'로 시작합니다. VirtualBox에서 실행중인 Ubuntu를 확인했으며 (지원해야 함) 문자열 'VirtualBox'가 포함되어 있습니다.

이전 포스터에서 언급했듯이 (그러나 놓치기 쉬웠습니다.)이 작업을 수행하는 방법에 대한 Amazon 설명서가 있습니다.

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html


2

아마도 당신은 "facter"를 사용할 수 있습니다 :

"Facter는 운영 체제, Linux 배포판 또는 MAC 주소와 같은 간단한 운영 체제 사실을 검색하기위한 크로스 플랫폼 라이브러리입니다."

http://www.puppetlabs.com/puppet/related-projects/facter/

예를 들어, ec2 팩트 (fact-1.6.12 / lib / facter / ec2.rb)를 살펴보면 다음과 같습니다.

require 'facter/util/ec2'
require 'open-uri'

def metadata(id = "")
  open("http://169.254.169.254/2008-02-01/meta-data/#{id||=''}").read.
    split("\n").each do |o|
    key = "#{id}#{o.gsub(/\=.*$/, '/')}"
    if key[-1..-1] != '/'
      value = open("http://169.254.169.254/2008-02-01/meta-data/#{key}").read.
        split("\n")
      symbol = "ec2_#{key.gsub(/\-|\//, '_')}".to_sym
      Facter.add(symbol) { setcode { value.join(',') } }
    else
      metadata(key)
    end
  end
end

def userdata()
  begin
    value = open("http://169.254.169.254/2008-02-01/user-data/").read.split
    Facter.add(:ec2_userdata) { setcode { value } }
  rescue OpenURI::HTTPError
  end
end

if (Facter::Util::EC2.has_euca_mac? || Facter::Util::EC2.has_openstack_mac? ||
    Facter::Util::EC2.has_ec2_arp?) && Facter::Util::EC2.can_connect?

  metadata
  userdata
else
  Facter.debug "Not an EC2 host"
end

1

curl을 설치 한 경우 EC2 내에서 실행중인 경우이 명령은 0을 반환하고 그렇지 않은 경우 0이 아닌 값을 반환합니다.

curl --max-time 3 http://169.254.169.254/latest/meta-data/ami-id 2>/dev/null 1>/dev/null`

AMI-ID를 선언하는 EC2 메타 데이터를 가져 오려고 시도합니다. 3 초 후에도 성공하지 못하면 EC2에서 실행되지 않는 것으로 가정합니다.


0

이 파티에 조금 늦었지만이 게시물을 보았고이 AWS 설명서를 찾았습니다.

EC2 인스턴스를 식별하는 결정적이고 암호로 검증 된 방법은 서명을 포함하여 인스턴스 자격 증명 문서를 확인하십시오. 이러한 문서는 모든 EC2 인스턴스에서 라우팅 할 수없는 로컬 주소 http://169.254.169.254/latest/dynamic/instance-identity/에서 제공됩니다.

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html

컬 타임 아웃을 다음과 같이 설정할 수는 있지만 네트워크 오버 헤드가 필요합니다.

curl -s --connect-timeout 5 http://169.254.169.254/latest/dynamic/instance-identity/

시간 초과가 5 초로 설정됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.