[AWS] AWS STS와 Assume Role을 통한 안전한 권한 관리 및 예시 (AWS CLI, Python boto3)

NewNewDaddy·2024년 2월 12일
0

AWS

목록 보기
11/13
post-thumbnail

🔹 0. INTRO

  • AWS CLI나 SDK를 통해 리소스에 접근할 때는 반드시 권한을 필요로 한다. 일반적으로 특정 권한이 부여된 유저가 Access keys를 생성하게되면 해당 Access key는 유저에게 부여된 권한과 동일하게 AWS 리소스들을 사용할 수 있다.
  • CLI의 경우 aws configure 명령을 통해 해당 Access key를 등록하고, Python SDK인 Boto3의 경우에는 특정 서비스에 대한 Client나 Resource 객체를 생성할 때 코드에 참조시켜준다.

📍 1. Access Key 발급

  • 하지만 이런식으로 영구적인 Access keys를 생성하여 등록 후 사용하는 것은 항상 한 가지의 위험성을 내포하고 있다. 그것은 바로 유출의 위험이다. 실수로 코드에 하드코딩을 해놓는다거나, 별도의 파일에 잘 보관해두었는데 git push 할 때 github에 그대로 올라간다거나 할 때는 해당 Key가 그대로 노출되어 다른 사람이 나의 AWS 리소스에 대한 자유로운 접근 권한이 생기게 된다. 물론 github이나 aws 내부적으로 이러한 경우에 Key를 사용할 수 없게 만든다거나, 즉시 알림을 준다거나하는 안전장치들이 있지만 100% 의 안전성을 보장해주지는 못한다.
  • 그래서 Access keys를 발급받아 사용하는 것은 편리하지만 항상 유출될 위험을 같이 안고있기 때문에 Best Usecase라고 보기는 힘들 것 같다.

📍 2. Assume Role 사용

  • 이러한 경우에 사용할 수 있는 것이 특정 권한을 일시적으로 빌려서 사용할 수 있도록 해주는 Assume Role이다. 이는 유저가 A 리소스에 대한 접근 권한이 없더라도 A 리소스 접근 Policy를 사용할 수 있는 임시 Token을 받아 특정 시간동안만 해당 권한을 행사할 수 있도록 하는 것이다.
  • 설명이 길어졌지만 표로 간단히 표현해보자면 아래와 같다.
  • AWS STS 라는 서비스를 통해 필요한 Role에 대한 임시 권한을 특정 시간동안 받아 User가 사용을 하는 것이다.
  • 이번 글에서는 S3 접근 권한 Role에 대한 Assume을 하는 방법들에 대해 다뤄볼 것이다.

🔹 1. User 및 Role 생성

  • User가 S3 Full Access 권한을 가진 Role을 Assume Role을 통해 임시적으로 사용할 수 있도록 할 것이다.

📍 1. User 생성

  • Assume Role을 하는 권한은 최소한 있어야 하기 때문에 유저 생성 후 STSassumeRoleFullAccess Policy 하나만 등록해준다.

📍 2. User Access Key 생성

  • User > Security credentials > Access keys 탭에서 해당 유저에 대한 Access key를 생성해준다.

📍 3. Role 생성

  • S3에 대한 Full Access 정책을 가진 Role을 생성해준다.

🔹 2. AWS CLI를 통한 권한 사용

📍 1. aws credential 등록

  • aws configure 명령을 통해 위에서 생성한 Access key를 등록해준다.
> aws configure

  AWS Access Key ID [****************ZP4G]: 
  AWS Secret Access Key [****************Jb0N]: 
  Default region name [ap-northeast-2]: 
  Default output format [None]: 
  • 등록한 Access key는 권한이 STSassumeRoleFullAccess 밖에 없기 때문에 S3 버킷 리스트를 조회하는 aws s3 ls 명령을 치면 아래와 같이 권한이 없다는 메세지가 나온다.
> aws s3 ls

  An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

📍 2. Role에 대한 임시 권한 획득

  • aws sts 서비스를 이용하여 assumeS3Full 역할에 대한 임시 권한을 획득한다.
aws sts assume-role \
--role-arn arn:aws:iam::1234567842:role/assumeS3Full \ # assumeS3Full Role에 대한 ARN
--role-session-name tempSession \ # assume role 이름
--duration-seconds 1000 \ # 유효 기간
  • 명령을 치면 아래와 같이 임시 Credentials값이 출력된다. AccessKeyId, SecretAccessKey, SessionToken 이 세 값을 aws configure에 등록해주면 해당 Key들로 assumeS3Full Role을 사용할 수 있다.
{
    "Credentials": {
        "AccessKeyId": "ASIAWQNYUB2T2HP5QUQA",
        "SecretAccessKey": "Rc7hmKiO2bwvVMiVxUTJPySf5EcchIxS+nD4hsd2",
        "SessionToken": "IQoJb3JpZ2luX2VjEIb//////////wEaDmFwLW5vcnRoZWFzdC0yIkcwRQIhAMDTXbJAYwP/T3QQRznAIAJ3cp78+S0rlMCXjdSAhKQ9AiBuZ8j+Ul5S78V3+9Dp9aoLPlKIdMQTLZ+hnNjmEn3I5SqYAghfEAEaDDQ0NzYwMDY2MDEzNSIMP94euOVuqYCJc162KvUB1SblMSvQt80kexKM8Z0rs/ZBOBpNPei26/2eyW40a0AYchbK2bdx7bQzbOrIMAOuyFX1qEY8Udp7irJ8MehqBd0MQ9L1aYTAZai2llkL/MHJmW1s2I12FGerJpjiwm1a1hM+FlJLvLAsvmXGRbrCYbNePiTHdqFhBSjl6m0Xc+dtKm9cFJ8i65GXe7Kq2dMW1pkEEr6cJDJzY5h+fswPfTzBub02RxhS9tGPO1gkeOFCFoAEG79GLl+9bW+Q3mm15iRt10widUQZFP/FAUxrWg7rmjCcnl+fh7tny7ReOQDoVQFIn6Pc86xLFCPnEiThoQzCWNowu9CorgY6nQGw6fjADladfRkr620wyTDGz1ZDsJLh6j64+CEvgprN374bNt8nw5mc6azRxKGtOfvuRrSeCpKlJqsxFfCSHFbVFcU5n+S5eaqfiD/mnxLEreuZDd3AadKItXX9GCdITWNGQNjkYg9PZORR5bV9jTJGVWnOze4NlfgI+AfJHBIuLvFd8qLkQS/O2aRDttxnRlljdraSQq+4MTTVLyuA",
        "Expiration": "2024-02-12T14:33:07+00:00"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAWQNYUB2TZNTIFO6PO:tempSession",
        "Arn": "arn:aws:sts::1234567842:assumed-role/assumeS3Full/tempSession"
    }
}

📍 3. aws configure에 등록

  • 임시로 발급받은 key 값들을 s3라는 profile 이름으로 등록해준다.
aws configure set --profile s3 aws_access_key_id [AccessKeyId]
aws configure set --profile s3 aws_secret_access_key [SecretAccessKey]
aws configure set --profile s3 aws_session_token [SessionToken]

📍 4. S3 버킷 조회

  • 이제 s3라는 profile로 aws cli 명령을 내려주면 S3 리소스 관련 명령이 잘 수행되는 것을 확인할 수 있다.
> aws s3 ls --profile s3

  2023-07-18 06:16:53 aws-athena-query-results-xxxxxxxxxxx
  2023-03-20 23:38:26 aws-cloudtrail-logs-xxxxxxxxxxx
  2023-11-30 14:12:57 aws-glue-assets-xxxxxxxxxxx
  2023-06-05 00:47:42 cdk-hnb659fds-assets-xxxxxxxxxxx
  2022-06-11 09:28:22 cdktoolkit-stagingbucket-xxxxxxxxxxx
  2021-04-25 07:53:24 cf-templates-1low35rftz23v-xxxxxxxxxxx

🔹 3. Boto3를 통한 권한 사용

  • Python Boto3 라이브러리를 통해 임시 Key를 발급받고 특정 profile에 해당 key들을 등록하는 코드이다.

📍 1. 임시 key 발급

import boto3
from pytz import timezone

# 함수 선언
def assume_role(
    role_arn, # 권한을 받으려는 Role에 대한 ARN
    role_session_name="TestRole", # assume role 이름
    duration_seconds=1000 # 유효기간
):
    sts_client = boto3.client('sts', region_name='ap-northeast-2')

    response = sts_client.assume_role(
        RoleArn=role_arn,
        RoleSessionName=role_session_name,
        DurationSeconds=duration_seconds,
    )

    credentials = response['Credentials']
    
    return {
        'AccessKeyId': credentials['AccessKeyId'],
        'SecretAccessKey': credentials['SecretAccessKey'],
        'SessionToken': credentials['SessionToken'],
        'Expiration': credentials['Expiration'].astimezone(timezone('Asia/Seoul')).strftime("%Y.%m.%d, %H:%M:%S")
    }

# 변수 선언
role_arn = "arn:aws:iam::1234567842:role/assumeS3Full"
role_name = "tempSession"
role_time = 1000

# 함수 실행
tempCred = assume_role(role_arn, role_name, role_time)

📍 2. User Profile에 발급 key 등록

  • CLI 예제와 동일하게 S3라는 이름의 Profile에 발급받은 임시 key 3종을 등록한다.
import subprocess

# 함수 선언
def configure_aws_profile(profile_name, access_key_id, secret_access_key, session_token):

    key_type = ['aws_access_key_id', 'aws_secret_access_key', 'aws_session_token']
    temp_key_list = [access_key_id, secret_access_key, session_token]
    
    [subprocess.run(['aws', 'configure', 'set', '--profile', profile_name, key_type[i], temp_key_list[i]]) for i in range(3)]

    print(f"AWS profile '{profile_name}' configured successfully.")

# 변수 선언
profile_name = "s3"
access_key_id = tempCred["AccessKeyId"]
secret_access_key = tempCred["SecretAccessKey"]
session_token = tempCred["SessionToken"]
region = "ap-northeast-2"

# 함수 실행
configure_aws_profile(profile_name, access_key_id, secret_access_key, session_token)
  • 함수 작동이 완료되면 선언한 profile name으로 권한에 대한 한시적 사용이 허용된다.

    aws s3 ls --profile s3

📍 3. Boto3를 통한 S3 목록 조회

  • 임시로 발급받은 세가지 Key들을 이용하여 s3 client를 생성하고 버킷 목록을 조회하는 코드이다.
import boto3

# 함수 선언
def list_s3_buckets(access_key_id, secret_access_key, session_token, region):

    # boto3 클라이언트 생성
    s3_client = boto3.client('s3',
                        aws_access_key_id=access_key_id,
                        aws_secret_access_key=secret_access_key,
                        aws_session_token=session_token,
                        region_name=region
                        )
    # 버킷 목록을 저장할 리스트 생성
    bucket_list = []

    # 버킷 목록 가져오기
    try:
        response = s3_client.list_buckets()
        # 가져온 버킷 목록 처리
        if 'Buckets' in response:
            for bucket in response['Buckets']:
                bucket_list.append(bucket['Name'])
        else:
            print("No buckets found")
    except Exception as e:
        print(f"An error occurred: {e}")

    return bucket_list

# 변수 선언
access_key_id = tempCred["AccessKeyId"]
secret_access_key = tempCred["SecretAccessKey"]
session_token = tempCred["SessionToken"]
region = "ap-northeast-2"

# 함수 실행
list_s3_buckets(access_key_id, secret_access_key, session_token, region)

🔹 4. OUTRO

  • assume role을 통해 특정 Role 권한을 임시로 부여받고 사용하는 것을 aws clipython boto3 두 가지 방법으로 다뤄보았다.
  • 나 또한 예전에 aws access key를 실수로 github에 올려두고 몇 분 후 허겁지겁 repo를 지우고 코드를 바꾸는 등의 대처를 한 경험이 있었는데 assume role을 사용한다면 이러한 걱정이 많이 없어지게 되는 것이 가장 큰 장점일 것이다.
  • 필요한 권한들을 Role로 세세하게 나누고 그때그때 필요한 역할을 임시적으로 위임받아 사용하는 flow를 잘만 구축해놓는다면 보안적으로 훌륭한 코드가 될 수 있을 것이라 생각한다.
profile
데이터 엔지니어의 작업공간 / #PYTHON #CLOUD #SPARK #AWS #GCP #NCLOUD

0개의 댓글