6주차 - EKS Security - IRSA & Pod Identity

728x90

 

 

EKS IRSA(IAM Roles for Service Accounts)

 

기존에는 Worker-Node 즉 EC2에 맵핑된 IAM Role를 Pod가 그대로 사용 할 수 있었다.

따라서 Pod가 탈취되면 그대로 EC2 IAM Role를 사용하여 보안적으로 취약할 수 있다.

 

이에 노드가 아닌 Pod에 최소한의 IAM 권한을 주는것이 IRSA이다.

 

 

실습  1 ( service account Token - false)

 

1. Pod 생성 시 Service Account Token이 자동 마운트 설정 해제

# 파드1 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test1
spec:
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      args: ['s3', 'ls']
  restartPolicy: Never
  automountServiceAccountToken: false
  terminationGracePeriodSeconds: 0
EOF

 

2. Pod에서 S3를 조회하는 명령어가 작동하는지 확인

# 확인
kubectl get pod
kubectl describe pod

# 로그 확인
kubectl logs eks-iam-test1

# 파드1 삭제
kubectl delete pod eks-iam-test1

 

 

실습  2 ( service account Token - True)

 

 

1. Pod 생성

# 파드2 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test2
spec:
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

 

2. Pod에서 Service Account Token 확인 및 S3를 조회하는 명령어가 작동하는지 확인

kubectl exec -it eks-iam-test2 -- ls /var/run/secrets/kubernetes.io/serviceaccount
kubectl exec -it eks-iam-test2 -- cat /var/run/secrets/kubernetes.io/serviceaccount/token ;echo

(yjsong@myeks:default) [root@myeks-bastion ~]# kubectl exec -it eks-iam-test2 -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt	namespace  token

# aws 서비스 사용 시도
kubectl exec -it eks-iam-test2 -- aws s3 ls
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

 

 

실습  3 ( IRSA)

초기 EKS 배포 시 iam 설정 내 withOIDC가 true로 설정되어 있어 IRSA를 사용 할 수 있음

 

1. IRSA 생성 - Service Account와 IAM Role ARN 맵핑

# Create an iamserviceaccount - AWS IAM role bound to a Kubernetes service account
eksctl create iamserviceaccount \
  --name my-sa \
  --namespace default \
  --cluster $CLUSTER_NAME \
  --approve \
  --attach-policy-arn $(aws iam list-policies --query 'Policies[?PolicyName==`AmazonS3ReadOnlyAccess`].Arn' --output text)

eksctl get iamserviceaccount --cluster $CLUSTER_NAME

 

2. IRSA 확인 (my-sa Service Account 생성 및 IAM Role 맵핑 확인)

eksctl get iamserviceaccount --cluster $CLUSTER_NAME

kubectl get sa
kubectl describe sa my-sa

 

3. Pod 생성 ( Pod 생성 시 my-sa Service Account 지정 )

# 파드3번 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-iam-test3
spec:
  serviceAccountName: my-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

# 해당 SA를 파드가 사용 시 mutatingwebhook으로 Env,Volume 추가함
kubectl get mutatingwebhookconfigurations pod-identity-webhook -o yaml | kubectl neat | yh

(yjsong@myeks:default) [root@myeks-bastion ~]# kubectl get pod eks-iam-test3 -o yaml | kubectl neat | yh
apiVersion: v1
kind: Pod
metadata: 
  name: eks-iam-test3
  namespace: default
spec: 
  containers: 
  - command: 
    - sleep
    - "36000"
    env: 
    - name: AWS_STS_REGIONAL_ENDPOINTS
      value: regional
    - name: AWS_DEFAULT_REGION
      value: ap-northeast-2
    - name: AWS_REGION
      value: ap-northeast-2
    - name: AWS_ROLE_ARN
      value: arn:aws:iam::590183955668:role/eksctl-myeks-addon-iamserviceaccount-default--Role1-WclIR9gNmGm7
    - name: AWS_WEB_IDENTITY_TOKEN_FILE
      value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
    image: amazon/aws-cli:latest
    name: my-aws-cli
    volumeMounts: 
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-rpzfw
      readOnly: true
    - mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
      name: aws-iam-token
      readOnly: true
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Never
  serviceAccountName: my-sa
  terminationGracePeriodSeconds: 0
  tolerations: 
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  volumes: 
  - name: aws-iam-token
    projected: 
      sources: 
      - serviceAccountToken: 
          audience: sts.amazonaws.com
          expirationSeconds: 86400
          path: token
  - name: kube-api-access-rpzfw
    projected: 
      sources: 
      - serviceAccountToken: 
          expirationSeconds: 3607
          path: token
      - configMap: 
          items: 
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI: 
          items: 
          - fieldRef: 
              fieldPath: metadata.namespace
            path: namespace

 

 

4. Pod에서 S3를 조회하는 명령어가 작동하는지 확인

kubectl exec -it eks-iam-test3 -- aws s3 ls

 

정리: 실습1, 실습2의 경우 Service Account 사용 또는 미사용과 상관없이 Pod가 S3에 대한 IAM Role이 없기 때문에 명령어를 사용하지 못하고 있다.

실습3경우 Service Account와 S3 IAM Role를 맵핑 후 해당 Service Account로 Pod를 생성하여 정상적으로 S3를 조회하는 것을 확인 할 수 있다. (IRSA)

 

 

EKS Pod Identity

 

IRSA의 경우, OIDC 앤드포인트가 공개( Public )으로 되어 있고, 신뢰 정책을 엄하게 설정하지 않으면 보안에 취약 할 수있음.

 

 

 

실습  -  "eks-pod-identity-agent 설치"

 

1. eks-pod-identity-agent 설치

#
ADDON=eks-pod-identity-agent
aws eks describe-addon-versions \
    --addon-name $ADDON \
    --kubernetes-version 1.28 \
    --query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \
    --output text
v1.2.0-eksbuild.1
True
v1.1.0-eksbuild.1
False
v1.0.0-eksbuild.1
False

aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name eks-pod-identity-agent
혹은
eksctl create addon --cluster $CLUSTER_NAME --name eks-pod-identity-agent --version 1.2.0

 

2. 확인

kubectl get ds -n kube-system eks-pod-identity-agent -o yaml | kubectl neat | yh

for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ss -tnlp | grep eks-pod-identit; echo "-----";done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c route; done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c -br -4 addr; done
for node in $N1 $N2 $N3; do ssh ec2-user@$node sudo ip -c addr; done

 

 

3. podidentityassociation 설정

eksctl create podidentityassociation \
--cluster $CLUSTER_NAME \
--namespace default \
--service-account-name s3-sa \
--role-name s3-eks-pod-identity-role \
--permission-policy-arns arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--region $AWS_REGION

# 확인
kubectl get sa
eksctl get podidentityassociation --cluster $CLUSTER_NAME

 

4. SA 생성 및  Pod 생성

kubectl create sa s3-sa

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: eks-pod-identity
spec:
  serviceAccountName: s3-sa
  containers:
    - name: my-aws-cli
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
  terminationGracePeriodSeconds: 0
EOF

 

5. 확인

kubectl get pod eks-pod-identity -o yaml | kubectl neat| yh
kubectl exec -it eks-pod-identity -- aws sts get-caller-identity --query Arn
kubectl exec -it eks-pod-identity -- aws s3 ls
kubectl exec -it eks-pod-identity -- env | grep AWS


# 토큰 정보 확인
kubectl exec -it eks-pod-identity -- ls /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/
kubectl exec -it eks-pod-identity -- cat /var/run/secrets/pods.eks.amazonaws.com/serviceaccount/eks-pod-identity-token

 

  • 고려사항 - 신규 기능이라 사용하기에는 많은 제약사항이 있음.
    • SDK 최신 버전
    • 워커노드에 IAM Policy 추가 - eks-auth:AssumeRoleForPodIdentity
    • 보안 솔루션으로 링크 로컬 주소 사용 가능 여부 확인

 

728x90