가시다(gasida) 님이 진행하는 AEWS(Amazon EKS Workshop Study) 3기 과정으로 학습한 내용을 정리 또는 실습한 내용을 정리한 게시글입니다.
6주차는 EKS Security 영역에 대해 가시다님께서 4시간에 장시간 열강 강의를 해 주셨습니다.
그렇지만, 6주차는 개인적인 사정으로 AWS IDMS 개인 학습 및 실습한 내용으로 대체하여 정리하였습니다.
최근 보안관련하여 IDMSv2를 필수적용 대상으로 언급되고 있는데 누군가에겐 도움이 되길 바랍니다.
Instance Metadata란 실행 중인 인스턴스를 구성하거나 관리하는데 사용되는 인스턴스에 대한 데이터를 의미한다. EC2는 그저 가상화한 하드웨어의 조각일 뿐, 자신이 EC2인지 클라우드에 올라간 서버인지 모른다. EC2를 생성하게 되면 해당 EC2는 자동으로 Metadata와 연결되어 정보를 얻고, 서비스를 제공한다고 생각하면 됩니다.
IMDSv1/IMSDv2 정식명칭 및 동작방식
Instance Metadata Service Version 1(IMDSv1) – a request/response (요청/응답)
Instance Metadata Service Version 2(IMDSv2) – a session-oriented (세션중심), TOKEN 발급후 AWS API 호출시 TOKEN을 포함
모든 Amazon Linux 2 및 Amazon Linux 2023 소프트웨어 패키지에서 IMDSv2를 지원합니다.
실행 중인 인스턴스에서 인스턴스 메타데이터 옵션을 수정할 수 있으며, 인스턴스 메타데이터 옵션을 수정한 후 즉시 적용됨으로 인스턴스를 재시작은 하지 않아도 됩니다.
메타데이터 응답 홉 제한: 1–64
TOKEN 발생을 위한 홉 제한은 PUT 응답에 허용된 네트워크 홉 수입니다. 홉 제한을 최소 1 및 최대 64로 설정할 수 있습니다.
컨테이너 환경에서는 반드시 홉 제한을 2로 설정 필요
메타데이터 응답 홉이 1일 경우 Docker 또는 Pod에서 AWS SDK 또는 Meta 정보 호출 시 Timeout (테스트 시 2분 경과 후) 발생됨
메타옵션 값 조회
❯ aws ec2 describe-instances --instance-ids i-080981d396f13742f | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
IMDSv2 - 메타데이터 응답 홉을 2로 변경
❯ aws ec2 modify-instance-metadata-options \
--instance-id i-080981d396f13742f \
--http-put-response-hop-limit 2 \
--http-endpoint enabled
AMI - AMI를 등록하거나 수정할 때 imds-support 파라미터를 v2.0으로 설정할 수 있습니다. 이 AMI로 인스턴스를 시작하면 인스턴스 메타데이터 버전이 자동으로 IMDSv2로 설정되고 홉 제한은 2로 설정됩니다.
IMDS를 통해 사용자(또는 인스턴스에서 실행되는 코드)가 인스턴스 시작에 사용된 AMI의 ID, 블록 디바이스 매핑, 인스턴스에 연결된 역할의 임시 IAM 보안 인증, 네트워크 인터페이스 정보, 사용자 데이터 등 풍부한 정적 및 동적 데이터에 액세스할 수 있습니다(인스턴스 메타데이터 카테고리 참조).
Amazon EC2 인스턴스 메타데이터 서비스(IMDS)는 고객이 안전하고 확장 가능한 애플리케이션을 구축하는 데 도움을 주었습니다.
IMDS는 자주 교체되는 임시 자격 증명에 대한 액세스를 제공하고 민감한 자격 증명을 수동으로 또는 프로그래밍 방식으로
인스턴스에 하드코딩하거나 배포할 필요성을 제거함으로써 클라우드 사용자의 큰 보안 문제를 해결했습니다.
모든 EC2 인스턴스에 로컬로 연결된 IMDS는 특수한 "링크 로컬" IP 주소 69.254.169.254에서 실행됩니다. 즉, 인스턴스에서 실행 중인 소프트웨어만 IMDS에 액세스할 수 있습니다. IMDS에 액세스할 수 있는 애플리케이션의 경우 인스턴스, 네트워크 및 스토리지에 대한 메타데이터를 사용할 수 있습니다. 또한 IMDS는 인스턴스에 연결된 모든 IAM 역할 에 AWS 자격 증명을 사용할 수 있도록 합니다.
클라우드에서 애플리케이션을 실행할 때 애플리케이션 보안은 인스턴스 보안만큼 중요합니다. 인스턴스에서 실행 중인 애플리케이션에 취약점이 있거나 구성이 잘못되어 있으면 심각한 결과가 발생할 수 있습니다. 애플리케이션 보안은 계층화된 방어에서 중요한 역할을 하지만, AWS는 이러한 상황이 발생할 때 발생할 수 있는 피해를 최소화하기 위해 인스턴스 내에서도 계층을 추가할 위치를 지속적으로 평가합니다.
IMDSv1 서비스는 요청/응답 액세스 방법을 사용
인증(TOKEN) 없이 메타 정보 조회, 응용어플리케이션 또는 AWS SDK/API 호출 가능
Metadata 조회는 별도의 IAM Role 없이도, AWS EC2라면 모두 조회가 가능하며, 아래 curl 명령어로 입력하는 IP주소는 AWS의 Internal IP 주소로 EC2에서만 조회가능
❯ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
managed-ssh-keys/
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
IMDSv1의 문제점 예시
만약 서버가 IAM Role이 할당되어 있는 상태이면, /iam/security-credentials/<role-name>을 조회하여 임시 자격증명을 발급받을 수 있다. 아래의 명령어로 내가 생성한 ec2-admin이라는 Role의 자격증명을 발급받았다. 자세히 보면, Access Key, Secret Key, Token, 그리고 만료 날짜도 보인다.
❯ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/your_ec2_iam_role

이 정보를 이용해 외부인도 아래와 같이 해당 Role의 권한을 자유롭게 이용하여 AWS 내부 서비스에 접근할 수 있다. 아래의 예제는 위에 출력된 값을 입력하여, 내 AWS 계정의 S3 버킷 리스트를 출력한 결과다. 허가받지 않은 외부인이라면 좀 더 무서운 명령어를 입력할 수도 있어 보인다.
(https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)
내 PC에서 AWS 접속

IMDSv2 서비스는 세션 지향 방법을 사용
MDSv2를 사용하면 이제 모든 요청이 세션 인증으로 보호됩니다.
세션은 EC2 인스턴스에서 실행되는 소프트웨어가 로컬에 저장된 EC2 인스턴스 메타데이터 및 자격 증명에 액세스하는 데 사용하는 일련의 요청을 시작하고 끝냅니다.
소프트웨어는 IMDSv2에 대한 간단한 HTTP PUT 요청으로 세션을 시작합니다. IMDSv2는 EC2 인스턴스에서 실행되는 소프트웨어에 비밀 토큰을 반환합니다. 소프트웨어는 해당 토큰을 암호로 사용하여 IMDSv2에 메타데이터 및 자격 증명을 요청합니다.
기존 비밀번호와 달리 소프트웨어가 PUT 요청 을 통해 토큰을 스스로 가져오기 때문에 소프트웨어에 토큰을 가져오는 것에 대해 걱정할 필요가 없습니다.
토큰은 IMDSv2에 의해 저장되지 않으며 후속 호출로 검색될 수 없습니다. 따라서 토큰을 사용하는 프로세스가 종료되면 세션과 해당 토큰이 효과적으로 삭제됩니다. 단일 세션 내의 요청 수에는 제한이 없으며 IMDSv2 세션 수에도 제한이 없습니다. 세션은 최대 6시간 동안 지속될 수 있으며 보안 강화를 위해 세션 토큰은 해당 세션이 시작된 EC2 인스턴스에서만 직접 사용할 수 있습니다.
예를 들어, 다음 curl 레시피는 6시간(21600초) 동안 유효한 세션 토큰을 검색한 다음 해당 토큰을 사용하여 EC2 인스턴스의 프로필 메타데이터에 액세스합니다.
❯ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
❯ curl http://169.254.169.254/latest/meta-data -H "X-aws-ec2-metadata-token: $TOKEN"
두 서비스 모두 완벽하게 안전하지만 v2는 IMDS에 액세스하려고 시도하는 데 사용될 수 있는 네 가지 유형의 취약점(개방형 웹사이트 애플리케이션 방화벽으로부터 보호, 개방형 역방향 프록시로부터 보호, SSRF 취약점으로부터 보호, 개방형 레이어 3 방화벽 및 NAT로부터 보호)에 대한 추가 보호 계층을 제공합니다.
이미 많은 애플리케이션 및 인스턴스가 IMDSv2를 사용하고 그 이점을 활용하고 있지만, AWS 계정 수준에서 IMDSv1을 비활성화해야만 모든 이점을 누릴 수 있습니다.
2024년 중반부터 새로 출시되는 Amazon EC2 인스턴스 유형은 EC2 인스턴스 메타데이터 서비스의 버전 2(IMDSv2)만 사용할 예정입니다.
또한 IMDSv2를 AWS Management Console 퀵 스타트 및 기타 시작 경로의 기본 선택으로 만들기 위한 일련의 조치가 진행 중에 있습니다.
❯ aws ec2 describe-instances --instance-ids <enter-your-instanced-id>
예) aws ec2 describe-instances --instance-ids i-080981d396f13742

내가 사용하는 EC2의 IMDS Version을 확인하려면 아래 CLI 명령어로 EC2의 정보를 조회하면 알 수 있다.
❯ aws ec2 describe-instances --region <region> --instance-id <instance-id> --query "Reservations[0].Instances[0].MetadataOptions"
예) aws ec2 describe-instances --region ap-northeast-2 --instance-id i-080981d396f13742f --query "Reservations[0].Instances[0].MetadataOptions"
각 IMDS Version 별로 결과물은 아래와 같다. 참고로 v1 만 활성화는 없다.
#IMDS v1 & v2
{
"State": "applied",
"HttpEndpoint": "enable",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1
}
#IMDS v2
{
"State": "applied",
"HttpEndpoint": "enabled",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 1
}
기존 EC2가 IMDSv1을 사용중인 경우 IDMSv2 방식으로 전환 필요, 아래 IMDSv1에서 IMDSv2로 전환 방법 참조
Docker 또는 EKS WorkerNode의 경우 Metadata reponse hop limit 1일때는 2로 변경 필요 함
IMDSv2가 필요로 적용된 경우 IMDSv1이 작동하지 않음
인스턴스에 IMDSv2가 필요한지 확인하려면 다음과 같이 하세요. 세부 정보를 볼 인스턴스를 선택하고 IMDSv2 값을 확인합니다. 값은 필수(IMDSv2만 사용 가능) 또는 선택(IMDSv2 및 IMDSv1 사용 가능)입니다
쿼리는 인스턴스당 IMDS로 제한되고, 한 인스턴스에서 IMDS로의 동시 연결 수에도 제한이 있습니다.
IMDS를 사용하여 AWS 보안 인증 정보를 가져올 경우 모든 트랜잭션 중에 또는 많은 스레드나 프로세스에서 동시에 자격 증명을 쿼리하지 마세요. 이렇게 하면 제한이 발생할 수 있습니다. 자격 증명 만료일이 다가오기 전까지는 자격 증명을 캐시에 저장하는 것이 좋습니다. IAM 역할 및 해당 역할과 연결된 보안 자격 증명에 대한 자세한 내용은 인스턴스 메타데이터에서 보안 자격 증명 검색 섹션을 참조하세요.
IMDS에 액세스하는 동안 제한이 발생하면 지수 백오프 전략으로 쿼리를 다시 시도하세요.

환경: EKS 1.24, EC2 WorkerNode는 Amazon Linux 2 사용
EC2는 IMDSv2 optional 설정 됨
HttpPutResponseHopLimit 조회 시 1로 설정되어 있음, 컨테이너 환경에서는 컨테이너가 추가 1개의 네트워크 hop으로 간주되기 때문에 AWS SDK를 이용하는 경우, IMDS 조회시 v2로 우선적으로 조회가 되고, 계속하여 실패하는 경우 v1을 이용하여 IMDS를 진행하게 됨
AWS 기술문서 상으로 컨테이너 환경에서는 Metadata response hop limit을 2로 설정할 것을 권장하고 있음
❯ aws ec2 describe-instances --instance-ids i-0c5505eb84a3e27fe | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
(방안1) Launch template의 Advanced details 부분에서 설정, 노드 교체 필요
(방안2) Terraform 사용 시 Launch-template 항목 코드 변경 후 배포, 노드 교체 필요
metadata_options {
http_endpoint = "enabled"
http_tokens = "required"
http_put_response_hop_limit = 2
instance_metadata_tags = "enabled"
}
(방안3) CloudShell에서 CLI 명령으로 온라인으로 Metadata reponse hop limit 값을 변경, 노드 교체 없이 가능. AutoScaling 환경은 임시 방편
❯ aws ec2 modify-instance-metadata-options \
--instance-id i-0c5505eb84a3e27fe \
--http-put-response-hop-limit 2 \
--http-endpoint enabled
❯ aws ec2 describe-instances --instance-ids i-0c5505eb84a3e27fe | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}

IMDSv2로 마이그레이션하는 경우 다음과 같은 도구와 전환 경로를 사용하는 것이 좋습니다.
소프트웨어가 IMDSv1을 사용하는 경우 다음 도구를 사용하면 IMDSv2를 사용하도록 소프트웨어를 재구성하는 데 도움이 됩니다.
AWS 소프트웨어
최신 버전의 AWS CLI 및 AWS SDK는 IMDSv2를 지원합니다. IMDSv2를 사용하려면 EC2 인스턴스에 최신 버전의 CLI 및 SDK가 있는지 확인합니다. CLI 업데이트에 대한 자세한 내용은 AWS Command Line Interface 사용 설명서에서 AWS CLI 설치, 업데이트 및 제거를 참조하세요.모든 Amazon Linux 2 및 Amazon Linux 2023 소프트웨어 패키지에서 IMDSv2를 지원합니다. Amazon Linux 2023에서는 IMDSv1은 기본적으로 비활성화되어 있습니다.IMDsv2를 지원하는 최소 AWS SDK 버전은 지원되는 AWS SDK 사용 섹션을 참조하세요.
IMDS 패킷 분석기
IMDS 패킷 분석기는 인스턴스의 부팅 단계에서 IMDSv1 호출을 식별하고 기록하는 오픈 소스 도구입니다. 이는 EC2 인스턴스에서 IMDSv1 호출을 수행하는 소프트웨어를 식별하는 데 도움이 되며, 이를 통해 인스턴스가 IMDSv2만 사용할 준비가 되도록 업데이트해야 하는 항목을 정확히 찾아낼 수 있습니다. 명령줄에서 IMDS 패킷 분석기를 실행하거나 서비스로 설치할 수 있습니다. 자세한 내용은 GitHub의 IMDS 패킷 분석기를 참조하세요.
CloudWatch
IMDSv2는 토큰 지원 세션을 사용하지만 IMDSv1은 사용하지 않습니다. MetadataNoToken CloudWatch 지표는 IMDSv1을 사용하는 인스턴스 메타데이터 서비스(IMDS)에 대한 호출 수를 추적합니다. 이 지표를 0까지 추적하면 모든 소프트웨어가 IMDSv2를 사용하도록 업그레이드되었는지 여부와 업그레이드된 시간을 확인할 수 있습니다.IMDSv1을 비활성화한 후 MetadataNoTokenRejected CloudWatch 지표를 사용하여 IMDsv1 직접 호출이 시도되었지만 거부된 횟수를 추적할 수 있습니다. 이 지표를 추적하면 IMDSv2를 사용하기 위해 소프트웨어를 업데이트해야 하는지 여부를 확인할 수 있습니다.자세한 내용은 인스턴스 지표 단원을 참조하십시오.
EC2 API 및 CLI 업데이트
새 인스턴스의 경우 RunInstances API를 사용하여 IMDSv2를 사용해야 하는 새 인스턴스를 시작할 수 있습니다. 자세한 내용은 새 인스턴스에 대한 인스턴스 메타데이터 옵션 구성 단원을 참조하십시오.기존 인스턴스의 경우 ModifyInstanceMetadataOptions API를 사용하여 IMDSv2를 사용하도록 할 수 있습니다. 자세한 내용은 기존 인스턴스에 대한 인스턴스 메타데이터 옵션 수정 단원을 참조하십시오.Auto Scaling 그룹에서 시작한 모든 새 인스턴스에서 IMDSv2를 사용해야 하는 경우 Auto Scaling 그룹에서 시작 템플릿 또는 시작 구성을 사용할 수 있습니다. 시작 템플릿을 생성하거나 시작 구성을 생성할 때 IMDSv2를 반드시 사용하도록 MetadataOptions 파라미터를 구성해야 합니다. Auto Scaling 그룹은 새 시작 템플릿 또는 시작 구성을 사용하여 새 인스턴스를 시작하지만 기존 인스턴스는 영향을 받지 않습니다. Auto Scaling 그룹의 기존 인스턴스의 경우 ModifyInstanceMetadataOptions API를 사용하여 기존 인스턴스에서 IMDSv2를 사용하도록 요구하거나 인스턴스를 종료하면 Auto Scaling 그룹이 새 시작 템플릿 또는 시작 구성에 정의된 인스턴스 메타데이터 옵션 설정으로 새 대체 인스턴스를 시작합니다.
기본적으로 IMDSv2를 구성하는 AMI 사용
인스턴스를 시작할 때 v2.0으로 설정된 ImdsSupport 파라미터로 구성한 AMI로 인스턴스를 시작하여 기본적으로 IMDSv2를 사용하도록 인스턴스를 자동 구성할 수 있습니다(HttpTokens 파라미터는 required로 설정됨). register-image CLI 명령을 사용하여 AMI를 등록할 때 ImdsSupport 파라미터를 v2.0로 설정하거나 modify-image-attribute CLI 명령을 사용하여 기존 AMI를 수정할 수 있습니다. 자세한 내용은 AMI 구성 단원을 참조하십시오.
IAM 정책 및 SCP
IAM 정책 또는 AWS Organizations 서비스 제어 정책(SCP)을 사용하여 다음과 같이 사용자를 제어할 수 있습니다.인스턴스가 IMDSv2를 사용하도록 구성되어 있지 않으면 RunInstances API를 사용하여 인스턴스를 시작할 수 없습니다.IMDSv1을 다시 활성화하기 위해 ModifyInstanceMetadataOptions API를 사용하여 실행 중인 인스턴스를 수정할 수 없습니다.IAM 정책 또는 SCP에 다음 IAM 조건 키가 포함되어야 합니다.ec2:MetadataHttpEndpoint``ec2:MetadataHttpPutResponseHopLimit``ec2:MetadataHttpTokensAPI 또는 CLI 호출의 파라미터가 조건 키가 포함된 정책에 지정된 상태와 일치하지 않는 경우 API 또는 CLI 호출은 UnauthorizedOperation 응답과 함께 실패합니다.추가로, IMDSv1에서 IMDSv2로 변경을 시행하기 위한 추가 보호 계층을 선택할 수 있습니다. EC2 역할 자격 증명을 통해 호출되는 API에 관한 액세스 관리 계층에서는 IAM 정책 또는 AWS Organizations 서비스 제어 정책(SCP)에서 새 조건 키를 사용할 수 있습니다. 특히, IAM 정책에서 값이 ec2:RoleDelivery인 조건 키 2.0을 사용하여 IMDSv1에서 얻은 EC2 역할 자격 증명으로 API 호출을 수행하면 UnauthorizedOperation 응답이 수신됩니다. SCP에 따라 필요한 조건을 사용하여 동일한 작업을 더 광범위하게 수행할 수 있습니다. 이렇게 하면 지정된 조건에 맞지 않게 API를 호출할 경우 UnauthorizedOperation 오류가 수신되기 때문에 실제로 IMDSv1을 통해 제공된 자격 증명을 사용하여 API를 호출할 수 없습니다.예제 IAM 정책은 인스턴스 메타데이터 작업 섹션을 참조하세요. SCP에 대한 자세한 내용을 알아보려면 AWS Organizations 사용 설명서의 서비스 제어 정책(SCP)을 참조하세요.
위의 도구를 사용하여 이 경로를 따라 IMDSv2로 전환하는 것이 좋습니다.
EC2 인스턴스에서 역할 자격 증명을 사용하는 SDK, CLI 및 소프트웨어를 IMDSv2와 호환되는 버전으로 업데이트합니다. CLI 업데이트에 대한 자세한 내용은 AWS Command Line Interface 사용 설명서에서 최신 버전의 AWS CLI로 업그레이드를 참조하세요.
그런 다음, IMDSv2 요청을 사용하여 인스턴스 메타데이터에 직접 액세스하는(다시 말해서, SDK를 사용하지 않는) 소프트웨어를 변경합니다. IMDS 패킷 분석기로 IMDSv2 요청 사용을 위해 변경해야 하는 소프트웨어를 식별할 수 있습니다.
CloudWatch 지표 MetadataNoToken을 사용하여 전환 진행률을 추적합니다. 이 지표는 인스턴스에서 IMDS에 대한 IMDSv1 호출 수를 표시합니다. 자세한 내용은 인스턴스 지표 단원을 참조하십시오.
CloudWatch 지표 MetadataNoToken이 IMDSv1 사용량을 0으로 기록하면 인스턴스가 IMDSv2 사용으로 완전히 전환할 준비가 된 것입니다. 이 단계에서 다음 작업을 수행할 수 있습니다.
계정 기본값
IMDSv2를 반드시 계정 기본값으로 사용하도록 설정할 수 있습니다. 인스턴스가 시작되면 인스턴스 구성이 계정 기본값으로 자동 설정됩니다.
계정 기본값을 설정하려면 다음을 수행합니다.
--http-tokens required 및 --http-put-response-hop-limit 2를 지정합니다.새 인스턴스
새 인스턴스를 시작할 때 다음을 수행할 수 있습니다.
기존 인스턴스
기존 인스턴스의 경우 다음 작업을 수행할 수 있습니다.
실행 중인 인스턴스에서 인스턴스 메타데이터 옵션을 수정할 수 있으며 인스턴스 메타데이터 옵션을 수정한 후 인스턴스를 다시 시작할 필요가 없습니다.
인스턴스가 아직 IMDSv2를 사용하도록 구성되지 않았는지, 즉 IMDSv2가 여전히 optional로 구성되었는지 확인할 수 있습니다. 인스턴스가 여전히 optional로 구성된 경우 이전 3단계를 반복하여 인스턴스 메타데이터 옵션을 수정하여 IMDSv2 required를 만들 수 있습니다.
인스턴스를 필터링하려면 다음을 수행합니다.
Amazon EC2 콘솔: 인스턴스 페이지에서 IMDSv2 = 선택 사항 필터를 사용하여 인스턴스를 필터링합니다. 필터링에 대한 자세한 내용은 콘솔을 사용하여 리소스 필터링 섹션을 참조하세요. 또한 각 인스턴스에 대해 IMDSv2가 필수인지 선택 사항인지 확인할 수 있습니다. 기본 설정 창에서 IMDSv2를 켜서 IMDSv2 열을 인스턴스 테이블에 추가하세요.
AWS CLI: describe-instance CLI 명령을 사용하고 다음과 같이 metadata-options.http-tokens = optional로 필터링합니다.
aws ec2 describe-instances --filters "Name=metadata-options.http-tokens,Values=optional" --query "Reservations[*].Instances[*].[InstanceId]" --output text
ec2:MetadataHttpTokens, ec2:MetadataHttpPutResponseHopLimit, ec2:MetadataHttpEndpoint IAM 조건 키를 사용하여 RunInstances 및 ModifyInstanceMetadataOptions API와 해당 CLI 사용을 제어할 수 있습니다. 정책이 생성되고 API 호출의 파라미터가 조건 키를 사용하는 정책에 지정된 상태와 일치하지 않으면 API 또는 CLI 호출이 UnauthorizedOperation 응답과 함께 실패합니다. 예제 IAM 정책은 인스턴스 메타데이터 작업 섹션을 참조하세요.
또한 IMDSv1을 비활성화한 후 MetadataNoTokenRejected CloudWatch 지표를 사용하여 IMDSv1 직접 호출이 시도되었지만 거부된 횟수를 추적할 수 있습니다. IMDSv1을 비활성화한 후 소프트웨어가 제대로 작동하지 않고 MetadataNoTokenRejected 지표에서 IMDSv1 직접 호출을 기록하는 경우 IMDSv2를 사용하려면 이 소프트웨어를 업데이트해야 할 수 있습니다.
보안강화를 위해 IMDS v2만 사용하도록 아래의 CLI 명령어로 v1을 비활성화할 수 있다. (https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/configuring-instance-metadata-options.html)
aws ec2 modify-instance-metadata-options \
--region <region> \
--instance-id <instance-id> \
--http-tokens required \
--http-endpoint enabled
혹은 아래 예제와 같이 MetadataHttpTokens를 반드시 요구하는 IAM 정책을 이용해 v2를 사용하도록 강제할 수 있다.
{
"Version": "2012-10-17"
"Statement": [
{
"Effect": "Deny",
"Action": "<action_tag>"
"condition": {
"StringNotEquals": {
"ec2:MetadataHttpTokens": "required"
}
}
}
]
}
인스턴스 메타데이터는 몇 가지 범주로 분류될 수 있습니다. 인스턴스 메타데이터를 검색하려면 요청에서 카테고리를 지정하여 응답에서 메타데이터를 반환합니다.
새 카테고리가 릴리스되면 새 버전 번호로 새 인스턴스 메타데이터 빌드가 생성됩니다. 다음 표에서 카테고리가 릴리스된 버전(Version when category was released) 열은 인스턴스 메타데이터 카테고리가 릴리스될 때 빌드 버전을 지정합니다. Amazon EC2가 새 인스턴스 메타데이터 빌드를 릴리스할 때마다 코드를 업데이트하지 않으려면 메타데이터 요청에서 버전 번호 대신 latest를 사용하세요. 자세한 내용은 인스턴스 메타데이터의 사용 가능한 버전 가져오기 단원을 참조하십시오.
Amazon EC2에서 새 인스턴스 메타데이터 범주를 릴리스하면 새 범주에 대한 인스턴스 메타데이터를 기존 인스턴스에서 사용하지 못할 수 있습니다. 인스턴스는 Nitro 시스템을 기반으로 하므로, 시작 시 사용할 수 있었던 범주에 대해서만 인스턴스 메타데이터를 검색할 수 있습니다. Xen 하이퍼바이저가 있는 인스턴스의 경우 인스턴스를 중지한 후 시작하여 인스턴스에 사용 가능한 범주를 업데이트할 수 있습니다.
다음 표는 인스턴스 메타데이터의 카테고리를 목록으로 표시합니다. 범주 이름 중 일부에는 해당 인스턴스에만 있는 데이터 자리 표시자가 포함되어 있습니다. 예를 들어, mac은 네트워크 인터페이스의 MAC 주소를 나타냅니다. 인스턴스 메타데이터를 가져올 때 이 자리 표시자를 실제 값으로 바꿔야 합니다.
| 범주 | 설명 | 카테고리 릴리스 버전 |
|---|---|---|
ami-id | 인스턴스를 시작하기 위해 사용된 AMI ID. | 1.0 |
ami-launch-index | 동일한 RunInstances 호출을 사용하여 여러 인스턴스를 시작하는 경우 이 값은 각 인스턴스의 시작 순서를 나타냅니다. 첫 번째 인스턴스의 값은 0입니다. Auto Scaling 또는 EC2 플릿을 사용하여 인스턴스를 시작하는 경우 이 값은 항상 0입니다. | 1.0 |
ami-manifest-path | Amazon S3에 위치한 AMI 매니페스트 파일 경로. Amazon EBS 지원 AMI를 사용하여 인스턴스를 시작한 경우 반환되는 결과는 unknown입니다. | 1.0 |
ancestor-ami-ids | 이 AMI를 생성하기 위해 다시 번들링된 모든 인스턴스의 AMI ID. 이 값은 AMI 매니페스트 파일에 ancestor-amis 키가 있는 경우에만 존재합니다. | 2007-10-10 |
autoscaling/target-lifecycle-state | Auto Scaling 인스턴스가 전환 중인 대상 Auto Scaling 수명 주기 상태를 보여주는 값입니다. 2022년 3월 10일 이후에 인스턴스가 대상 수명 주기 상태 중 하나로 전환될 때 표시됩니다. 가능한 값은 Detached | InService |
block-device-mapping/ami | 루트/부트 파일 시스템을 포함하는 가상 디바이스. | 2007-12-15 |
block-device-mapping/ebsN | Amazon EBS 볼륨과 연결된 가상 디바이스입니다. Amazon EBS 볼륨은 시작 시 존재하는 경우 또는 인스턴스를 마지막으로 시작한 시점에만 메타데이터에서 사용할 수 있습니다. N은 Amazon EBS 볼륨의 색인을 나타냅니다(ebs1 또는 ebs2 등). | 2007-12-15 |
block-device-mapping/ephemeralN | 모든 비 NVMe 인스턴스 스토어 볼륨의 가상 디바이스입니다. N은 각 볼륨의 인덱스를 나타냅니다. 블록 디바이스 매핑에 있는 인스턴스 스토어 볼륨 수는 인스턴스에 대한 실제 인스턴스 스토어 볼륨 수와 일치하지 않을 수도 있습니다. 인스턴스 유형은 인스턴스에 사용 가능한 인스턴스 스토어 볼륨 수를 결정합니다. 블록 디바이스 매핑에 있는 인스턴스 스토어 볼륨 수가 인스턴스에 사용 가능한 수를 초과한 경우 추가 인스턴스 스토어 볼륨이 무시됩니다. | 2007-12-15 |
block-device-mapping/root | 루트 디바이스 또는 루트(/ 또는 C:) 파일 시스템이 특정 인스턴스와 연결된 경우 가상 디바이스의 파티션과 연결된 가상 디바이스 또는 파티션입니다. | 2007-12-15 |
block-device-mapping/swap | swap와 연결된 가상 디바이스. 항상 존재하는 것은 아님. | 2007-12-15 |
elastic-gpus/associations/elastic-gpu-id | 인스턴스에 연결된 탄력적 GPU가 있는 경우 탄력적 GPU에 대한 정보(해당 ID 및 연결 정보 포함)를 비롯한 JSON 문자열을 포함합니다. | 2016-11-30 |
elastic-inference/associations/eia-id | 인스턴스에 연결된 Elastic Inference 액셀러레이터가 있는 경우, Elastic Inference 액셀러레이터에 대한 정보(해당 ID 및 유형 포함)를 비롯한 JSON 문자열을 포함합니다. | 2018-11-29 |
events/maintenance/history | 인스턴스에 대해 완료되거나 취소한 유지 관리 이벤트가 있다면, 이벤트에 관한 정보가 있는 JSON 문자열이 포함됩니다. 자세한 내용은 완료되거나 취소된 이벤트에 대한 이벤트 기록 보기를 참조하세요. | 2018-08-17 |
events/maintenance/scheduled | 인스턴스에 대해 활성화된 유지 관리 이벤트가 있다면, 이벤트에 관한 정보가 있는 JSON 문자열이 포함됩니다. 자세한 내용은 예약된 이벤트 보기 섹션을 참조하세요. | 2018-08-17 |
events/recommendations/rebalance | 인스턴스에 대해 EC2 인스턴스 리밸런싱 권고 알림이 생성되는 대략적인 시간(UTC)입니다. 다음은 이 범주에 대한 메타데이터의 예입니다 {"noticeTime": "2020-11-05T08:22:00Z"}. 이 범주는 알림이 생성된 후에만 사용할 수 있습니다. 자세한 내용은 EC2 인스턴스 리밸런싱 권고 단원을 참조하십시오. | 2020-10-27 |
hostname | EC2 인스턴스가 IP 기반 이름 지정(IPBN)을 사용하는 경우 인스턴스의 프라이빗 IPv4 DNS 호스트 이름입니다. EC2 인스턴스가 리소스 기반 이름 지정(RBN)을 사용하는 경우 RBN입니다. 다중 네트워크 인터페이스가 존재하는 경우 eth0 디바이스를 의미함(디바이스 번호가 0인 디바이스). IPBN 및 RBN에 대한 자세한 내용은 Amazon EC2 인스턴스 호스트 이름 유형 섹션을 참조하세요. | 1.0 |
iam/info | 인스턴스 시작 시 IAM 역할이 연결되어 있을 경우, 인스턴스의 LastUpdated date, InstanceProfileArn 및 InstanceProfileId 등 마지막으로 인스턴스 프로파일이 업데이트된 시간 관련 정보를 포함합니다. 그렇지 않을 경우 제공되지 않습니다. | 2012-01-12 |
iam/security-credentials/role-name | 인스턴스 시작 시 IAM 역할이 연결되어 있을 경우 role-name은 역할 이름이고 role-name에는 이 역할과 연결된 임시 보안 자격 증명이 들어 있습니다(자세한 내용은 인스턴스 메타데이터에서 보안 자격 증명 검색 참조). 그렇지 않을 경우 제공되지 않습니다. | 2012-01-12 |
identity-credentials/ec2/info | identity-credentials/ec2/security-credentials/ec2-instance의 보안 인증에 대한 정보입니다. | 2018-05-23 |
identity-credentials/ec2/security-credentials/ec2-instance | 인스턴스 내 소프트웨어가 EC2 Instance Connect 및 AWS Systems Manager 기본 호스트 관리 구성과 같은 기능을 지원하기 위해 AWS에 자신을 식별할 수 있도록 하는 인스턴스 ID 역할에 대한 보안 인증 정보입니다. 이러한 자격 증명에는 정책이 연결되어 있지 않으므로 AWS 기능에 대한 인스턴스를 식별하는 것 외에는 추가 AWS API 권한이 없습니다. 자세한 내용은 인스턴스 ID 역할 단원을 참조하십시오. | 2018-05-23 |
instance-action | 번들링을 준비하기 위해 재부팅되어야 함을 인스턴스에 통지합니다. 유효한 값: none | shutdown \| bundle-pending. |
instance-id | 이 인스턴스의 ID. | 1.0 |
instance-life-cycle | 이 인스턴스의 구매 옵션입니다. 자세한 내용은 인스턴스 구입 옵션 섹션을 참조하세요. | 2019년 10월 1일 |
instance-type | 인스턴스 유형. 자세한 내용은 Amazon EC2 인스턴스 유형 섹션을 참조하세요. | 2007-08-29 |
ipv6 | 인스턴스의 IPv6 주소. 여러 네트워크 인터페이스가 있는 경우 이는 eth0 디바이스(디바이스 번호가 0인 디바이스) 네트워크 인터페이스와 할당된 첫 번째 IPv6 주소를 나타냅니다. 네트워크 인터페이스[0]에 IPv6 주소가 없으면 이 항목이 설정되지 않고 HTTP 404 응답이 발생합니다. | 2021-01-03 |
kernel-id | 이 인스턴스와 함께 시작한 커널 ID(해당하는 경우). | 2008-02-01 |
local-hostname | 다중 네트워크 인터페이스가 존재하는 경우 eth0 디바이스를 의미함(디바이스 번호가 0인 디바이스). EC2 인스턴스가 IP 기반 이름 지정(IPBN)을 사용하는 경우 인스턴스의 프라이빗 IPv4 DNS 호스트 이름입니다. EC2 인스턴스가 리소스 기반 이름 지정(RBN)을 사용하는 경우 RBN입니다. IPBN, RBN 및 EC2 인스턴스 이름 지정에 대한 자세한 내용은 Amazon EC2 인스턴스 호스트 이름 유형 섹션을 참조하세요. | 2007-01-19 |
local-ipv4 | 인스턴스의 프라이빗 IPv4 주소. 다중 네트워크 인터페이스가 존재하는 경우 eth0 디바이스를 의미함(디바이스 번호가 0인 디바이스). IPv6 전용 인스턴스인 경우 이 항목이 설정되지 않고 HTTP 404 응답이 발생합니다. | 1.0 |
mac | 인스턴스의 미디어 액세스 제어(MAC) 주소. 다중 네트워크 인터페이스가 존재하는 경우 eth0 디바이스를 의미함(디바이스 번호가 0인 디바이스). | 2011-01-01 |
metrics/vhostmd | 더 이상 사용할 수 없습니다. | 2011-05-01 |
network/interfaces/macs/mac/device-number | 해당 인터페이스와 연결된 고유한 디바이스 번호. 이 디바이스 번호는 디바이스 이름과 부합됩니다. 예를 들어 device-number 2는 eth2 디바이스의 번호입니다. 이 범주는 AWS CLI용 Amazon EC2 API 및 EC2 명령에서 사용하는 DeviceIndex 및 device-index 필드에 해당합니다. | 2011-01-01 |
network/interfaces/macs/mac/interface-id | 네트워크 인터페이스의 ID입니다. | 2011-01-01 |
network/interfaces/macs/mac/ipv4-associations/public-ip | 각 퍼블릭 IP 주소와 연결되고 해당 인터페이스에 할당된 프라이빗 IPv4 주소. | 2011-01-01 |
network/interfaces/macs/mac/ipv6s | 인터페이스에 할당된 IPv6 주소 | 2016-06-30 |
network/interfaces/macs/mac/ipv6-prefix | 네트워크 인터페이스에 할당된 IPv6 접두사 | |
network/interfaces/macs/mac/local-hostname | 인스턴스의 프라이빗 IPv4 DNS 호스트 이름. 다중 네트워크 인터페이스가 존재하는 경우 eth0 디바이스를 의미함(디바이스 번호가 0인 디바이스). IPv6 전용 인스턴스인 경우 리소스 기반 이름입니다. IPBN 및 RBN에 대한 자세한 내용은 Amazon EC2 인스턴스 호스트 이름 유형 섹션을 참조하세요. | 2007-01-19 |
network/interfaces/macs/mac/local-ipv4s | 프라이빗 IPv4 주소는 인터페이스와 연결됩니다. IPv6 전용 네트워크 인터페이스인 경우 이 항목이 설정되지 않고 HTTP 404 응답이 발생합니다. | 2011-01-01 |
network/interfaces/macs/mac/mac | 인스턴스의 MAC 주소. | 2011-01-01 |
network/interfaces/macs/mac/network-card | 네트워크 카드의 인덱스입니다. 일부 인스턴스 유형은 여러 네트워크 카드를 지원합니다. | 2020-11-01 |
network/interfaces/macs/mac/owner-id | 네트워크 인터페이스 소유자 ID. 다중 인터페이스 환경에서 인터페이스는 Elastic Load Balancing 등 타사 제품이 연결될 수 있습니다. 인터페이스 상의 트래픽은 항상 인터페이스 소유자에게 청구됩니다. | 2011-01-01 |
network/interfaces/macs/mac/public-hostname | 인터페이스의 퍼블릭 DNS(IPv4). 이 범주는 enableDnsHostnames 속성이 true로 설정된 경우에만 반환됩니다. 자세한 내용을 알아보려면 Amazon VPC 사용 설명서의 VPC에 대한 DNS 속성을 참조하세요. 인스턴스에 퍼블릭 IPv6 주소만 있고 퍼블릭 IPv4 주소가 없는 경우 이 항목이 설정되지 않고 HTTP 404 응답이 발생합니다. | 2011-01-01 |
network/interfaces/macs/mac/public-ipv4s | 인터페이스와 연결된 퍼블릭 IP 주소 또는 탄력적 IP 주소입니다. 인스턴스에는 다중 IPv4 주소가 있을 수 있습니다. | 2011-01-01 |
network/interfaces/macs/mac/security-groups | 네트워크 인터페이스에 속한 보안 그룹. | 2011-01-01 |
network/interfaces/macs/mac/security-group-ids | 네트워크 인터페이스에 속한 보안 그룹의 ID. | 2011-01-01 |
network/interfaces/macs/mac/subnet-id | 인터페이스가 위치하는 서브넷 ID. | 2011-01-01 |
network/interfaces/macs/mac/subnet-ipv4-cidr-block | 인터페이스가 위치하는 서브넷의 IPv4 CIDR 블록. | 2011-01-01 |
network/interfaces/macs/mac/subnet-ipv6-cidr-blocks | 인터페이스가 위치하는 서브넷의 IPv6 CIDR 블록. | 2016-06-30 |
network/interfaces/macs/mac/vpc-id | 인터페이스가 위치하는 VPC의 ID. | 2011-01-01 |
network/interfaces/macs/mac/vpc-ipv4-cidr-block | VPC의 기본 IPv4 CIDR 블록. | 2011-01-01 |
network/interfaces/macs/mac/vpc-ipv4-cidr-blocks | VPC에 대한 IPv4 CIDR 블록. | 2016-06-30 |
network/interfaces/macs/mac/vpc-ipv6-cidr-blocks | 인터페이스가 위치하는 VPC의 IPv6 CIDR 블록. | 2016-06-30 |
placement/availability-zone | 인스턴스가 시작된 가용 영역. | 2008-02-01 |
placement/availability-zone-id | 인스턴스가 시작된 정적 가용 영역 ID입니다. 가용 영역 ID는 계정 간에 일관성이 있습니다. 그러나 가용 영역과는 다를 수 있으며, 가용 영역은 계정에 따라 다를 수 있습니다. | 2019년 10월 1일 |
placement/group-name | 인스턴스가 시작된 배치 그룹의 이름입니다. | 2020-08-24 |
placement/host-id | 인스턴스가 시작된 호스트의 ID입니다. 전용 호스트에만 해당됩니다. | 2020-08-24 |
placement/partition-number | 인스턴스가 시작된 파티션의 번호입니다. | 2020-08-24 |
placement/region | 인스턴스가 시작된 AWS 리전입니다. | 2020-08-24 |
product-codes | AWS Marketplace인스턴스에 연결된 제품 코드(해당되는 경우). | 2007-03-01 |
public-hostname | 인스턴스의 퍼블릭 DNS(IPv4). 이 범주는 enableDnsHostnames 속성이 true로 설정된 경우에만 반환됩니다. 자세한 내용을 알아보려면 Amazon VPC 사용 설명서의 VPC에 대한 DNS 속성을 참조하세요. 인스턴스에 퍼블릭 IPv6 주소만 있고 퍼블릭 IPv4 주소가 없는 경우 이 항목이 설정되지 않고 HTTP 404 응답이 발생합니다. | 2007-01-19 |
public-ipv4 | 퍼블릭 IPv4 주소. 인스턴스와 탄력적 IP 주소가 연결된 경우 반환된 값은 탄력적 IP 주소입니다. | 2007-01-19 |
public-keys/0/openssh-key | 퍼블릭 키. 시작 시에 인스턴스가 제공된 경우에만 사용할 수 있습니다. | 1.0 |
ramdisk-id | 시작 시에 지정된 RAM의 ID(해당하는 경우). | 2007-10-10 |
reservation-id | 예약 ID: | 1.0 |
security-groups | 인스턴스에 적용된 보안 그룹의 이름.시작 이후 인스턴스의 보안 그룹을 변경할 수 있습니다. 해당 변경은 여기 및 network/interfaces/macs/mac/security-groups에 반영됩니다. | 1.0 |
services/domain | 리전의 AWS 리소스에 대한 도메인입니다. | 2014-02-25 |
services/partition | 리소스가 있는 파티션. 표준 AWS 리전에서 파티션은 aws입니다. 리소스가 다른 파티션에 있는 경우 파티션은 aws-partitionname입니다. 예를 들어 중국(베이징) 리전에 있는 리소스의 파티션은 aws-cn입니다. | 2015-10-20 |
spot/instance-action | 항목이 발생할 때 작업(최대 절전 모드, 중지 또는 종료)과 작업이 이루어지는 대략의 시간(UTC)입니다. 이 항목은 스팟 인스턴스가 최대 절전 모드, 중지, 종료로 표시된 경우에만 존재합니다. 자세한 내용은 instance-action 섹션을 참조하세요. | 2016-11-15 |
spot/termination-time | 스팟 인스턴스의 운영 체제가 종료 신호를 수신하는 UTC 기준 예상 시간. 스팟 인스턴스가 Amazon EC2의 종료 대상으로 표시된 경우에만 이 항목이 존재하고 시간 값(예: 2015-01-05T18:02:00Z)이 포함됩니다. 사용자가 스팟 인스턴스를 직접 종료한 경우 종료 시간 항목에 시간이 설정되지 않습니다. 자세한 내용은 termination-time 섹션을 참조하세요. | 2014-11-05 |
tags/instance | 인스턴스와 연결된 인스턴스 태그입니다. 인스턴스 메타데이터의 태그에 대한 액세스를 명시적으로 허용하는 경우에만 사용할 수 있습니다. 자세한 내용은 인스턴스 메타데이터의 태그에 대한 액세스 허용 단원을 참조하십시오. | 2021-03-23 |
다음 표는 동적 데이터의 카테고리를 목록으로 표시합니다.
| 범주 | 설명 | 카테고리 릴리스 버전 |
|---|---|---|
fws/instance-monitoring | 고객이 CloudWatch에서 1분 세부 모니터링을 설정했는지 보여주는 값. 유효한 값: `enabled | disabled` |
instance-identity/document | 인스턴스 ID, 프라이빗 IP 주소 등 인스턴스 속성을 포함하는 JSON. 인스턴스 자격 증명 문서 섹션을 참조하세요. | 2009-04-04 |
instance-identity/pkcs7 | 문서의 신뢰성 및 서명 내용을 검증하는 데 사용됩니다. 인스턴스 자격 증명 문서 섹션을 참조하세요. | 2009-04-04 |
instance-identity/signature | 출처 및 신뢰성을 검증하기 위해 다른 사용자가 사용할 수 있는 데이터. 인스턴스 자격 증명 문서 섹션을 참조하세요. | 2009-04-04 |
EC2에서 Security Credential 조회 테스트
[ec2-user@ip-172-16-0-50 ~]$ aws ec2 describe-instances --instance-ids i-0ae0a3971b51aba92 | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
[ec2-user@ip-172-16-0-50 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role-ec2-iac-dev-mgmt-instance-profile
{
"Code" : "Success",
"LastUpdated" : "2024-05-12T03:51:09Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "*****",
"SecretAccessKey" : "*****",
"Token" : "IQoJb3JpZ2luX2VjEOz//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIgOq2humSy6oHBfs75N62mlUfM1Yg1jfSxklKegApzVSgCIQCuGv....uQMI9yZQHLuFCVxt8i7BCtWVzvrFzMnGGijYe/lmt7AuJrPxjRNQg02lToIdUQ0vhSBh/ZFzppQ5+PXFb1CP1D8DGedE/U0MmlqEVM8wmxQDDF+YCyBjqxAdxoCZ+kUCG9+DWJ4HVRGiSL6+Htqm/Fkd1YUl7jK+RDQX7F643qyHGtACiMJcqmfMXtqCUQGbVpaplFyPjKeZ3Ab22cSikPrEAzQ6ic9j1OdA7ogWvJtoX/sQjoOWUWQIdBBcuhmsWavBOdiksHOhH6OGDiCrbkjIqP7oqAH8jCkp9vs/GtI9jRDxrYTR1bZhpsdWvzCKpu6mJu/jquywWqaT6yMjOieN7yPad3UWgYPw==",
"Expiration" : "2024-05-12T10:26:33Z"
}
## Instance에 매핑되지 않은 Role은 조회 불가
[ec2-user@ip-172-16-0-50 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/role-iac-dev-node
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
Docker에서 http-put-response-hop-limit 테스트 (--network host 있고/없고 && HttpPutResponseHomeLimit 1/2 차이비교)
i-0ae0a3971b51aba92
aws ec2 modify-instance-metadata-options \
--instance-id i-0ae0a3971b51aba92 \
--http-tokens=required \
--http-put-response-hop-limit 1 \
--http-endpoint enabled
{
"InstanceId": "i-0ae0a3971b51aba92",
"InstanceMetadataOptions": {
"State": "pending",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
}
aws ec2 describe-instances --instance-ids i-0ae0a3971b51aba92 | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
❯ aws ec2-instance-connect ssh --instance-id i-0ae0a3971b51aba92
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
echo "Install docker !!!"
sudo dnf install docker -y
docker -v
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker ec2-user
exit
## 오버레이 네트워크를 Host로 사용할 때는 메타데이터응답홉 영향을 받지 않음
❯ aws ec2-instance-connect ssh --instance-id i-0ae0a3971b51aba92
[ec2-user@ip-172-16-0-50 ~]$ docker run --rm -it --network host amazonlinux:2
bash-4.2# yum install awscli
Loaded plugins: ovl, priorities
Resolving Dependencies
--> Running transaction check
---> Package awscli.noarch 0:1.18.147-1.amzn2.0.2 will be installed
--> Processing Dependency: python2-botocore = 1.18.6 for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: PyYAML for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: groff-base for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: python-colorama for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: python-docutils for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: python-rsa for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Processing Dependency: python2-s3transfer for package: awscli-1.18.147-1.amzn2.0.2.noarch
--> Running transaction check
---> Package PyYAML.x86_64 0:3.10-11.amzn2.0.3 will be installed
--> Processing Dependency: libyaml-0.so.2()(64bit) for package: PyYAML-3.10-11.amzn2.0.3.x86_64
---> Package groff-base.x86_64 0:1.22.2-8.amzn2.0.2 will be installed
---> Package python-docutils.noarch 0:0.12-0.2.20140510svn7747.amzn2 will be installed
--> Processing Dependency: python-imaging for package: python-docutils-0.12-0.2.20140510svn7747.amzn2.noarch
---> Package python2-botocore.noarch 0:1.18.6-1.amzn2.0.3 will be installed
--> Processing Dependency: python-dateutil >= 1.4 for package: python2-botocore-1.18.6-1.amzn2.0.3.noarch
--> Processing Dependency: python-jmespath >= 0.9.3 for package: python2-botocore-1.18.6-1.amzn2.0.3.noarch
--> Processing Dependency: python2-urllib3 >= 1.20 for package: python2-botocore-1.18.6-1.amzn2.0.3.noarch
---> Package python2-colorama.noarch 0:0.3.9-3.amzn2.0.1 will be installed
---> Package python2-rsa.noarch 0:3.4.1-1.amzn2.0.4 will be installed
--> Processing Dependency: python-pyasn1 >= 0.1.3 for package: python2-rsa-3.4.1-1.amzn2.0.4.noarch
--> Processing Dependency: python-setuptools for package: python2-rsa-3.4.1-1.amzn2.0.4.noarch
---> Package python2-s3transfer.noarch 0:0.3.3-1.amzn2.0.1 will be installed
--> Processing Dependency: python-futures for package: python2-s3transfer-0.3.3-1.amzn2.0.1.noarch
--> Running transaction check
---> Package libyaml.x86_64 0:0.1.4-11.amzn2.0.2 will be installed
---> Package python-pillow.x86_64 0:2.0.0-23.gitd1c6db8.amzn2.0.12 will be installed
--> Processing Dependency: libjpeg.so.62(LIBJPEG_6.2)(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
--> Processing Dependency: libtiff.so.5(LIBTIFF_4.0)(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
--> Processing Dependency: libfreetype.so.6()(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
--> Processing Dependency: libjpeg.so.62()(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
--> Processing Dependency: libtiff.so.5()(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
--> Processing Dependency: libwebp.so.4()(64bit) for package: python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64
---> Package python-urllib3.noarch 0:1.25.9-1.amzn2.0.3 will be installed
--> Processing Dependency: python-backports-ssl_match_hostname for package: python-urllib3-1.25.9-1.amzn2.0.3.noarch
--> Processing Dependency: python-six for package: python-urllib3-1.25.9-1.amzn2.0.3.noarch
---> Package python2-dateutil.noarch 1:2.6.1-3.amzn2 will be installed
---> Package python2-futures.noarch 0:3.0.5-1.amzn2 will be installed
---> Package python2-jmespath.noarch 0:0.9.3-1.amzn2.0.2 will be installed
---> Package python2-pyasn1.noarch 0:0.1.9-7.amzn2.0.2 will be installed
---> Package python2-setuptools.noarch 0:41.2.0-4.amzn2.0.3 will be installed
--> Running transaction check
---> Package freetype.x86_64 0:2.8-14.amzn2.1.2 will be installed
--> Processing Dependency: libpng15.so.15(PNG15_0)(64bit) for package: freetype-2.8-14.amzn2.1.2.x86_64
--> Processing Dependency: libpng15.so.15()(64bit) for package: freetype-2.8-14.amzn2.1.2.x86_64
---> Package libjpeg-turbo.x86_64 0:2.0.90-2.amzn2.0.6 will be installed
---> Package libtiff.x86_64 0:4.0.3-35.amzn2.0.20 will be installed
--> Processing Dependency: libjbig.so.2.0()(64bit) for package: libtiff-4.0.3-35.amzn2.0.20.x86_64
---> Package libwebp.x86_64 0:0.3.0-10.amzn2.0.2 will be installed
---> Package python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.amzn2 will be installed
--> Processing Dependency: python-backports for package: python-backports-ssl_match_hostname-3.5.0.1-1.amzn2.noarch
--> Processing Dependency: python-ipaddress for package: python-backports-ssl_match_hostname-3.5.0.1-1.amzn2.noarch
---> Package python2-six.noarch 0:1.11.0-8.amzn2.0.1 will be installed
--> Running transaction check
---> Package jbigkit-libs.x86_64 0:2.0-11.amzn2.0.3 will be installed
---> Package libpng.x86_64 2:1.5.13-8.amzn2.0.5 will be installed
---> Package python-backports.x86_64 0:1.0-8.amzn2.0.2 will be installed
---> Package python-ipaddress.noarch 0:1.0.16-2.amzn2.0.2 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
======================================================================================================================================================================================================
Package Arch Version Repository Size
======================================================================================================================================================================================================
Installing:
awscli noarch 1.18.147-1.amzn2.0.2 amzn2-core 2.1 M
Installing for dependencies:
PyYAML x86_64 3.10-11.amzn2.0.3 amzn2-core 180 k
freetype x86_64 2.8-14.amzn2.1.2 amzn2-core 374 k
groff-base x86_64 1.22.2-8.amzn2.0.2 amzn2-core 948 k
jbigkit-libs x86_64 2.0-11.amzn2.0.3 amzn2-core 47 k
libjpeg-turbo x86_64 2.0.90-2.amzn2.0.6 amzn2-core 171 k
libpng x86_64 2:1.5.13-8.amzn2.0.5 amzn2-core 212 k
libtiff x86_64 4.0.3-35.amzn2.0.20 amzn2-core 176 k
libwebp x86_64 0.3.0-10.amzn2.0.2 amzn2-core 170 k
libyaml x86_64 0.1.4-11.amzn2.0.2 amzn2-core 53 k
python-backports x86_64 1.0-8.amzn2.0.2 amzn2-core 5.9 k
python-backports-ssl_match_hostname noarch 3.5.0.1-1.amzn2 amzn2-core 13 k
python-docutils noarch 0.12-0.2.20140510svn7747.amzn2 amzn2-core 1.5 M
python-ipaddress noarch 1.0.16-2.amzn2.0.2 amzn2-core 35 k
python-pillow x86_64 2.0.0-23.gitd1c6db8.amzn2.0.12 amzn2-core 446 k
python-urllib3 noarch 1.25.9-1.amzn2.0.3 amzn2-core 191 k
python2-botocore noarch 1.18.6-1.amzn2.0.3 amzn2-core 4.4 M
python2-colorama noarch 0.3.9-3.amzn2.0.1 amzn2-core 30 k
python2-dateutil noarch 1:2.6.1-3.amzn2 amzn2-core 251 k
python2-futures noarch 3.0.5-1.amzn2 amzn2-core 27 k
python2-jmespath noarch 0.9.3-1.amzn2.0.2 amzn2-core 42 k
python2-pyasn1 noarch 0.1.9-7.amzn2.0.2 amzn2-core 100 k
python2-rsa noarch 3.4.1-1.amzn2.0.4 amzn2-core 67 k
python2-s3transfer noarch 0.3.3-1.amzn2.0.1 amzn2-core 104 k
python2-setuptools noarch 41.2.0-4.amzn2.0.3 amzn2-core 658 k
python2-six noarch 1.11.0-8.amzn2.0.1 amzn2-core 33 k
Transaction Summary
======================================================================================================================================================================================================
Install 1 Package (+25 Dependent packages)
Total download size: 12 M
Installed size: 75 M
Is this ok [y/d/N]: y
Downloading packages:
(1/26): PyYAML-3.10-11.amzn2.0.3.x86_64.rpm | 180 kB 00:00:00
(2/26): freetype-2.8-14.amzn2.1.2.x86_64.rpm | 374 kB 00:00:00
(3/26): awscli-1.18.147-1.amzn2.0.2.noarch.rpm | 2.1 MB 00:00:00
(4/26): groff-base-1.22.2-8.amzn2.0.2.x86_64.rpm | 948 kB 00:00:00
(5/26): jbigkit-libs-2.0-11.amzn2.0.3.x86_64.rpm | 47 kB 00:00:00
(6/26): libjpeg-turbo-2.0.90-2.amzn2.0.6.x86_64.rpm | 171 kB 00:00:00
(7/26): libpng-1.5.13-8.amzn2.0.5.x86_64.rpm | 212 kB 00:00:00
(8/26): libtiff-4.0.3-35.amzn2.0.20.x86_64.rpm | 176 kB 00:00:00
(9/26): libwebp-0.3.0-10.amzn2.0.2.x86_64.rpm | 170 kB 00:00:00
(10/26): libyaml-0.1.4-11.amzn2.0.2.x86_64.rpm | 53 kB 00:00:00
(11/26): python-backports-1.0-8.amzn2.0.2.x86_64.rpm | 5.9 kB 00:00:00
(12/26): python-backports-ssl_match_hostname-3.5.0.1-1.amzn2.noarch.rpm | 13 kB 00:00:00
(13/26): python-ipaddress-1.0.16-2.amzn2.0.2.noarch.rpm | 35 kB 00:00:00
(14/26): python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64.rpm | 446 kB 00:00:00
(15/26): python-docutils-0.12-0.2.20140510svn7747.amzn2.noarch.rpm | 1.5 MB 00:00:00
(16/26): python-urllib3-1.25.9-1.amzn2.0.3.noarch.rpm | 191 kB 00:00:00
(17/26): python2-colorama-0.3.9-3.amzn2.0.1.noarch.rpm | 30 kB 00:00:00
(18/26): python2-dateutil-2.6.1-3.amzn2.noarch.rpm | 251 kB 00:00:00
(19/26): python2-futures-3.0.5-1.amzn2.noarch.rpm | 27 kB 00:00:00
(20/26): python2-jmespath-0.9.3-1.amzn2.0.2.noarch.rpm | 42 kB 00:00:00
(21/26): python2-pyasn1-0.1.9-7.amzn2.0.2.noarch.rpm | 100 kB 00:00:00
(22/26): python2-rsa-3.4.1-1.amzn2.0.4.noarch.rpm | 67 kB 00:00:00
(23/26): python2-botocore-1.18.6-1.amzn2.0.3.noarch.rpm | 4.4 MB 00:00:00
(24/26): python2-s3transfer-0.3.3-1.amzn2.0.1.noarch.rpm | 104 kB 00:00:00
(25/26): python2-six-1.11.0-8.amzn2.0.1.noarch.rpm | 33 kB 00:00:00
(26/26): python2-setuptools-41.2.0-4.amzn2.0.3.noarch.rpm | 658 kB 00:00:00
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 29 MB/s | 12 MB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : python2-six-1.11.0-8.amzn2.0.1.noarch 1/26
Installing : libjpeg-turbo-2.0.90-2.amzn2.0.6.x86_64 2/26
Installing : 1:python2-dateutil-2.6.1-3.amzn2.noarch 3/26
Installing : python2-jmespath-0.9.3-1.amzn2.0.2.noarch 4/26
Installing : groff-base-1.22.2-8.amzn2.0.2.x86_64 5/26
Installing : python2-futures-3.0.5-1.amzn2.noarch 6/26
Installing : libwebp-0.3.0-10.amzn2.0.2.x86_64 7/26
Installing : python2-pyasn1-0.1.9-7.amzn2.0.2.noarch 8/26
Installing : python-backports-1.0-8.amzn2.0.2.x86_64 9/26
Installing : libyaml-0.1.4-11.amzn2.0.2.x86_64 10/26
Installing : PyYAML-3.10-11.amzn2.0.3.x86_64 11/26
Installing : python2-colorama-0.3.9-3.amzn2.0.1.noarch 12/26
Installing : python-ipaddress-1.0.16-2.amzn2.0.2.noarch 13/26
Installing : python-backports-ssl_match_hostname-3.5.0.1-1.amzn2.noarch 14/26
Installing : python-urllib3-1.25.9-1.amzn2.0.3.noarch 15/26
Installing : jbigkit-libs-2.0-11.amzn2.0.3.x86_64 16/26
Installing : libtiff-4.0.3-35.amzn2.0.20.x86_64 17/26
Installing : 2:libpng-1.5.13-8.amzn2.0.5.x86_64 18/26
Installing : freetype-2.8-14.amzn2.1.2.x86_64 19/26
Installing : python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64 20/26
Installing : python-docutils-0.12-0.2.20140510svn7747.amzn2.noarch 21/26
Installing : python2-botocore-1.18.6-1.amzn2.0.3.noarch 22/26
Installing : python2-s3transfer-0.3.3-1.amzn2.0.1.noarch 23/26
Installing : python2-setuptools-41.2.0-4.amzn2.0.3.noarch 24/26
Installing : python2-rsa-3.4.1-1.amzn2.0.4.noarch 25/26
Installing : awscli-1.18.147-1.amzn2.0.2.noarch 26/26
Verifying : python-pillow-2.0.0-23.gitd1c6db8.amzn2.0.12.x86_64 1/26
Verifying : libjpeg-turbo-2.0.90-2.amzn2.0.6.x86_64 2/26
Verifying : python2-setuptools-41.2.0-4.amzn2.0.3.noarch 3/26
Verifying : 2:libpng-1.5.13-8.amzn2.0.5.x86_64 4/26
Verifying : jbigkit-libs-2.0-11.amzn2.0.3.x86_64 5/26
Verifying : python2-six-1.11.0-8.amzn2.0.1.noarch 6/26
Verifying : python-ipaddress-1.0.16-2.amzn2.0.2.noarch 7/26
Verifying : python2-s3transfer-0.3.3-1.amzn2.0.1.noarch 8/26
Verifying : python2-colorama-0.3.9-3.amzn2.0.1.noarch 9/26
Verifying : 1:python2-dateutil-2.6.1-3.amzn2.noarch 10/26
Verifying : awscli-1.18.147-1.amzn2.0.2.noarch 11/26
Verifying : libyaml-0.1.4-11.amzn2.0.2.x86_64 12/26
Verifying : python-backports-1.0-8.amzn2.0.2.x86_64 13/26
Verifying : python2-pyasn1-0.1.9-7.amzn2.0.2.noarch 14/26
Verifying : libwebp-0.3.0-10.amzn2.0.2.x86_64 15/26
Verifying : python-backports-ssl_match_hostname-3.5.0.1-1.amzn2.noarch 16/26
Verifying : python2-botocore-1.18.6-1.amzn2.0.3.noarch 17/26
Verifying : python-urllib3-1.25.9-1.amzn2.0.3.noarch 18/26
Verifying : libtiff-4.0.3-35.amzn2.0.20.x86_64 19/26
Verifying : python2-futures-3.0.5-1.amzn2.noarch 20/26
Verifying : freetype-2.8-14.amzn2.1.2.x86_64 21/26
Verifying : groff-base-1.22.2-8.amzn2.0.2.x86_64 22/26
Verifying : PyYAML-3.10-11.amzn2.0.3.x86_64 23/26
Verifying : python2-jmespath-0.9.3-1.amzn2.0.2.noarch 24/26
Verifying : python2-rsa-3.4.1-1.amzn2.0.4.noarch 25/26
Verifying : python-docutils-0.12-0.2.20140510svn7747.amzn2.noarch 26/26
Installed:
awscli.noarch 0:1.18.147-1.amzn2.0.2
Dependency Installed:
PyYAML.x86_64 0:3.10-11.amzn2.0.3 freetype.x86_64 0:2.8-14.amzn2.1.2 groff-base.x86_64 0:1.22.2-8.amzn2.0.2
jbigkit-libs.x86_64 0:2.0-11.amzn2.0.3 libjpeg-turbo.x86_64 0:2.0.90-2.amzn2.0.6 libpng.x86_64 2:1.5.13-8.amzn2.0.5
libtiff.x86_64 0:4.0.3-35.amzn2.0.20 libwebp.x86_64 0:0.3.0-10.amzn2.0.2 libyaml.x86_64 0:0.1.4-11.amzn2.0.2
python-backports.x86_64 0:1.0-8.amzn2.0.2 python-backports-ssl_match_hostname.noarch 0:3.5.0.1-1.amzn2 python-docutils.noarch 0:0.12-0.2.20140510svn7747.amzn2
python-ipaddress.noarch 0:1.0.16-2.amzn2.0.2 python-pillow.x86_64 0:2.0.0-23.gitd1c6db8.amzn2.0.12 python-urllib3.noarch 0:1.25.9-1.amzn2.0.3
python2-botocore.noarch 0:1.18.6-1.amzn2.0.3 python2-colorama.noarch 0:0.3.9-3.amzn2.0.1 python2-dateutil.noarch 1:2.6.1-3.amzn2
python2-futures.noarch 0:3.0.5-1.amzn2 python2-jmespath.noarch 0:0.9.3-1.amzn2.0.2 python2-pyasn1.noarch 0:0.1.9-7.amzn2.0.2
python2-rsa.noarch 0:3.4.1-1.amzn2.0.4 python2-s3transfer.noarch 0:0.3.3-1.amzn2.0.1 python2-setuptools.noarch 0:41.2.0-4.amzn2.0.3
python2-six.noarch 0:1.11.0-8.amzn2.0.1
Complete!
bash-4.2# curl -v http://169.254.169.254/latest/meta-data/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 06:28:07 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
bash-4.2# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 29582 0 --:--:-- --:--:-- --:--:-- 56000
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hibernation/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
managed-ssh-keys/
metrics/
network/
placement/
profile
public-keys/
reservation-id
security-groups
services/
## 그렇지만 일반적인 Overlay 네트워크를 사용할 때는 메타데이터응답홉 영향을 받게 됨
## HttpPutResponseHomeLimit 1일 경우 에러 발생
❯ aws ec2-instance-connect ssh --instance-id i-0ae0a3971b51aba92
[ec2-user@ip-172-16-0-50 ~]$ docker run --rm -it amazonlinux:2
bash-4.2# curl -v http://169.254.169.254/latest/meta-data/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 06:30:19 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
bash-4.2# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:02:02 --:--:-- 0
curl: (56) Recv failure: Connection reset by peer
bash-4.2# aws s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".
bash-4.2# aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-2
Default output format [None]:
bash-4.2# aws s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".
## HttpPutResponseHomeLimit 2로 변경 후
aws ec2 modify-instance-metadata-options \
--instance-id i-0ae0a3971b51aba92 \
--http-tokens=required \
--http-put-response-hop-limit 2 \
--http-endpoint enabled
{
"InstanceId": "i-0ae0a3971b51aba92",
"InstanceMetadataOptions": {
"State": "pending",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
}
❯ aws ec2 describe-instances --instance-ids i-0ae0a3971b51aba92 | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
bash-4.2# aws s3 ls
2022-01-09 03:14:06 aws-sam-cli-managed-default-samclisourcebucket-wjtvwvzrznlz
2021-12-15 14:08:49 cf-templates-1uab54z3d06kj-ap-northeast-2
bash-4.2# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 40846 0 --:--:-- --:--:-- --:--:-- 56000
bash-4.2#
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hibernation/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
managed-ssh-keys/
metrics/
network/
placement/
profile
public-keys/
reservation-id
security-groups
services/
EKS WorkerNode 테스트 - Pod에서는 HttpPutResponseHomeLimit이 2인 경우 테스트 정상
i-0f3e6cdc4169a023e
❯ aws ec2 describe-instances --instance-ids i-0f3e6cdc4169a023e | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
## Node 접속 후
[root@ip-172-16-0-38 /]# curl -v http://169.254.169.254/latest/meta-data/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 05:26:39 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
[root@ip-172-16-0-38 /]# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 10648 0 --:--:-- --:--:-- --:--:-- 11200
[root@ip-172-16-0-38 /]#
[root@ip-172-16-0-38 /]# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
autoscaling/
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-keys/
reservation-id
security-groups
services/
## Amazon Linux Pod 실행
❯ kubectl run imdstest --image amazonlinux:2 -it --rm
If you don't see a command prompt, try pressing enter.
bash-4.2# curl -v http://169.254.169.254/latest/meta-data/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 05:37:14 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
bash-4.2# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 26807 0 --:--:-- --:--:-- --:--:-- 28000
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
autoscaling/
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-keys/
reservation-id
security-groups
services/
bash-4.2# aws sts get-caller-identity --region ap-northeast-2
{
"Account": "123456789012",
"UserId": "AROAX2ZEYLDWSEN3HPLAW:i-0af452ba1a50957b6",
"Arn": "arn:aws:sts::123456789012:assumed-role/role-iac-dev-node/i-0af452ba1a50957b6"
}
## 다른 다른 Role의 Credential 조회불가 - 실패가 정상
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-ec2-iac-dev-mgmt-instance-profile
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>404 - Not Found</title>
</head>
<body>
<h1>404 - Not Found</h1>
</body>
</html>
## ## 토근 이용하여 IAM Role 메타 정보 조회됨
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-iac-dev-node/
{
"Code" : "Success",
"LastUpdated" : "2024-05-12T05:11:55Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "*****",
"SecretAccessKey" : "*****",
"Token" : "IQoJb3JpZ2luX2VjEO3//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIhANgZcod8j6W4PTrOAiUqYthiTRQ6ZRDeolJeUHXYJk1tAiBAusbabtdEJ6LDB2uE1R2wTz0SshkRV/uYCKqv+IGjYirKBQhWEAIaDDUzODU1ODYxNzgzNyIMBw6XRPtYzv7qUqX/KqcF0fCuCHC2V+QLgLl9iXuou......9BV3a2yrZzt9hWMLIj6sZ5F6SitWGIfATElZywQBBAc6slDKkYNGrpmT2ihL/XG9LFHEQeBqzmRZ5dCrATtK1WIH1pteI+USoAq7LRq0dPbDDonoGyBjqxAcV4kkmE8skvdonuuEqjmbQqzExQYX9tioLkkeIlXIkY/Efvp01eN6MPjOfxGRcgHO4Mfhu+7rlKktrifLEamMGn76IQOyCbH2bb/QKotedfGkM5Xpxg2/XcT38gVUcNFFDPHGMTMOXzVfUnLy5AoJQjhfNz4cOAgzhJbjpHufogfQBylg5VETLt8bBMmJ/+KS1TMm+KBmSc1jamS9akd0jRGejKqPQ6sjsAOvMm2bInjw==",
"Expiration" : "2024-05-12T11:17:50Z"
}
## 토근없이는 IAM Role 메타 정보 조회 불가
bash-4.2# curl -v http://169.254.169.254/latest/meta-data/iam/security-credentials/role-iac-dev-node/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/iam/security-credentials/role-iac-dev-node/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 05:42:35 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
EKS WorkerNode 테스트 - HttpPutResponseHomeLimit을 2에서 1로 변경 후 Pod에서 TOKEN 발급 및 aws api 호출 실패함
❯ aws ec2 modify-instance-metadata-options \
--instance-id i-0f3e6cdc4169a023e \
--http-tokens=required \
--http-put-response-hop-limit 1 \
--http-endpoint enabled
❯ aws ec2 describe-instances --instance-ids i-0f3e6cdc4169a023e | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
## HttpPutResponseHopLimit = 1 여도 조회 됨
bash-4.2# curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-iac-dev-node/
{
"Code" : "Success",
"LastUpdated" : "2024-05-12T05:11:55Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "*****",
"SecretAccessKey" : "*****",
"Token" : "IQoJb3JpZ2luX2VjEO3//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIhANgZcod8j6W4PTrOAiUqYthiTRQ6ZRDeolJeUHXYJk1tAiBAusbabtdEJ6LDB2uE1R2wTz0SshkRV/uYCKqv+IGjYirKBQhWEAIaDDUzODU1ODYxNzgzNyIMBw6XRPtYzv7qUqX/KqcF0fCuCHC2V+QLgLl9iXuouXQWVNeQ6Ka0CBlOvisyf7Bq1zmbGkZHkMs7rYO7uVVa9ASwKMm8EG/3/47E8rLuy/Zgeh6JueY/QvZhvdCVA4+BR53SCSeoYELwKEoOVCAU2q4WAo9sefgZHROtALbTrrmmvyLhxF9P7dkUs5VxHKfouK2mwe5bUWh0zE7UWLqaJTWgN6XKhL79G/MxzYlxiBANxNSVr5gYhidvr7rzAy7uVWyBJ32.../ATTGV/tPRah+awHa7EE+Z4pJ/jKPNbP2qdcRd9FU7zjSw60DfKUAtxxhPoQmTr6s6DvdUi6/0Z0mJDMMKITgE/rws/R0YqpNJhLCynOxnDMdIK9BV3a2yrZzt9hWMLIj6sZ5F6SitWGIfATElZywQBBAc6slDKkYNGrpmT2ihL/XG9LFHEQeBqzmRZ5dCrATtK1WIH1pteI+USoAq7LRq0dPbDDonoGyBjqxAcV4kkmE8skvdonuuEqjmbQqzExQYX9tioLkkeIlXIkY/Efvp01eN6MPjOfxGRcgHO4Mfhu+7rlKktrifLEamMGn76IQOyCbH2bb/QKotedfGkM5Xpxg2/XcT38gVUcNFFDPHGMTMOXzVfUnLy5AoJQjhfNz4cOAgzhJbjpHufogfQBylg5VETLt8bBMmJ/+KS1TMm+KBmSc1jamS9akd0jRGejKqPQ6sjsAOvMm2bInjw==",
"Expiration" : "2024-05-12T11:17:50Z"
}
bash-4.2# yum install awscli -y
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 56 100 56 0 0 26807 0 --:--:-- --:--:-- --:--:-- 28000
## Token 발행에 Timeout 발생 됨
bash-4.2# curl -v -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
* Trying 169.254.169.254:80...
* Connected to 169.254.169.254 (169.254.169.254) port 80
> GET /latest/meta-data/ HTTP/1.1
> Host: 169.254.169.254
> User-Agent: curl/8.3.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< Content-Length: 0
< Date: Sun, 12 May 2024 06:00:49 GMT
< Server: EC2ws
< Connection: close
< Content-Type: text/plain
<
* Closing connection
bash-4.2# TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:02:02 --:--:-- 0
curl: (56) Recv failure: Connection reset by peer
## HttpPutResponseHopLimit = 2로 조정 후 다시 테스트
aws ec2 modify-instance-metadata-options \
--instance-id i-0f3e6cdc4169a023e \
--http-tokens=required \
--http-put-response-hop-limit 2 \
--http-endpoint enabled
{
"InstanceId": "i-0f3e6cdc4169a023e",
"InstanceMetadataOptions": {
"State": "pending",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
}
❯ aws ec2 describe-instances --instance-ids i-0f3e6cdc4169a023e | jq -r ".Reservations[0].Instances[0].MetadataOptions"
{
"State": "applied",
"HttpTokens": "required",
"HttpPutResponseHopLimit": 2,
"HttpEndpoint": "enabled",
"HttpProtocolIpv6": "disabled",
"InstanceMetadataTags": "disabled"
}
bash-4.2# aws sts get-caller-identity
{
"Account": "123456789012",
"UserId": "AROAX2ZEYLDWSEN3HPLAW:i-0af452ba1a50957b6",
"Arn": "arn:aws:sts::123456789012:assumed-role/role-iac-dev-node/i-0af452ba1a50957b6"
}
bash-4.2# aws s3 ls
2022-01-09 03:14:06 aws-sam-cli-managed-default-samclisourcebucket-wjtvwvzrznlz
2021-12-15 14:08:49 cf-templates-1uab54z3d06kj-ap-northeast-2
2022-08-07 09:31:33 cf-templates-1uab54z3d06kj-us-east-1
인스턴스 메타데이터 및 사용자 데이터 https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
[AWS] EC2 Metadata 관련하여 https://bosungtea9416.tistory.com/entry/AWS-EC2-Metadata-%EA%B4%80%EB%A0%A8%ED%95%98%EC%97%AC
Transition to IMDSv2 on EC2 - Introduction, Preparation, Pitfalls https://www.youtube.com/watch?v=bi3bIs92xE0
Upgrading from AWS EC2 IMDSv1 to IMDSv2 https://medium.com/sai-ops/upgrading-from-aws-ec2-imdsv1-to-imdsv2-d96bbf4a2031
EC2 인스턴스 메타데이터 서비스의 향상된 기능을 통해 개방형 방화벽, 역방향 프록시 및 SSRF 취약성에 대한 심층적인 방어 기능을 추가하세요.