AWES[1기](Amzaon EKS Study)

[AWES] 6주차 - EKS Security

Joon0464 2023. 6. 1. 20:30

1. K8S 인증/인가

  • 서비스 어카운트(Service Account)
  • API 서버 사용 : kubectl(config, 다수 클러스터 관리 가능), 서비스 어카운트, https(x.509 Client Certs)
  • API 서버 접근 과정 : 인증 → 인가 → Admission Control(API 요청 검증, 필요 시 변형 - 예. ResourceQuota, LimitRange)

인증(Authentication)

  • X.509 Client Certs : kubeconfig 에 CA crt(발급 기관 인증서) , Client crt(클라이언트 인증서) , Client key(클라이언트 개인키) 를 통해 인증
  • kubectl : 여러 클러스터(kubeconfig)를 관리 가능 - contexts 에 클러스터와 유저 및 인증서/ 참고
  • Service Account : 기본 서비스 어카운트(default) - 시크릿(CA crt 와 token)

 

인가(Authorization)

  • 인가 방식 : RBAC(Role, RoleBinding), ABAC, Webhook, Node Authorization
  • RBAC : 역할 기반의 권한 관리, 사용자와 역할을 별개로 선언 후 두가지를 조합(binding)해서 사용자에게 권한을 부여하여 kubectl or API로 관리 가능
    • Namespace/Cluster - Role/ClusterRole, RoleBinding/ClusterRoleBinding, Service Account
    • Role(롤) - (RoleBinding 롤 바인딩) - Service Account(서비스 어카운트) : 롤 바인딩은 롤과 서비스 어카운트를 연결
    • Role(네임스페이스내 자원의 권한) vs ClusterRole(클러스터 수준의 자원의 권한)

.kube/config 파일 내용

  • clusters : kubectl 이 사용할 쿠버네티스 API 서버의 접속 정보 목록. 원격의 쿠버네티스 API 서버의 주소를 추가해 사용 가능
  • users : 쿠버네티스의 API 서버에 접속하기 위한 사용자 인증 정보 목록. (서비스 어카운트의 토큰, 혹은 인증서의 데이터 등)
  • contexts : cluster 항목과 users 항목에 정의된 값을 조합해 최종적으로 사용할 쿠버네티스 클러스터의 정보(컨텍스트)를 설정.
    • 예를 들어 clusters 항목에 클러스터 A,B 가 정의돼 있고, users 항목에 사용자 a,b 가 정의돼 있다면 cluster A + user a 를 조합해, 'cluster A 에 user a 로 인증해 쿠버네티스를 사용한다' 라는 새로운 컨텍스트를 정의할 수 있습니다.
    • kubectl 을 사용하려면 여러 개의 컨텍스트 중 하나를 선택.
cat .kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EWXdNVEE0TlRNMU5sb1hEVE16TURVeU9UQTROVE0xTmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTFBlCmp3L3NNTXJpUForN1pZa1JPYWt6Z2IxTlY5aHA3WVMrYi9UZXpLUzFtYmxvUWVwN3E2STY5VmRLUzI3QWFUOTYKY0dKUlFPYVRFSllZV3FFSlpwelNjVVBNTUoxaHpCRk9mL0RBS1Y3YW4vVU9sNEE0eEJZekxZUWt0Um5zTHNCeQpqZEhkQms3Z3RPR2RKK3EySlRKRlA4bHhVb2thaEM4UjZTK09PODB5Wis4bjJPbGdOWDVkU2taVG50bTJEWU5NCi9sdnFBK0JhVCtNSlNOOTNvVTM2Y29EQjI0NVpjTHRSL3pQZFhUU1l6SDFyY3o4SVNjQlVyU29LV1pBSjljSSsKQVVKOVQvbHlNbldjZHR2SVhMNE1UdWwwM29mMFBKTTB1QldxNm1zdC9XNWpiN2VFWTc2bDJlWWFQRm84bTV6TgpSRHNCNWlmYW9GZzROakJCbFU4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIMmxpc3BBWEVWakEzYUtFQk1uaGZ1N3ZDRmRNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQk92d1kyNnBqcVRwRzU3K25qWgp2UUN6amZsQTZMS1dTa2lrVEd0S0M2NjBZQUJMZEpIUXNDdXVVdFF1ZkRQNmdYSmczQW5BL1VLbVhOV245YlljClorVGpRMWExc3YxWWNlT082NHBVTk9odDdGdlIzNzhla2pvemhyMmVlVWlTdXk2NUhnclFZM3BwUEc5OGMyd3kKNTNDRmdnZjhHMkcreWNQYkxlWURpd2NSTkM0L2pNWHU3bDhRZzBzZk05eXpRWU9lRm1WYzczdWgzL1VPZnZUTwplRERRZDlDOStzM20wUUJLUU1sUVMzdHpCZVJUTDlvUSs1WURjRndvb3UvVWRRNzcxa1gxdjNZZ1NBUXgyaHZkCjl4ZTZpRkRGZk81d1NxTjNNc3VreTdIcmFrdUFXTWEwMUhDYU0vQ0hNNlFYSTlJUWxaS0I1TmVTZTh2RjUxUTgKclMwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://13A850EA43233DC9B443EF2F494D7C0F.gr7.ap-northeast-2.eks.amazonaws.com
  name: myeks.ap-northeast-2.eksctl.io
contexts:
- context:
    cluster: myeks.ap-northeast-2.eksctl.io
    namespace: default
    user: thdguswns3@myeks.ap-northeast-2.eksctl.io
  name: JOON
current-context: JOON
kind: Config
preferences: {}
users:
- name: thdguswns3@myeks.ap-northeast-2.eksctl.io
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - eks
      - get-token
      - --output
      - json
      - --cluster-name
      - myeks
      - --region
      - ap-northeast-2
      command: aws
      env:
      - name: AWS_STS_REGIONAL_ENDPOINTS
        value: regional
      interactiveMode: IfAvailable
      provideClusterInfo: false

 

 

실습


실습환경

  • 쿠버네티스에 사용자를 위한 서비스 어카운트(Service Account, SA)를 생성 : dev-k8s, infra-k8s
  • 사용자는 각기 다른 권한(Role, 인가)을 가짐 : dev-k8s(dev-team 네임스페이스 내 모든 동작) , infra-k8s(dev-team 네임스페이스 내 모든 동작)
  • 각각 별도의 kubectl 파드를 생성하고, 해당 파드에 SA 를 지정하여 권한에 대한 테스트를 진행

 

네임스페이스와 서비스 어카운트 생성 후 확인

  • 파드 기동 시 서비스 어카운트 한 개가 할당되며, 서비스 어카운트 기반 인증/인가를 함, 미지정 시 기본 서비스 어카운트가 할당
  • 서비스 어카운트에 자동 생성된 시크릿에 저장된 토큰으로 쿠버네티스 API에 대한 인증 정보로 사용 할 수 있다 ← 1.23 이전 버전의 경우에만 해당
# 네임스페이스(Namespace, NS) 생성 및 확인
kubectl create namespace dev-team
kubectl create ns infra-team

# 네임스페이스 확인
kubectl get ns

# 네임스페이스에 각각 서비스 어카운트 생성 : serviceaccounts 약자(=sa)
kubectl create sa dev-k8s -n dev-team
kubectl create sa infra-k8s -n infra-team

# 서비스 어카운트 정보 확인
kubectl get sa -n dev-team
kubectl get sa dev-k8s -n dev-team -o yaml | yh

kubectl get sa -n infra-team
kubectl get sa infra-k8s -n infra-team -o yaml | yh

네임스페이스 생성 및 확인
서비스 어카운트 생성 및 확인

dev-k8s 서비스어카운트의 토큰 정보 확인 

https://coffeewhale.com/kubernetes/authentication/http-auth/2020/05/03/auth02/

# dev-k8s 서비스어카운트의 토큰 정보 확인 
DevTokenName=$(kubectl get sa dev-k8s -n dev-team -o jsonpath="{.secrets[0].name}")
DevToken=$(kubectl get secret -n dev-team $DevTokenName -o jsonpath="{.data.token}" | base64 -d)
echo $DevToken
  • 쿠버네티스에서 Bearer 토큰을 전송할 때 주로 JWT (JSON Web Token) 토큰을 사용
  • jwt(JSON Web Token)는 쿠버네티스에서 뿐만 아니라 다양한 웹 사이트에서 인증, 권한 허가, 세션관리 등의 목적으로 사용

 

서비스 어카운트를 지정하여 파드 생성 후 권한 테스트

https://kubetm.github.io/practice/intermediate/object-authentication/

# 각각 네임스피이스에 kubectl 파드 생성 - 컨테이너이미지
# docker run --rm --name kubectl -v /path/to/your/kube/config:/.kube/config bitnami/kubectl:latest
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: dev-kubectl
  namespace: dev-team
spec:
  serviceAccountName: dev-k8s
  containers:
  - name: kubectl-pod
    image: bitnami/kubectl:1.24.10
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: infra-kubectl
  namespace: infra-team
spec:
  serviceAccountName: infra-k8s
  containers:
  - name: kubectl-pod
    image: bitnami/kubectl:1.24.10
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF

# 확인
kubectl get pod -A
kubectl get pod -o dev-kubectl -n dev-team -o yaml
 serviceAccount: dev-k8s
 ...
kubectl get pod -o infra-kubectl -n infra-team -o yaml
 serviceAccount: infra-k8s
...

# 파드에 기본 적용되는 서비스 어카운트(토큰) 정보 확인
kubectl exec -it dev-kubectl -n dev-team -- ls /run/secrets/kubernetes.io/serviceaccount
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/token
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/namespace
kubectl exec -it dev-kubectl -n dev-team -- cat /run/secrets/kubernetes.io/serviceaccount/ca.crt

# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'

# 권한 테스트
k1 get pods # kubectl exec -it dev-kubectl -n dev-team -- kubectl get pods 와 동일한 실행 명령이다!
k1 run nginx --image nginx:1.20-alpine
k1 get pods -n kube-system

k2 get pods # kubectl exec -it infra-kubectl -n infra-team -- kubectl get pods 와 동일한 실행 명령이다!
k2 run nginx --image nginx:1.20-alpine
k2 get pods -n kube-system

# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
no

 

각각 네임스피이스에 kubectl 파드 생성 - 컨테이너이미지
확인
파드에 기본 적용되는 서비스 어카운트(토큰) 정보 확인
테스트 명령어 alias에 등록
두개의 파드 모두에서 권한이 부족하여 명령어가 수행되지 않는 것을 볼 수 있다.
권한을 확인해보면 불가능하다고 조회된다.

각각 네임스페이스에 롤(Role)를 생성 후 서비스 어카운트 바인딩

  • 롤(Role) : apiGroups 와 resources 로 지정된 리소스에 대해 verbs 권한을 인가
  • 실행 가능한 조작(verbs) : *(모두 처리), create(생성), delete(삭제), get(조회), list(목록조회), patch(일부업데이트), update(업데이트), watch(변경감시)

# 각각 네임스페이스내의 모든 권한에 대한 롤 생성
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role-dev-team
  namespace: dev-team
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
EOF

cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role-infra-team
  namespace: infra-team
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
EOF

# 롤 확인 
kubectl get roles -n dev-team
kubectl get roles -n infra-team
kubectl get roles -n dev-team -o yaml
kubectl describe roles role-dev-team -n dev-team
...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]

# 롤바인딩 생성 : '서비스어카운트 <-> 롤' 간 서로 연동
cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: roleB-dev-team
  namespace: dev-team
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: role-dev-team
subjects:
- kind: ServiceAccount
  name: dev-k8s
  namespace: dev-team
EOF

cat <<EOF | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: roleB-infra-team
  namespace: infra-team
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: role-infra-team
subjects:
- kind: ServiceAccount
  name: infra-k8s
  namespace: infra-team
EOF

# 롤바인딩 확인
kubectl get rolebindings -n dev-team
kubectl get rolebindings -n infra-team
kubectl get rolebindings -n dev-team -o yaml
kubectl describe rolebindings roleB-dev-team -n dev-team
...
Role:
  Kind:  Role
  Name:  role-dev-team
Subjects:
  Kind            Name     Namespace
  ----            ----     ---------
  ServiceAccount  dev-k8s  dev-team

 

role 생성

 

role 생성 확인
권한 확인
권한 확인

 

롤바인딩 생성 : '서비스어카운트 <-> 롤' 간 서로 연동
생성된 롤 바인딩 확
생성된 롤 바인딩 확인

 

 

서비스 어카운트를 지정하여 생성한 파드에서 다시 권한 테스트

# 각각 파드로 Shell 접속하여 정보 확인 : 단축 명령어(alias) 사용
alias k1='kubectl exec -it dev-kubectl -n dev-team -- kubectl'
alias k2='kubectl exec -it infra-kubectl -n infra-team -- kubectl'

# 권한 테스트
k1 get pods 
k1 run nginx --image nginx:1.20-alpine
k1 get pods
k1 delete pods nginx
k1 get pods -n kube-system
k1 get nodes

k2 get pods 
k2 run nginx --image nginx:1.20-alpine
k2 get pods
k2 delete pods nginx
k2 get pods -n kube-system
k2 get nodes

# (옵션) kubectl auth can-i 로 kubectl 실행 사용자가 특정 권한을 가졌는지 확인
k1 auth can-i get pods
yes

 

권한 테스트를 해보면 아까와 달리 각 네임스페이스 내에서 파드를 생성 조회 삭제가 가능하다. 단 kube-system 네임스페이스에서 조회를 해보면 파드가 조회되지 않는것을 볼 수 있다. 노드 정보도 마찬가
아까와 다르게 yes 출력

2. EKS 인증/인가

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

 

실습


# 설치
kubectl krew install access-matrix rbac-tool rbac-view rolesum

# Show an RBAC access matrix for server resources
kubectl access-matrix # Review access to cluster-scoped resources
kubectl access-matrix --namespace default # Review access to namespaced resources in 'default'

# RBAC Lookup by subject (user/group/serviceaccount) name
kubectl rbac-tool lookup
kubectl rbac-tool lookup system:masters
  SUBJECT        | SUBJECT TYPE | SCOPE       | NAMESPACE | ROLE
+----------------+--------------+-------------+-----------+---------------+
  system:masters | Group        | ClusterRole |           | cluster-admin

kubectl rbac-tool lookup system:nodes # eks:node-bootstrapper
kubectl rbac-tool lookup system:bootstrappers # eks:node-bootstrapper
kubectl describe ClusterRole eks:node-bootstrapper

# RBAC List Policy Rules For subject (user/group/serviceaccount) name
kubectl rbac-tool policy-rules
kubectl rbac-tool policy-rules -e '^system:.*'

# Generate ClusterRole with all available permissions from the target cluster
kubectl rbac-tool show

# Shows the subject for the current context with which one authenticates with the cluster
kubectl rbac-tool whoami
{Username: "kubernetes-admin",
 UID:      "aws-iam-authenticator:911283.....:AIDA5ILF2FJ......",
 Groups:   ["system:masters",
            "system:authenticated"],
 Extra:    {accessKeyId:  ["AKIA5ILF2FJ....."],
            arn:          ["arn:aws:iam::911283....:user/admin"],
            canonicalArn: ["arn:aws:iam::911283....:user/admin"],
            principalId:  ["AIDA5ILF2FJ....."],
            sessionName:  [""]}}

# Summarize RBAC roles for subjects : ServiceAccount(default), User, Group
kubectl rolesum -h
kubectl rolesum aws-node -n kube-system
kubectl rolesum -k User system:kube-proxy
kubectl rolesum -k Group system:masters

# [터미널1] A tool to visualize your RBAC permissions
kubectl rbac-view
INFO[0000] Getting K8s client
INFO[0000] serving RBAC View and http://localhost:8800

## 이후 해당 작업용PC 공인 IP:8800 웹 접속
echo -e "RBAC View Web http://$(curl -s ipinfo.io/ip):8800"

 

설치

 

권한 조회를 보다 쉽게 가
RBAC Lookup by subject (user/group/serviceaccount) name
RBAC List Policy Rules For subject (user/group/serviceaccount) name
Shows the subject for the current context with which one authenticates with the cluster
Summarize RBAC roles for subjects : ServiceAccount(default), User, Group

 

A tool to visualize your RBAC permissions

 

[터미널1] A tool to visualize your RBAC permissions

 

작업용PC 공인 IP:8800 웹 접속

 

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

https://docs.aws.amazon.com/eks/latest/userguide/cluster-auth.html
https://awskoreamarketingasset.s3.amazonaws.com/2022 Summit/pdf/T10S1_EKS 환경을 더 효율적으로 더 안전하게.pdf

 

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

# sts caller id의 ARN 확인
aws sts get-caller-identity --query Arn
"arn:aws:iam::<자신의 Account ID>:user/admin"

# kubeconfig 정보 확인
cat ~/.kube/config | yh
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJek1EWXdNVEE0TlRNMU5sb1hEVE16TURVeU9UQTROVE0xTmxvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTFBlCmp3L3NNTXJpUForN1pZa1JPYWt6Z2IxTlY5aHA3WVMrYi9UZXpLUzFtYmxvUWVwN3E2STY5VmRLUzI3QWFUOTYKY0dKUlFPYVRFSllZV3FFSlpwelNjVVBNTUoxaHpCRk9mL0RBS1Y3YW4vVU9sNEE0eEJZekxZUWt0Um5zTHNCeQpqZEhkQms3Z3RPR2RKK3EySlRKRlA4bHhVb2thaEM4UjZTK09PODB5Wis4bjJPbGdOWDVkU2taVG50bTJEWU5NCi9sdnFBK0JhVCtNSlNOOTNvVTM2Y29EQjI0NVpjTHRSL3pQZFhUU1l6SDFyY3o4SVNjQlVyU29LV1pBSjljSSsKQVVKOVQvbHlNbldjZHR2SVhMNE1UdWwwM29mMFBKTTB1QldxNm1zdC9XNWpiN2VFWTc2bDJlWWFQRm84bTV6TgpSRHNCNWlmYW9GZzROakJCbFU4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZIMmxpc3BBWEVWakEzYUtFQk1uaGZ1N3ZDRmRNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQk92d1kyNnBqcVRwRzU3K25qWgp2UUN6amZsQTZMS1dTa2lrVEd0S0M2NjBZQUJMZEpIUXNDdXVVdFF1ZkRQNmdYSmczQW5BL1VLbVhOV245YlljClorVGpRMWExc3YxWWNlT082NHBVTk9odDdGdlIzNzhla2pvemhyMmVlVWlTdXk2NUhnclFZM3BwUEc5OGMyd3kKNTNDRmdnZjhHMkcreWNQYkxlWURpd2NSTkM0L2pNWHU3bDhRZzBzZk05eXpRWU9lRm1WYzczdWgzL1VPZnZUTwplRERRZDlDOStzM20wUUJLUU1sUVMzdHpCZVJUTDlvUSs1WURjRndvb3UvVWRRNzcxa1gxdjNZZ1NBUXgyaHZkCjl4ZTZpRkRGZk81d1NxTjNNc3VreTdIcmFrdUFXTWEwMUhDYU0vQ0hNNlFYSTlJUWxaS0I1TmVTZTh2RjUxUTgKclMwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    server: https://13A850EA43233DC9B443EF2F494D7C0F.gr7.ap-northeast-2.eks.amazonaws.com
  name: myeks.ap-northeast-2.eksctl.io
contexts:
- context:
    cluster: myeks.ap-northeast-2.eksctl.io
    namespace: default
    user: thdguswns3@myeks.ap-northeast-2.eksctl.io
  name: JOON
current-context: JOON
kind: Config
preferences: {}
users:
- name: thdguswns3@myeks.ap-northeast-2.eksctl.io
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - eks
      - get-token
      - --output
      - json
      - --cluster-name
      - myeks
      - --region
      - ap-northeast-2
      command: aws
      env:
      - name: AWS_STS_REGIONAL_ENDPOINTS
        value: regional
      interactiveMode: IfAvailable
      provideClusterInfo: false

# 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'

 

임시 보안 자격 증명을 요청

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

해당 내용을 EKS 쿠버네티스 API에 bearer 에 담아서 요청 -> 일반적으로 AWS 구문과 비슷 

  • 토큰을 jwt 사이트에 복붙으로 디코드 정보 확인(HS384 → HS256) PAYLOAD 정보 확인 : 일반적인 AWS API 호출과 유사

jwt.io에서 디코드한다.
PAYLOAD의 값을 URL Decode Online 에서 DECODE로 확인

 

3. EKS API는 Token Review 를 Webhook token authenticator에 요청 
참고로 Webhook token authenticator 는 aws-iam-authenticator 를 사용한다.

# tokenreviews api 리소스 확인 
kubectl api-resources | grep authentication
tokenreviews                                   authentication.k8s.io/v1               false        TokenReview

# List the fields for supported resources.
kubectl explain tokenreviews
...
DESCRIPTION:
     TokenReview attempts to authenticate a token to a known user. Note:
     TokenReview requests may be cached by the webhook token authenticator
     plugin in the kube-apiserver.

 

4. 쿠버네티스 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
mutatingwebhookconfigurations                  admissionregistration.k8s.io/v1        false        MutatingWebhookConfiguration
validatingwebhookconfigurations                admissionregistration.k8s.io/v1        false        ValidatingWebhookConfiguration

# validatingwebhookconfigurations 리소스 확인
kubectl get validatingwebhookconfigurations
NAME                                        WEBHOOKS   AGE
eks-aws-auth-configmap-validation-webhook   1          50m
vpc-resource-validating-webhook             2          50m
aws-load-balancer-webhook                   3          8m27s

kubectl get validatingwebhookconfigurations eks-aws-auth-configmap-validation-webhook -o yaml | kubectl neat | yh

# aws-auth 컨피그맵 확인
kubectl get cm -n kube-system aws-auth -o yaml | kubectl neat | yh
apiVersion: v1
kind: ConfigMap
metadata: 
  name: aws-auth
  namespace: kube-system
data: 
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::91128.....:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-1OS1WSTV0YB9X
      username: system:node:{{EC2PrivateDNSName}}
#---<아래 생략(추정), ARN은 EKS를 설치한 IAM User , 여기 있었을경우 만약 실수로 삭제 시 복구가 가능했을까?---
  mapUsers: |
    - groups:
      - system:masters
      userarn: arn:aws:iam::111122223333:user/admin
      username: kubernetes-admin

# EKS 설치한 IAM User 정보 >> system:authenticated는 어떤 방식으로 추가가 되었는지 궁금???
kubectl rbac-tool whoami
{Username: "kubernetes-admin",
 UID:      "aws-iam-authenticator:9112834...:AIDA5ILF2FJIR2.....",
 Groups:   ["system:masters",
            "system:authenticated"],
...

# system:masters , system:authenticated 그룹의 정보 확인
kubectl rbac-tool lookup system:masters
kubectl rbac-tool lookup system:authenticated
kubectl rolesum -k Group system:masters
kubectl rolesum -k Group system:authenticated

# system:masters 그룹이 사용 가능한 클러스터 롤 확인 : cluster-admin
kubectl describe clusterrolebindings.rbac.authorization.k8s.io cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
Role:
  Kind:  ClusterRole
  Name:  cluster-admin
Subjects:
  Kind   Name            Namespace
  ----   ----            ---------
  Group  system:masters

# cluster-admin 의 PolicyRule 확인 : 모든 리소스  사용 가능!
kubectl describe clusterrole cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]

# system:authenticated 그룹이 사용 가능한 클러스터 롤 확인
kubectl describe ClusterRole system:discovery
kubectl describe ClusterRole system:public-info-viewer
kubectl describe ClusterRole system:basic-user
kubectl describe ClusterRole eks:podsecuritypolicy:privileged