연재 시리즈

pkos 스터디 5주차 2편 - pod에서 인스턴스 메타데이터 접근 가능하면 생기는 위험

악분 2023. 4. 3. 18:22
반응형

5주차에서는 두 번째 주제는 pod에서 EC2 인스턴스 메타데이터를 사용가능하면 어떤 위험이 있는지 설명합니다.

 

사전지식

이 글은 EC2 인스턴스 메타데이터를 알고있다는 전제로 설명합니다. 제 블로그 이전 글에 인스턴스 메타데이터에 정리했습니다.

 

노드에서 인스턴스 메타데이터 조회하도록 설정

스터디에서 생성한 kops클러스터 기본 설정으로는 IMDS API호출이 불가능합니다. 그러므로 인스턴스 메타데이터도 조회하지 못합니다. 토큰을 발급하더라도 호출을 실패합니다.

 

IMDS API호출이 실패하는 이유는 httpPutResponseHopLimit설정이 1로 설정되어 있기 때문입니다. 네트워크 hop수만큼 httpPutResponseHopLimit를 설정해야하는데 기본으로 1로 설정되어 있습니다. 검증을 위해 한 워커노드에 해당하는 EC2 instnace설정을 수정했습니다. 업데이트 시간은약 5분정도 소요됩니다.

# kops edit ig nodes-ap-northeast-2a
---
# 아래 3줄 제거
spec:
  instanceMetadata:
    httpPutResponseHopLimit: 1
    httpTokens: required
---

# 업데이트 적용 : 노드1대 롤링업데이트
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster --yes

 

설정이 업데이트 된 워커노드에서 IMDS API를 사용하면 인스턴스 메타데이터를 잘 가져옵니다.

 

반면, 설정하지 않는 다른 노드는 IMDS API를 사용하지 못합니다.

 

POD에서 메타데이터 확인

인스턴스 메타데이터 API 노드 설정은 pod까지 영향이 갑니다. A노드는 API설정을 해제했으므로 A노드에 실행된 pod는 인스턴스 메타데이터를 조회할 수 있습니다. 하지만 B노드는 설정해제를 안했으므로 B노드에서 실행하는 POD도 인스턴스 메타데이터를 가져오지 못합니다.

 

몇 가지 테스트로 위 내용을 간단히 증명할 수 있습니다. 먼저 netshoot pod 2개를 생성합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot-pod
spec:
  replicas: 2
  selector:
    matchLabels:
      app: netshoot-pod
  template:
    metadata:
      labels:
        app: netshoot-pod
    spec:
      containers:
      - name: netshoot-pod
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0

 

그리고 각 pod가 원한는 노드에 실행되었는지 확인합니다.

kubectl get po -o wide

 

pod내부에서 IMDS API를 사용해볼게요. 아래 스크립트를 사용하면 모든 pod에서 IMDS API를 호출합니다.

# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})

# EC2 메타데이터 정보 확인
kubectl exec -it $PODNAME1 -- curl 169.254.169.254 ;echo
kubectl exec -it $PODNAME2 -- curl 169.254.169.254 ;echo

 

메타데이터 접근 가능시 생기는 위험

pod가 IMDS API 사용가능하다면 많은 위험에 노출됩니다. 해커가 pod를 해킹하는 순간 IMDS API를 사용하여 정보를 탈취할 수 있습니다. 또한 추가 해킹을 위해 AWS 리소스를 생성할 수 있습니다. 

 

공격 시나리오

해커가 pod내부 쉘을 접속했다고 가정합니다. 그리고 IMDS API를 사용하여 S3데이터를 조회해보겠습니다.

 

공격 원리

IMDS API를 사용하면 임시자격증명을 발급받을 수 있습니다. 이 내용은 AWS 공식문서에 친절히 설명되어 있습니다.

 

pod 설정 확인

pod에는 aws API를 쉽게 사용하기 위해 aws-cli가 설치되어 있습니다. 그리고 pod내부에는 aws인증정보가 설정되어 있지 않습니다. 

 

환경변수를 확인하면 AWS인증정보가 없습니다.

 

aws 프로파일도 없습니다.

 

AWS 설정 확인

테스트를 쉽게 하기위해 노드에 할당한 role에는 S3ReadonlyAccess policy를 추가했습니다.

 

공격

공식문서에서 설명한 API를 그대로 사용하면 임시자격증명이 발급됩니다.

curl 169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE 이름};

 

발급한 임시자격증명을 설정합니다. 설정방법도 AWS공식문서에 소개되어 있습니다. 제 유투브에서도 정리한 적 있습니다.

export AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
export AWS_SESSION_TOKEN=${AWS_SESSION_TOKEN}

 

그리고 S3 API를 사용해보세요. 잘 조회됩니다.

 

해결방법

pod가 IMDS API를 사용하지 않도록 제한하면 보안조치를 할 수 있습니다. 또한 노드에 할당한 Role은 최소한 권한만 사용하도록 제한해야 합니다.

 

IMDS API를 사용하고 싶다면 AWS IRSA를 사용하는 방법도 좋습니다. ISRA는 쿠버네티스 Service Account에 AWS IAM Role을 부여하는 방법입니다. 그러므로 각 pod마다 역할을 따로 설정하여 권한관리를 분리할 수 있습니다.

 

해결방법을 정리하면 아래와 같습니다.

- Role은 최소한 policy만 설정
- EC2 메타데이터 접속 제한
- AWS IRSA 사용

반응형