Splunk SOAR(이하 Phantom 으로 지칭) 에서 제공하는 AWS 관련 app을 보면 아래와 같이 2가지 방법으로 Phantom 과 AWS를 연결할 수 있다.
첫번째, Access Key / Secret Key 를 입력하는 방법.
두번재, EC2에서 현재 Phantom 을 실행할때 연결된 role 을 사용하는 방법.
위 두가지 방법 중 두번째 방법을 보면 체크 박스에 체크를 하는것만으로도 AWS App 의 Test connectivity 가 정상적으로 Pass가 되는걸 볼수가 있다. (Phantom이 EC2에 실행이 되어야 하고 role을 사용해야 함.) 어떻게 key 또는 ID / PWD가 없이 연결이 되는거지? 라는 의문이 들었다. 해당 의문에 대해서는 다음과 같은 사이트에서 이해할 수 있었다. (https://cloudguardians.medium.com/ec2-instance-metadata-보안-edd23f56b64c)
메타데이터를 이용해 EC2에 대한 정보를 가져올수가 있는데 아래와 같이 curl을 던지면 사용 가능한 meta-data정보 리스트를 확인해볼수 있다.
/iam/security-credentials/ 정보를 체크해보면
해당 Phantom이 설치된 EC2 인스턴스는 bob_role이라는 role을 사용하고 있다는걸 알수 있다. bob_role 를 통해 임시보안자격증명을 하려면 아래와 같이 임시로 쓸수 있는 key와 만료시간을 전달받을 수가 있다.
임시로 쓰는 키지만…다 보여드리기 기분이 좀 그래서 가림..ㅎㅎ
다시 돌아와 Phantom app 에서 use_role을 체크한다면 아래와 같은 boto3를 이용한 소스가 실행되 key 값을 받게된다.
from boto3 import Session, client, resource
if config.get('use_role'):
credentials = self._handle_get_ec2_role()
if not credentials:
return self.set_status(phantom.APP_ERROR, EC2_ROLE_CREDENTIALS_FAILURE_MSG)
self._access_key = credentials.access_key
self._secret_key = credentials.secret_key
self._session_token = credentials.token
return phantom.APP_SUCCESS
self._access_key = config.get(EC2_JSON_ACCESS_KEY)
self._secret_key = config.get(EC2_JSON_SECRET_KEY)
def _handle_get_ec2_role(self):
session = Session(region_name=self._region)
credentials = session.get_credentials()
return credentials
하지만 현재 사용하고 있는 role 이 아닌 다른 role 접근을 하려면 STS를 사용해야 한다.우선 권한이 필요하다. (https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_credentials_temp_control-access_enable-create.html) bob_role 에서 bob_role2 연결을 하려면 아래와 같은 권한이 필요하다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com",
"AWS": "arn:aws:iam::[bob Account]:role/bob_role"
},
"Action": "sts:AssumeRole"
}
]
}
권한 부여가 되었으면 python에서 STS를 사용하면 된다.
def _assume_a_role(self, param):
boto_config = None
if self._proxy:
boto_config = Config(proxies=self._proxy)
self.debug_print("Creating boto3 STS client assuming given role")
sts_client = client(
'sts',
region_name=self._region,
aws_access_key_id=self._access_key,
aws_secret_access_key=self._secret_key,
aws_session_token=self._session_token,
config=boto_config)
response = sts_client.assume_role(
RoleArn=param['role_arn'],
RoleSessionName="AssumeRoleSession2"
)
# self._access_key = response['Credentials']['AccessKeyId']
# self._secret_key = response['Credentials']['SecretAccessKey']
# self._session_token = response['Credentials']['SessionToken']
return response['Credentials']
# 사용 예시
if param and 'role_arn' in param:
try:
temp_credentials = self._assume_a_role(param) # ast.literal_eval(param['credentials'])
self._access_key = temp_credentials.get('AccessKeyId', '')
self._secret_key = temp_credentials.get('SecretAccessKey', '')
self._session_token = temp_credentials.get('SessionToken', '')
self.save_progress("Using temporary assume role credentials for action")
except Exception as e:
return action_result.set_status(phantom.APP_ERROR,
"Failed to get temporary credentials:{0}".format(e))
실행 결과
Status : success 가 나오는걸 확인할 수 있다.
Phantom의 AWS 관련 앱에서 어떻게 key가 없이 연결이 되는지 라는 물음에서 많은 공부가 되었다. 해당 문제를 해결하려면 기본적인 AWS IAM 을 이해해야 해서 관련 문서를 보면 많은 도움이 된다.
잘못되거나 수정해야 할 내용이 있으면 알려주길 바란다.