1. 개요

IMDS(Instance Metadata Service)는 EC2 인스턴스가 자기 정보를 읽어 오는 서비스다. 인스턴스 안에서 링크 로컬 주소 169.254.169.254 로 요청하면 인스턴스 ID, 네트워크 정보, 그리고 인스턴스에 붙은 IAM 역할의 임시 자격 증명을 돌려준다.

# IMDSv2 — 세션 토큰을 먼저 받고 그 토큰으로 읽는다
TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token \
  -H "X-aws-ec2-metadata-token-ttl-seconds: 60")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

인스턴스 안의 AWS SDK 는 이 경로로 자격 증명을 받아 쓴다. 그래서 인스턴스 안에서 이 주소에 닿는 프로그램은 누구든 그 인스턴스의 AWS 권한을 쓸 수 있다.

2. 버전

IMDSv1IMDSv2
요청GET 한 번PUT 으로 세션 토큰을 받은 뒤 그 토큰으로 GET
SSRF 에 대한 내성약함. URL 만 조작하면 읽힌다강함. 임의의 PUT 과 헤더를 만들어야 한다
강제—http_tokens = "required" 로 v1 을 끈다

웹 앱이 사용자 입력 URL 로 요청을 보내는 SSRF 취약점이 있으면, IMDSv1 에서는 그 앱을 통해 자격 증명이 새어 나간다. IMDSv2 를 강제하면 이 경로가 대부분 막힌다.

3. hop limit

hop limit 은 IMDSv2 토큰 응답(PUT 의 응답) 패킷의 TTL 이다. 패킷이 네트워크 장비를 하나 지날 때마다 TTL 이 1 줄어, 0 이 되면 버려진다.

hop limit결과
1인스턴스 자신만 토큰을 받는다. 컨테이너(브리지·veth 를 한 번 더 지남)는 받지 못한다
2인스턴스 위의 컨테이너도 토큰을 받는다

쿠버네티스 노드에서 hop limit 1 은 일반 Pod 가 노드의 IAM 역할을 쓰지 못하게 막는다. hostNetwork: true 인 Pod 는 노드와 같은 네트워크를 쓰므로 막히지 않는다.

# Terraform launch template
metadata_options {
  http_endpoint               = "enabled"
  http_tokens                 = "required"   # IMDSv2 강제
  http_put_response_hop_limit = 1            # Pod 차단
}

4. 컨테이너에서의 위험

경로결과
Pod 가 IMDS 에 닿음노드 역할로 ECR 이미지 받기, EC2 정보 조회 등 노드 권한 사용
컨테이너 탈출노드 자체가 되므로 hop limit 과 상관없이 IMDS 를 쓴다

hop limit 은 첫 번째 경로만 막는다. 두 번째는 gVisor 같은 샌드박스가 맡는다. 여러 팀의 코드가 한 노드에서 도는 클러스터에서는 두 겹을 함께 쓰고, 네트워크 정책으로 169.254.169.254 를 한 번 더 막는다.

5. Pod 가 AWS 권한이 필요할 때

노드 역할을 Pod 에 나눠 주는 대신, Pod 마다 따로 권한을 준다.

방식원리
IRSAServiceAccount 토큰(OIDC)으로 IAM 역할을 직접 받는다
EKS Pod Identity노드의 에이전트가 ServiceAccount 에 연결된 역할의 자격 증명을 준다

이 방식을 쓰면 노드의 hop limit 을 1 로 두고도 필요한 Pod 만 AWS 를 쓸 수 있다.

6. 확인 명령

# 인스턴스 설정 확인
aws ec2 describe-instances --instance-ids i-0123456789abcdef0 \
  --query 'Reservations[].Instances[].MetadataOptions'

# Pod 안에서 막혔는지 확인 (응답이 없어야 정상)
wget -q -T 3 -O- http://169.254.169.254/latest/meta-data/ || echo blocked

7. 관련 문서

  • gVisor — 컨테이너 탈출 경로를 줄이는 샌드박스
  • Cilium — 메타데이터 주소를 정책으로 막고 차단을 기록
  • Subnet — 링크 로컬 대역 169.254.0.0/16
  • IRSA (예정) — ServiceAccount 로 IAM 역할을 받는 방식

8. 출처