AEWS 6 WEEK

Hi yena·2023년 6월 1일

AEWS

목록 보기
6/8

EKS Security

[ EKS 인증/인가 ]

EKS 인증/인가?

동작 : 사용자/애플리케이션 → k8s 사용 시 ⇒ 인증은 AWS IAM, 인가는 K8S RBAC


(스터디원분중 박준희 님이 정리해주셨다)
핵심은 인증은 AWS IAM, 인가는 K8S RBAC에서 처리한다는 것

내용이 이해하기 좀 어려우니.. 반복해서 읽어보도록 해야겠다.


RBAC 관련 krew 플러그인 설치

kubectl krew install access-matrix rbac-tool rbac-view rolesum

RBAC Lookup by subject (user/group/serviceaccount) name


cluster role이 찾아보기 불편한데 플러그인 툴을 받아서 쉽게 찾아볼 수 있다
위 사진은 system:master라는 그룹이 어떤 scope인지, 연결된 role은 뭔지 표현해준다.

Shows the subject for the current context with which one authenticates with the cluster

A tool to visualize your RBAC permissions

kubectl rbac-view



요런 페이지 확인이 가능하다


인증/인가 완벽 분석 해보기


kubectl 명령 → aws eks get-token → EKS Service endpoint(STS)에 토큰 요청 ⇒ 응답값 디코드(Pre-Signed URL 이며 GetCallerIdentity..)

  1. STS에 토큰 발급요청

    aws api를 사용하는 user의 arn 정보(사용자 정보)
  • kubeconfig 정보 확인

    cat ~/.kube/config | yh

config에서 User exec 를 보면 인증 처리를 하는 부분이 보인다.
이전엔 툴을 설치하여 진행했지만 cli 1.16 버전 이후에는 내장되어 있다.

  • Get a token for authentication with an Amazon EKS cluster.
  • This can be used as an alternative to the aws-iam-authenticator.

    aws eks get-token help

  • 임시 보안 자격 증명(토큰)을 요청 : expirationTimestamp 시간경과 시 토큰 재발급됨

    aws eks get-token --cluster-name $CLUSTER_NAME | jq
    aws eks get-token --cluster-name $CLUSTER_NAME | jq -r '.status.token'

  1. Pre-Signed URL을 Bearer Token으로 EKS API Cluster Endpoint로 요청을 보냄

토큰값을 HS384 → HS256 순으로 디코드해본 후 payload값을 디코드해보면

이런 값을 볼 수 있다

  1. EKS API는 Token Review 를 Webhook token authenticator에 요청 ⇒ (STS GetCallerIdentity 호출) AWS IAM 해당 호출 인증 완료 후 User/Role에 대한 ARN 반환
  • 참고로 Webhook token authenticator 는 aws-iam-authenticator 를 사용한다.

  • tokenreviews api 리소스 확인


tokenreviews api 리소스를 보니 사용자에 대한 토큰 인증을 하는 역할이며 이것을 webhook token authentication으로 처리한다고 나와있음

  1. 이제 쿠버네티스 RBAC 인가를 처리합니다.
  • 해당 IAM User/Role 확인이 되면 k8s aws-auth configmap에서 mapping 정보를 확인하게 됩니다.
  • aws-auth 컨피그맵에 'IAM 사용자, 역할 arm, K8S 오브젝트' 로 권한 확인 후 k8s 인가 허가가 되면 최종적으로 동작 실행을 합니다.
  • 참고로 EKS를 생성한 IAM principal은 aws-auth 와 상관없이 kubernetes-admin Username으로 system:masters 그룹에 권한을 가짐

Webhook api 리소스 확인

kubectl api-resources | grep Webhook


사용자 인증을 쿠버네티스 api가 하지 않고 토큰리뷰로 aws iam으로 보냈는데
그때 동작하는것이 validationwebhook

validation은 통과할지 말지 판단. iam 사용자가 없으면 통과를 할 수 없음

validatingwebhookconfigurations 리소스 확인

kubectl get validatingwebhookconfigurations

aws-auth 컨피그맵 확인

kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh

aws-auth 컨피그맵 내 내용을 보면
mapRoles 쿠버네티스 eks를 사용하는 주체가 user 말고도 aws iam role도 가능하다
eks 관리형 노드가 최초 프로비저닝할때 eks 쿠버네티스 api를 사용해야함
그 때 사용하는 신원처리는 node에 있는 role로 함
kubernetes-admin은 공식적으로 감춰둠
왜냐하면 arn은 eks를 설치한 iam user, 이것을 날려버릴경우 복구가..불가능해서 이지 않을까(추정)


데브옵스 신입 사원을 위한 myeks-bastion-2에 설정 해보기


user 생성후 프로그래밍 방식 액세스 권한 부여

aws iam attach-user-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --user-name testuser

testuser 사용자에 정책을 추가

aws sts get-caller-identity --query Arn

get-caller-identity 확인


EC2 IP 확인 : myeks-bastion-EC2-2 PublicIPAdd 확인

[myeks-bastion-2] testuser 자격증명 설정 및 확인

get-caller-identity 확인

  • kubectl 시도 >> testuser도 AdministratorAccess 권한을 가지고 있는데, 실패 이유는? -> ./kube 파일에 인증정보가 없다

    kubectl get node -v6
    ls ~/.kube

[myeks-bastion] testuser에 system:masters 그룹 부여로 EKS 관리자 수준 권한 설정

방안1 : eksctl 사용 >> iamidentitymapping 실행 시 aws-auth 컨피그맵 작성해줌
  • Creates a mapping from IAM role or user to Kubernetes user and groups

    eksctl create iamidentitymapping --cluster CLUSTERNAMEusernametestusergroupsystem:mastersarnarn:aws:iam::CLUSTER_NAME --username testuser --group system:masters --arn arn:aws:iam::ACCOUNT_ID:user/testuser

auth configmap을 편집해주는 명령어다
teatuser를 쿠버네티스의 system:master에 매핑해줘
(user의 arn정보와 함께)

[myeks-bastion-2] testuser kubeconfig 생성 및 kubectl 사용 확인

  • testuser kubeconfig 생성

    kubectl 사용 확인
    kubectl ns default
    kubectl get node -v6

  • 첫번째 bastic ec2의 config와 비교

    cat ~/.kube/config | yh

  • kubectl 사용 확인

    kubectl ns default
    kubectl get node -v6

[myeks-bastion] testuser 의 Group 변경(system:masters → system:authenticated)으로 RBAC 동작 확인

  • 아래 edit로 mapUsers 내용 직접 수정 system:authenticated

    kubectl edit cm -n kube-system aws-auth



[myeks-bastion-2] testuser kubectl 사용 확인

kubectl get node -v6
kubectl api-resources -v5


차단됨..

[myeks-bastion]에서 testuser IAM 맵핑 삭제

testuser IAM 맵핑 삭제
eksctl delete iamidentitymapping --cluster CLUSTERNAMEarnarn:aws:iam::CLUSTER_NAME --arn arn:aws:iam::ACCOUNT_ID:user/testuser
Get IAM identity mapping(s)
eksctl get iamidentitymapping --cluster $CLUSTER_NAME
kubectl get cm -n kube-system aws-auth -o yaml | yh


5. OWASP Kubernetes Top Ten

mysql 배포

dvwa 배포

ingress 배포

..주기적으로 acm을 삭제해주고 실습을 하면 잘 됐는데
왜 안될까여ㅠㅠ..

ec2 가 가지고 있는 Iam role의 정보를 모두 확인할 수 있는 취약한 웹 사이트..
command injection 이니 삽입하고, 지우면서 조작해볼 수 있다


IRSA

  • EC2 Instance Profile : 사용하기 편하지만, 최소 권한 부여 원칙에 위배하며 보안상 권고하지 않음 → IRSA를 쓰시라
  • 동작 : k8s파드 → AWS 서비스 사용 시 ⇒ AWS STS/IAM ↔ IAM OIDC Identity Provider(EKS IdP) 인증/인가
    (ex. POD가 AWS 서비스를 쓰는 것)
  • RSA 소개 : 파드가 특정 IAM 역할로 Assume 할때 토큰을 AWS에 전송하고, AWS는 토큰과 EKS IdP를 통해 해당 IAM 역할을 사용할 수 있는지 검증

IRSA 실습

  • Configure a Pod to Use a Projected Volume for Storage : 시크릿 컨피그맵 downwardAPI serviceAccountToken의 볼륨 마운트를 하나의 디렉터리에 통합 - 링크
    • This page shows how to use a [projected](https://kubernetes.io/docs/concepts/storage/volumes/#projected) Volume to mount several existing volume sources into the same directory. Currently, secretconfigMapdownwardAPI, and serviceAccountToken volumes can be projected.
    • Note: serviceAccountToken is not a volume type.

Package these files into secrets:

kubectl create secret generic user --from-file=./username.txt
kubectl create secret generic pass --from-file=./password.txt

  • 파드 생성

projected volume을 쓰면 token의 만료기간과 audiance를 사용 가능하다


k8s api 접근 단계

  • AuthNAuthZAdmisstion Control 권한이 있는 사용자에 한해서 관리자(Admin)가 특정 행동을 제한(validate) 혹은 변경(mutate)
  • AuthN & AuthZ - MutatingWebhook - Object schema validation - ValidatingWebhook → etcd
  • Admission Control도 Webhook으로 사용자에게 API가 열려있고, 사용자는 자신만의 Admission Controller를 구현할 수 있으며,
    이를 Dynamic Admission Controller라고 부르고, 크게 MutatingWebhookValidatingWebhook 로 나뉩니다.
  • MutatingWebhook은 사용자가 요청한 request에 대해서 관리자가 임의로 값을 변경하는 작업입니다.
  • ValidatingWebhook은 사용자가 요청한 request에 대해서 관리자기 허용을 막는 작업입니다.
    (출처 AEWS notion)

OIDC OpenID Connect = OpenID 인증 + OAuth2.0 인가, JSON 포맷을 이용한 RESful API 형식으로 인증

- iss: 토큰 발행자
- sub: 사용자를 구분하기 위한 유니크한 구분자
- email: 사용자의 이메일
- iat: 토큰이 발행되는 시간을 Unix time으로 표기한 것
- exp: 토큰이 만료되는 시간을 Unix time으로 표기한 것
- aud: ID Token이 어떤 Client를 위해 발급된 것인지.

실습

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
EOF

서비스 어카운트 토큰 옵션을 끔(자동배포 옵션 off)


eks-iam-test1 pod error 임을 확인 가능


cloudtrail listbuckets 정보를 보면
accessdenied 오류코드 뱉는 것이 있다


실습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
EOF

pod2 생성

serviceaccount 옵션을 끄지 않아 volume이 생긴것을 확인 가능

모두 러닝중

aws 서비스 사용 시도

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


에러 .. 토큰정보를 쫒아가보면

토큰 oidc 프로바이더의 정보를 jwt 에서 확인 가능


실습3 https://github.com/aws/amazon-eks-pod-identity-webhook/ : This webhook is for mutating pods that will require AWS IAM access

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)

IRSA의 목적은 단 하나 pod가 aws 의 서비스를 사용하려고 할 때


IRSA 하나 셋팅할때마다 cloudformation에서 iam role을 만든다
매핑된 권한을 연결시켜주고
신뢰관계 형성

IAM 역할 (s3)

신뢰관계

federation 이 aws 입장에선 다른 인증기관
이 인증기관은 k8s의 OIDC 공급자 url 주소로 형성되어있다.

eksctl get iamserviceaccount --cluster $CLUSTER_NAME

awsloadbalancer pod가 저 role을 쓸 수 있다 이해할것


annotaion 확인

POD 에서 AWS CLI 사용 확인


👏🏻👏🏻👏🏻 ls 조회 성공

그런데

ec2는 나오지 않음 권한이 없기때문

** 파드에 볼륨 마운트 2개 확인

** aws-iam-token 볼륨 정보 확인 : JWT 토큰이 담겨져있고, exp, aud 속성이 추가되어 있음

0개의 댓글