본문 바로가기
CSP (Cloud Service Provider)/AWS

[Terraform] AWS MFA 적용 User_토큰 입력 자동화 설정

by BTC_SHINN 2023. 6. 23.

베하! 안녕하세요~!

BTC_수신자표시제한 입니다.

오늘은 테라폼에서 MFA가 설정된 유저 Profile의 토큰 발급 자동화 세팅방법에 대해 알아보겠습니다. 


먼저, 기본적인 Terraform 환경구성은 완료된 상태라는 가정하에 작업을 진행해보도록 하겠습니다. 

 

(만약 Terraform 환경구성이 궁금하다면 ☞여기를 클릭하세요)

 

MFA는 로그인시 2차인증을 거침으로써 계정의 해킹위험을 낮춰 보안성을 높여줍니다.

보안을 위해 MFA 적용한 IAM User를 사용하지만

MFA를 통해 발급받은 임시 세션 토큰은 

IAM 유저의 경우 일반적으로 12시간(최대 36시간까지 설정 가능)동안 유효하므로,

매일 토큰값을 새로 발급받아 등록하는 귀찮은 과정을 반복해야하는 번거로움이 발생합니다.

 

따라서 이 번거로운 작업을 최대한 간소화시키기위해

매일 MFA OTP 값만 입력하면 새로발급 받은 임시토큰 값이 자동으로 치환되어 입력되도록

설정하는 방법에 대해 알아보겠습니다. 

 

 

1. ~/.aws/config 파일에 mfa_arn 정보 들어있는지 확인합니다. 

 

mfa arn 확인 명령어
$ aws iam list-mfa-devices --profile <profile 이름>

 

$ vi ~/.aws/config
[profile user]
region = ap-northeast-2
aws_arn_mfa = 

[profile mfa]
region = ap-northeast-2

 

2. 자동화를 위한 스크립트 파일을 생성합니다. 

 

파이썬 파일과 쉘 스크립트 두가지 방법을 소개드리니

사용하시기 편한 방법을 선택해서 사용하시면 됩니다. :)

※ profile명은 본인이 설정한 이름으로 수정 필요

 

✅방법 1 (python)

 

./aws_mfa.py

import sys
import configparser
import json
import os
import getpass
from os.path import expanduser

if(len(sys.argv) <= 1 ):
    exit("Need named profile")

home = expanduser("~")
requestedProfile = sys.argv[1]
awsConfig = configparser.ConfigParser()
awsCred   = configparser.ConfigParser()

awsConfig.read("%s/.aws/config" % home)
awsCred.read('%s/.aws/credentials' % home)

try:
    mfaARN = awsConfig["profile " + requestedProfile]['aws_arn_mfa']
except KeyError:
    try:
        mfaARN = awsConfig['profile user'].get('aws_arn_mfa')
    except KeyError:
        exit("Need MFA arn in config file")

profiles = set( awsCred.sections())
configprofiles = set( awsConfig.sections())

if( requestedProfile in profiles and "profile " + requestedProfile in configprofiles):
    print("Updating %s profile" % requestedProfile)
else:
    if( "profile " + requestedProfile in configprofiles):
        print("Creating %s credentials profile" % requestedProfile)
        awsCred.add_section(requestedProfile)
    else:
        exit("No such profile \"%s\" in config" % requestedProfile )

try:
    OneTimeNumber = getpass.getpass("OTP from device: ")
except ValueError:
    exit("OTP must be a number")


response = os.popen("aws --profile user sts get-session-token --serial-number  %s --token-code %s" % (mfaARN,
                                                                                                       str(OneTimeNumber).zfill(6))).read()

try:
    myjson = json.loads(response)
except json.decoder.JSONDecodeError:
    exit("Failed to parse the response as valid JSON. Check the format of the response from AWS.")

awsCred[requestedProfile]['aws_access_key_id']     = myjson['Credentials']['AccessKeyId']
awsCred[requestedProfile]['aws_secret_access_key'] = myjson['Credentials']['SecretAccessKey']
awsCred[requestedProfile]['aws_session_token']     = '"' + myjson['Credentials']['SessionToken'] + '"'

with open('%s/.aws/credentials' % home, 'w') as awsCredfile:
    awsCred.write(awsCredfile)

 

✅방법 2 (Shell Script)

    - jq 패키지 설치 필요

$ vi aws_mfa.sh


#!/bin/bash

##### Parameters #####
aws_original_profile=$1
aws_mfa_token=$2
aws_mfa_profile_name="mfa"
session_duration=43200 #I set it to 43200 (12 hours).
######################

create_new_credentials() {
    local aws_original_profile=$1
    local aws_mfa_token=$2
    local aws_mfa_profile_name=$3
    local session_duration=$4

    local mfa_serial_number=$(aws configure --profile "${aws_original_profile}" get aws_arn_mfa)
    if [ -z "${mfa_serial_number}" ] ; then
        echo "ERROR mfa_serial_number is empty for profile ${mfa_serial_number}. Set it in default credential file with key aws_arn_mfa"
        exit 1
    fi

    local tmp_credentials=$(aws sts get-session-token \
        --profile "${aws_original_profile}" \
        --serial-number "${mfa_serial_number}"  \
        --token-code "${aws_mfa_token}" \
        --duration-second "${session_duration}" )
    if [ $? -ne 0 ]; then
        echo "ERROR. Check your profile or MFA"
        exit 2
    fi

    local aws_access_key_id=$(echo "${tmp_credentials}" | jq .Credentials.AccessKeyId | sed "s/\"//g")
    local aws_secret_access_key=$(echo "${tmp_credentials}" | jq .Credentials.SecretAccessKey | sed "s/\"//g")
    local aws_session_token=$(echo "${tmp_credentials}" | jq .Credentials.SessionToken | sed "s/\"//g")

    aws configure --profile "${aws_mfa_profile_name}" set aws_access_key_id ${aws_access_key_id}
    aws configure --profile "${aws_mfa_profile_name}" set aws_secret_access_key ${aws_secret_access_key}
    aws configure --profile "${aws_mfa_profile_name}" set aws_session_token ${aws_session_token}

    echo "Done, now you can use your mfa profile ${aws_mfa_profile_name}"
}

create_new_credentials "${aws_original_profile}" "${aws_mfa_token}" "${aws_mfa_profile_name}" "${session_duration}"

 

3. 토큰 만료시 파일 실행을 통한 프로파일 설정

 

위와같이 파일을 설정해두면 매일 테라폼 작업 시작 전

아래와 같이 명령어를 실행하고 OTP 번호만 입력해주면

간편하게 mfa 프로파일을 새로 적용할 수 있습니다. 

 

# 파이썬 파일 적용시 
./aws_mfa.py <profile이름>

OR

# 쉘 스크립트 적용시
./aws_mfa.sh <profile이름> <mfa 토큰값>

 


여기까지 MFA 임시토큰 입력 자동화에 대해 알아보았습니다.😊


다음에 또 만나요 👋👋

 

'CSP (Cloud Service Provider) > AWS' 카테고리의 다른 글

[AWS] Amazon ElastiCache와 MemoryDB for Redis  (0) 2023.06.25
[AWS] Solutions Library  (0) 2023.06.23
[AWS][GCP] AWS GCP VPN 연동  (0) 2023.06.23
[AWS] AWS CodeBuild  (0) 2023.06.22
[AWS] SQS (Simple Queue Service)  (0) 2023.06.14

댓글