Study_note
[kubernetes]IRSA 및 OIDC, Serviceaccount, IAM workflow 본문
예전에 aws에서 주최하는 쿠버네티스 핸즈온 세션에서 여러 주제로 강의를 해준적 있었다.
그중 보안에 대한 이해가 부족하고 iam 권한 할당과 irsa의 권한 할당 workflow를 이해하지 못해 공부해본다.
우선 IAM 권한 할당 workflow
WorkFlow 및 구성
AWS-IAM-Authenticator
AWS IAM 자격 증명을 사용하여 Kubernetes 클러스터에 인증하는 도구로 쿠버네티스의 RBAC 권한을 AWS IAM을 통해 제어할 수 있도록 해주는 도구이다 ( EKS에서는 자동으로 내장되어 있음 )
Client
사용자가 요청을 보내면 AWS-IAM-Authenticator Client가 AWS sts:GetCallerIdentity API endpoint에 대한 요청을 생성하고 요청에 대하여pre-sign url을 설정한 후 요청을 쿠버네티스 인증 시스템을 통과할 수 있는 토큰으로 직렬화해준다.
Server
AWS-IAM-Authenticator Server
AWS-IAM-Authenticator Client에서 받은 토큰은 Kubernetes API 서버를 통해 웹 후크 구성으로 AWS-IAM-Authenticator Server의 /authenticate 엔드포인트로 전달됩니다.
AWS-IAM-Authenticator Server는 pre-sign된 요청의 모든 매게 변수를 확인하여 이상한 내용이 없는지 확인합니다.
그런 다움 요청을 실제 aws sts에 제출하여 Client에서 pre-sign된 요청을 확인하고 사용자에 대한 정보를 반환한다.
server가 client의 AWS Cluster ID를 알고 있으므로 간단한 정적 매핑을 통해 이 ID를 Kubernetes 사용자 및 그룹으로 변환
AWS STS
AWS 리소스에 대한 액세스를 제어할 수 있는 임시 보안 자격 증명을 생성하여 신뢰받는 사용자에게 제공
AWS-Auth = Config Map
AWS-IAM-Authenticator Server에 의해 사용 설정 되는 인증자들은 AWS-Auth = Config Map에서 구성 정보를 확인하고 가져옵니다.
Cluster ID
하나의 Authenticator server가 클라이언트의 토큰을 사용하여 다른 클러스터의 다른 Authenticator 서버에 인증하는 것을 방지
즉 정리 해보자면
1. 사용자가 kubectl로 api를 호출하면서 액션
2. AWS-IAM-Authenticator Client가 그 액션에 대한 AWS sts:GetCallerIdentity API endpoint 요청을 생성하고 pre-sign url을 설정하고 인증 시스템을 통과할 수 있는 토큰으로 직렬화
3. Client에서 받은 토큰은 Kubernetes API 서버를 통해 웹 후크 구성으로 AWS-IAM-Authenticator Server의 /authenticate 엔드포인트로 전달
4. Server는 pre-sign된 요청의 모든 매게 변수를 확인하여 이상한 내용이 없는지 확인
5. 확인된 요청을 실제 aws sts에 제출하여 Client에서 pre-sign된 요청을 확인
6. 리소스에 대한 액세스를 제어할 수 있는 임시 보안 자격 증명을 생성하여 사용자에게 반환
7. server가 요청을 확인하여 client의 Cluster ID를 알고 있으므로 간단한 정적 매핑을 통해 이 ID를 Kubernetes 사용자 및 그룹으로 변환
8. AWS-IAM-Authenticator에 의해 사용 설정 되는 인증자들은 AWS-Auth = Config Map에서 구성 정보를 확인 반환
9. kubernetes api는 sts한테 받은 임시 보안 자격 증명을 통해 RBAC 생성
https://github.com/kubernetes-sigs/aws-iam-authenticator
IRSA
IAM Role for Service Account의 약자로 Service Account에 iam 역할을 매핑하여 특정 리소스를 관리한다 생각
IRSA가 필요한 이유
kubernetes에서 제공하는 RBAC은 엔터티(user, group, service account)에 권한이 있는 Role과 바인딩하여 느슨한 연결 즉 간접적으로 권한을 부여하는 리소스이다.
RBAC은 Role과 Clusterrole이 있고 Role은 네임스페이스를 기준으로 권한을 부여 Clusterrole은 전체 클러스터에 권한을 부여한다.
하지만 이렇게 RBAC을 사용하여 Role과 Clusterrole에 권한을 부여하면 특정 리소스에만 권한을 부여 못하기 때문에 보안 취약성이 발생할 수 있다.
여기서 Service Account는 aws리소스가 아니기 때문에 OIDC를 통해 인증을 받고 iam 역할을 부여해야한다.
OIDC
OpenID Connect는 Google 등의 IdP(ID 공급자)에 로그인할 수 있도록 지원하는 표준 인증 프로토콜로 권한허가 프로토콜인 OAuth 2.0 기술을 이용하여 만들어진 인증 레이어로 OIDC를 사용하면 손쉽게 외부 서비스를 통해 사용자 인증을 구현할 수 있게 됩니다.
즉, Kunernetes의 리소스와 AWS 리소스 처럼 서로 다른 리소스간의 인증을 이 OIDC를 사용
간단하게 설명하면
사용자고 OIDC에 사용자 인증을 요청하면 OIDC는 IdP에게 OpenID(사용자 인증)를 요청하고 IdP는 사용자 신원 정보가 담긴 토큰(id_token, jwt 형식)을 제공한다.
사용자는 제공 받은 토큰(id_token, jwt 형식)을 가지고 쿠버네티스에 전송하고 쿠버네티스 API 서버는 전달 받은 토큰이 자신이 생성한 OAuth Client ID인지, 변조되진 않았는지 확인 후 인증을 마친다.
즉 아래에 업로드한 그림으로 IRSA를 받는 Workflow를 설명하면 아래와 같다.
-
- 진행전 service account와 service account에 IAM role을 사용하기 위해 해당 클러스터에 OIDC Provider, 사용할 iam 권한 생성
- eksctl를 통해 service account과 IAM role를 같이 생성(IRSA)하면서 생성했던 IAM 권한과 연결
- OIDC에 IRSA 대한 사용자 인증을 요청하면 OIDC는 IdP에게 OpenID를 요청하고 IdP는 사용자 신원 정보가 담긴 토큰(id_token, jwt 형식)을 제공
- 제공 받은 토큰이 있는 service account를 해당 pod의 할당
- pod위에서 동작하는 app이 AWS SDK를 사용하여 S3의 리스트를 가져오려고 할때 JWT와 IAM Role 의 ARN정보를 AWS STS에게 전달
- 정보를 받은 STS는 IAM에게 임시 자격증명을 줄 수 있는지 확인을 요청
- IAM은 IAM OIDC Provider와 통신하고, pod에 할당된 serviceaccount에 IAM Role 정보와 JWT가 잘 annotate되어 있는 지 변조되진 않았는지 확인 후에 IAM에게 확인 되었다는 응답
- IAM은 STS에게 권한을 줘도 된다고 응답
- AWS STS는 pod의 AWS SDK에게 임시 자격증명을 전달
- 최종적으로 pod의 AWS SDK는 aws s3의 리스트를 가져올 수 있게 된다
이 부분은 아래 있는 타 블로그 참조
OIDC 생성은 아래와 같다 (업로드 했던 Aws-alb-controller 생성 글에도 설명 있다)
# 우선 클러스터에 대한 IAM OIDC(OpenID Connect) identity Provider를 생성은 다음과 같다
eksctl utils associate-iam-oidc-provider \
--region ${AWS_REGION} \
--cluster (클러스터 이름) \
--approve
# 생성한 IAM OIDC 자격 증명 공급자는 IAM 콘솔 Identity providers 메뉴 혹은 아래의 명령어를 통해 확인할 수 있습니다.
# 먼저, 클러스터의 OIDC provider URL을 아래의 명령어들을 통해 확인합니다.
aws eks describe-cluster --name (클러스터 이름) --query "cluster.identity.oidc.issuer" --output text
# 명령어 결과 나오는 값은 아래와 같은 형식을 가지고 있습니다.
https://oidc.eks.ap-northeast-2.amazonaws.com/id/8A6E78112D7F1C4DC352B1B511DD13CF
# 위 의 결과 값에서 /id/ 뒤에 있는 값을 복사한 후, 아래와 같이 명령어를 수행합니다.
aws iam list-open-id-connect-providers | grep 8A6E78112D7F1C4DC352B1B511DD13CF
# 결과 값이 출력되면 IAM OIDC identity provider가 클러스터에 생성이 된 것이고, 아무 값도 나타나지 않으면 생성 작업을 수행해야 합니다.
참조
https://github.com/kubernetes-sigs/aws-iam-authenticator
https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-iam-permissions-namespaces/
https://coffeewhale.com/kubernetes/authentication/oidc/2020/05/04/auth03/
https://kim-dragon.tistory.com/279
글을 마치며 여러 블로그를 보고 공부한터라 부족한 부분이 있을 수 있으니 피드백은 댓글로 부탁드립니다.
'Kubernetes' 카테고리의 다른 글
[kubernetes] EFS를 POD에 동적 마운팅 (0) | 2022.11.30 |
---|---|
[kubernetes]AWS Secrets Manager를 통한 쿠버네티스 Secret관리 (0) | 2022.11.29 |
[kubernetes] Helm Override 및 Upgrade (0) | 2022.11.17 |
[kubernetes] Helm 및 chart 커스텀 (0) | 2022.11.16 |
[kubernetes] karpenter vs ca (0) | 2022.11.10 |