반응형
Intro
aws iam user에 발급받은 Credentials key로 aws cli, python boto3, terraform를 사용할때 mfa를 사용하도록 강제로 설정 하려면 어떻게 해야할까요? 오늘은 그 방법에 대해 알아보도록 하겠습니다.
결론부터 말씀드리면 aws문서와 같이 매번 임시토큰을 생성 받고 aws credential key를 변경해야합니다.
https://aws.amazon.com/ko/premiumsupport/knowledge-center/authenticate-mfa-cli/
이 번거로운 과정을 자동화해주기 위해 쉘스크립트와 파이썬 코드를 사용할 수 있습니다.
MFA사용 강제 설정
IAM User Policy 설정
IAM User에 아래와 같이 policy설정을 하면 aws cli사용시 강제로 mfa를 사용할 수 있도록 설정할 수 있습니다.
- force_mfa_policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowViewAccountInfo",
"Effect": "Allow",
"Action": [
"iam:GetAccountPasswordPolicy",
"iam:GetAccountSummary",
"iam:ListVirtualMFADevices"
],
"Resource": "*"
},
{
"Sid": "AllowManageOwnPasswords",
"Effect": "Allow",
"Action": [
"iam:ChangePassword",
"iam:GetUser"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnSigningCertificates",
"Effect": "Allow",
"Action": [
"iam:DeleteSigningCertificate",
"iam:ListSigningCertificates",
"iam:UpdateSigningCertificate",
"iam:UploadSigningCertificate"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnSSHPublicKeys",
"Effect": "Allow",
"Action": [
"iam:DeleteSSHPublicKey",
"iam:GetSSHPublicKey",
"iam:ListSSHPublicKeys",
"iam:UpdateSSHPublicKey",
"iam:UploadSSHPublicKey"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnGitCredentials",
"Effect": "Allow",
"Action": [
"iam:CreateServiceSpecificCredential",
"iam:DeleteServiceSpecificCredential",
"iam:ListServiceSpecificCredentials",
"iam:ResetServiceSpecificCredential",
"iam:UpdateServiceSpecificCredential"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "AllowManageOwnVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice"
],
"Resource": "arn:aws:iam::*:mfa/${aws:username}"
},
{
"Sid": "AllowManageOwnUserMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::*:user/${aws:username}"
},
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:ChangePassword",
"iam:GetAccountPasswordPolicy",
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
]
}
MFA임시 토큰 설정 자동화
IAM MFA설정
- MFA설정 이후 mfa_arn 정보를 기억해두고 아래 aws credential파일안에
aws_arn_mfa
입력
AWS Credentials 설정
default
가 붙은 프로필이 MFA를 사용하는 프로필- 스크립트 실행을 통해 autogen 부분 값이 자동생성됨
[test]
aws_access_key_id = mykey
aws_secret_access_key = mykey
[dev-default]
aws_access_key_id = mykey
aws_secret_access_key = mykey
[prod-default]
aws_access_key_id = mykey
aws_secret_access_key = mykey
[dev]
aws_arn_mfa = arn:aws:iam::myaccount:mfa/myaccount
aws_access_key_id = autogen
aws_secret_access_key = autogen
aws_session_token = autogen
[prod]
aws_arn_mfa = arn:aws:iam::myaccount:mfa/myaccount
aws_access_key_id = autogen
aws_secret_access_key = autogen
aws_session_token = autogen
MFA설정 스크립트
awsp.sh
, mfa.py
이름으로 ~/.aws/
경로에 추가하고,
~/.zshrc
또는 ~/.bashrc
에 source ~/.aws/awsp.sh
를 추가
- awsp.sh
#! /bin/bash
setProfile() {
export AWS_PROFILE=$1
export AWS_DEFAULT_PROFILE=$1
python ~/.aws/mfa.py --profile $1 $2
}
alias awsp=setProfile
- mfa.py
import os
import json
import sys
import argparse
import subprocess
import configparser
parser = argparse.ArgumentParser(description='Update your AWS CLI Token')
parser.add_argument('token', help='token from your MFA device')
parser.add_argument('--profile', help='aws profile to store the session token', default=os.getenv('AWS_PROFILE'))
parser.add_argument('--arn', help='AWS ARN from the IAM console (Security credentials -> Assigned MFA device). This is saved to your .aws/credentials file')
parser.add_argument('--credential-path', help='path to the aws credentials file', default=os.path.expanduser('~/.aws/credentials'))
args = parser.parse_args()
if args.profile is None:
parser.error('Expecting --profile or profile set in environment AWS_PROFILE. e.g. "stage"')
config = configparser.ConfigParser()
config.read(args.credential_path)
if args.profile not in config.sections():
parser.error('Invalid profile. Section not found in ~/.aws/credentails')
if args.arn is None:
if 'aws_arn_mfa' not in config[args.profile]:
sys.exit(0)
# parser.error('ARN is not provided. Specify via --arn')
args.arn = config[args.profile]['aws_arn_mfa']
else:
# Update the arn with user supplied one
config[args.profile]['aws_arn_mfa'] = args.arn
# Generate the session token from the profile
result = subprocess.run(['aws', 'sts', 'get-session-token', '--profile', args.profile + '-default', '--serial-number', args.arn, '--token-code', args.token], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
parser.error(result.stderr.decode('utf-8').strip('\n'))
credentials = json.loads(result.stdout.decode('utf-8'))['Credentials']
config[args.profile]['aws_access_key_id'] = credentials['AccessKeyId']
config[args.profile]['aws_secret_access_key'] = credentials['SecretAccessKey']
config[args.profile]['aws_session_token'] = credentials['SessionToken']
# Save the changes back to the file
with open(args.credential_path, 'w') as configFile:
config.write(configFile)
print('Saved {} credentials to {}'.format(args.profile, args.credential_path))
awsp 사용 방법
awsp [프로필명] [mfa code]
반응형
'IT > AWS' 카테고리의 다른 글
[AWS] CodeDeploy 심화 - ALB Target Group 지정하기 (0) | 2022.01.12 |
---|---|
[AWS] EC2 인스턴스 ENA driver Upgrade 하기 (feat. image builder) (0) | 2022.01.05 |
[AWS] EC2에 EBS mount 트러블슈팅 (.mount 파일 명명 규칙) (0) | 2021.12.28 |
[AWS] EC2에 EBS mount 쉽게 하기(feat. amzlinux2, nvme) (0) | 2021.12.27 |
[AWS] ENA Driver 업그레이드 하기(EC2 5세대 이전 ami 사용 시) (0) | 2021.12.17 |