data engineering

How to get temporary credential from ec2 iam role

qkqhxla1 2020. 4. 24. 17:50

배경 : 현재 access key와 secret key가 그냥 평문으로 박혀있습니다. 그런데 이게 보안적으로 위험해서 내가 필요한 권한을 가진 iam role을 가진 ec2에서 임시 credential을 가져와서 동작하도록 하고자 합니다.

 

대충 구성도를 그리면 이렇습니다.

 

1. 1번 ec2 즉 s3로 업로드할 수 있는 iam role을 가진 ec2를 생성합니다. 권한 가져오기 전용이므로 인스턴스는 가장 작은거로 적당하게 만듭니다.

 

2. 1번 ec2의 메타데이터를 가져와서 2번 ec2에서 사용해야 합니다. 1번 ec2에 인스턴스 메타데이터 서비스 구성을 해줘야 합니다. aws cli로 아래 구문을 실행해줍니다. instance-id는 1번 ec2의 instance-id로 설정합니다. 참고로 아래 aws콘솔을 실행시키려면 실행시키는 서버에서 권한이 있어야 합니다.

aws ec2 modify-instance-metadata-options \
    --instance-id i-1234567890abcdef0 \
    --http-tokens required \
    --http-endpoint enabled

아래처럼 결과가 나오면 성공입니다.

{
    "InstanceId": "i-1234567890abcdef0",
    "InstanceMetadataOptions": {
        "State": "pending",
        "HttpEndpoint": "enabled",
        "HttpTokens": "required",
        "HttpPutResponseHopLimit": 1
    }
}

3. 이제 1번 ec2에서 인스턴스 메타데이터 서비스 구성이 완료되었습니다. 인스턴스 메타데이터 검색을 참조합니다.

1번 ec2로 접속한 후 아래 구문을 실행시킵니다.

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/iam/security-credentials/

결과로 1번 ec2가 가지고 있는 iam role이름이 나오게 됩니다.

4. 그러면 다시 위의 구문의 끝에 iam role이름을 붙여서 실행시킵니다.

TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/iam-role-name

아래처럼 결과가 나오면 1번 ec2로부터 임시로 access key와 secret key를 가져오는데 성공했습니다.

{
  "Code" : "Success",
  "LastUpdated" : "2020-04-24T07:14:57Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "~~~~~",
  "SecretAccessKey" : "~~~~~",
  "Token" : "~~~~~~~",
  "Expiration" : "2020-04-24T13:39:30Z"
}

5. 이제 테스트해볼 차례입니다. 2번 ec2로 접속 후 1번 ec2에서 가져온 AccessKeyId와 SecretAccessKey, Token 3개를 가져와서 아래 코드에 넣고 실행시켜봅시다.

import boto3

access_key = '~~~~~~'
secret_access_key = '~~~~~'
token = '~~~~~'
s3 = boto3.client('s3',
                  aws_access_key_id=access_key,
                  aws_secret_access_key=secret_access_key,
                  aws_session_token=token,
                  )
print s3.list_objects(Bucket='pricing-naxos-s3')

6. 만약 결과가 잘 나온다면 권한이 없는 2번 ec2에서 s3로 접속을 잘 한게 되니 성공했다고 볼 수 있습니다.