ecsimsw

Vault Dynamic secret 으로 AWS 키를 보다 안전하게 관리하는 방법 본문

Vault Dynamic secret 으로 AWS 키를 보다 안전하게 관리하는 방법

JinHwan Kim 2023. 4. 25. 01:39

Dynamic secret

정적인 Secret은 위험하다. 사용자가 모두 같은 키 공유하기 때문에 하나의 키만 탈취당해도 모든 권한을 갖는다. 마찬가지로 하나의 키를 공유하여 여러 서비스가 사용하고 있기에 퇴사자가 생기거나 탈취 상황에서 키를 만료시키기 쉽지 않다. 극단적인 예로 하나의 AWS 키를 모든 개발자와 CI/CD agent가 사용하다가 퇴사자가 나쁜 마음을 먹고 키를 사용한다고 가정해 보자. 키를 revoke -> renew 하는 사이 시간 동안 모든 개발 작업, CI/CD 동작들이 멈출 것이다.

Dynamic secret은 미리 정의한 사용자 허가 범위에 따라 임시 키를 만들어 사용자에게 반환한다. 그 임시 키는 사용자마다 공통되지 않고, 만료 기간이 정의되어 있어 기간 외엔 사용할 수 없는 키가 되버린다. 또 관리자 측에서 임시 키의 권한을 빼앗을 수도 있다.

Vault의 Dynamic secret 요청과 생명 주기 시나리오는 다음과 같다.

 

1. 인증된 사용자가 Vault에 key 요청
2. Vault는 정의된 Role에 따라 허용된 액션, 만료 기간, 리소스 범위 확인
3. 허용된 액션, 만료 기간, 리소스 범위를 갖는 임시 키 생성
4. 사용자에 반환
5. 관리자 측에서 해당 키를 revoke 하거나 renew 할 수 있다.
6. 만료기한 이후엔 키 자동 삭제

 

AWS Dynamic secret

Vault는 AWS Dynamic secret 을 지원한다. 인증된 사용자가 원하는 role에 해당하는 키를 요청하면 Vault는 사용자가 요청한 role를 가질 권한이 있는지 확인한다. 권한이 있다면 role에 정의된 액션, 자원, 만료 기간을 바탕으로 임시 IAM user를 생성하여 access key를 반환한다. 만료 기간 전까지 해당 사용자는 반환받은 key를 이용하여 AWS에 접근하는 것으로 사용자에 마다 다른 임시 key, 사용자마다의 다른 권한, 만료 기간과 권한 뺏기가 가능해진다.

 


AWS vault root user 생성

Vault 임시 사용자를 만들어 access key를 반환할 수 있도록 하는 user를 생성한다. 이후에는 이 Vault가 사용할 User를 ‘AWS-Vault-Root-User’라고 말하겠다.

 


이 User는 임시 user를 생성하고 access키를 발급 받을 수 있어야 한다. 그러기 위해선 아래 IAM 권한들이 필요하다. 아래 rule로 policy를 만들어 AWS-Vault-Root-User에게 할당한다. 

 

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": [
            "iam:CreateUser",
            "iam:DeleteUser",
            "iam:CreateAccessKey",
            "iam:DeleteAccessKey",
            "iam:AttachUserPolicy",
            "iam:ListUserPolicies",
            "iam:TagUser",
            "iam:CreateAccessKey",
            "iam:CreateLoginProfile",
            "iam:RemoveUserFromGroup",
            "iam:AddUserToGroup",
            "iam:ListGroupsForUser",
            "iam:ListAttachedUserPolicies",
            "iam:PutUserPolicy",
            "iam:DetachUserPolicy",
            "iam:GetLoginProfile",
            "iam:DeleteLoginProfile",
            "iam:ListUserTags",
            "iam:ListAccessKeys",
            "iam:ListPolicies",
            "iam:ListRoles",
            "iam:ListUsers",
            "iam:ListGroups"
        ],
    "Resource": "*"
  }
}


정책은 Vault가 IAM 유저를 만들고 유저를 제거하고, Policy를 붙이고 만들 수 있다 등 임시 유저를 생성하고 정책을 붙이며, 기간이 만료되면 해당 임시 유저를 제거하는데 필요한 액션들을 허용한다. 

 

Resource는 예시에선 *으로 하였는데 꼭 본인 환경에 맞도록 임시 유저가 생성되고 사라질 리소스 범위를 구체적으로 적어줬으면 좋겠다.  

 

Vault Secret engine 

아래 명령어로 Vault에 AWS Secret engine 를 하나 추가한다. MY_PATH에는 이 secret engine이 위치할 논리 위치를 넣어주면 된다. 

 

vault secrets enable -path={MY_PATH} aws   

// ex
vault secrets enable -path=aws aws

 

Vault Root user 추가

Secret engine의 root user를 등록한다. Secret engine에 Secret을 요청하면 키를 준다. Dynamic secret은 이 키를 만들어 반환하기 위해 root가 필요하다. root user가 AWS에 임시 user를 생성하고 그 키를 반환하는 역할이다. 

 

앞서 생성한 ‘AWS-Vault-Root-User’를 Vault aws config root로 추가할 것이다. 

 

vault write ${AWS_SECRET_ENGINE}/config/root \
    access_key=${AWS-Vault-Root-User_ACCESS_KEY} \
    secret_key=${AWS-Vault-Root-User_SECRET_KEY}  \
    region=${REGION}

 

Success! Data written to: aws/config/root

 

Role 추가하기

Role을 정의한다. 사용자가 AWS 키를 요청하면 Vault는 이 role을 읽어 정의된 권한을 갖는 User를 반환한다. 

 

아래는 'ec2-temp-user'라는 이름으로 ec2 모든 자원의, 모든 액션을 허용하는 policy가 추가된 role을 생성한다. 만약 Vault에 인증한 유저가  이 'ec2-temp-user'의 role에 secret을 요청하면 Vault는 이 policy에 맞는 임시 유저를 만들어 반환하게 된다.

 

vault write ${AWS_SECRET_ENGINE}/roles/${NEW_ROLE_PATH} \
        credential_type=iam_user \ 
        ttl=10m \ 
        policy_document=-<<EOF         
{                        
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1426528957000",
      "Effect": "Allow",
      "Action": [
        "ec2:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
EOF

 

Success! Data written to: aws/roles/ec2-temp-user

 

Role에 키 요청

아래 vault 커멘드로 'ec2-temp-user'에 해당하는 임시 user를 생성하고 그 Access key를 반환 받을 수 있다. 

 

vault read ${AWS_SECRET_ENGINE}/creds/${ROLE_NAME}

 

물론 이를 요청하는 Vault user (Entity)에 해당 위치 키를 읽을 수 있는 권한이 있어야 한다. 만약 읽는데 문제가 있다면 1. Policy를 정의했는지, 2. Policy에 Secret path가 정의되어 있는지, 3. Policy에 read credentials가 정의되어 있는지, 4. 그 Policy가 인증한 유저에 적용이 되었는지 확인한다.

 

반환에 성공 시 응답 메시지는 다음과 같다. Default 값 한달로 만료기간이 제한되고 IAM policy 권한이 'ec2-temp-user' 의 권한과 같은 임시 키가 발행된 것이다.

 

Key                Value
---                -----
lease_id           aws/creds/ec2-temp-user/9rgHayCHqtFMhNvK0GyyGIlL
lease_duration     10m
lease_renewable    true
access_key         AKIA2X42PZNOCYHOJ36U
secret_key         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
security_token     <nil>

 

키 무효화 

아래 커멘드로 만료 기한 이전에도 키를 무효화할 수 있다. 

 

vault lease revoke ${AWS_SECRET_ENGINE}/creds/${ROLE_NAME}/${LEASE_ID}

 

All revocation operations queued successfully!

 

아래 코멘드로는 특정 role에서 생성된 유효한 임시 키를 모두 revoke 할 수 있다.

 

vault lease revoke -prefix vault lease revoke ${AWS_SECRET_ENGINE}/creds/${ROLE_NAME}

 

TIP : AWS IAM group으로 관리하기

AWS IAM에 임시 user가 생성된 것을 확인 할 수 있다. 

 

 

임시 User로 생성되는 User에 태깅과 Group 설정이 되면 유저 관리와 권한 관리에 더 좋을 것 같다. 

 

이번에는 AWS_Group 을 만들고 그 그룹 안에 Policy를 적용했다. 예를 들면 cicd 용 임시 키 발급에 사용되는 user라면 group을 'vault-cicd-temp-users'라고 만들고 필요한 policy를 그 그룹에 붙이는 것이다.

 

vault write ${AWS_SECRET_ENGINE}/roles/${ROLE_NAME} \
    iam_groups=${AWS_GROUP_NAME} \
    credential_type=iam_user

 

그럼 Role을 만들 때 앞선 Policy를 직접 정의하지 않아도 되는, 관리 가능한 임시 유저를 생성 할 수 있으면서 Group으로 관리되기에 IAM user를 확인하거나 한번에 작업하기에도 편하다.

 

Comments