Разобрать журналы CloudTrail с помощью Python

Я работаю над лямбда-функцией, которая получает события из CloudTrail и анализирует их.

У меня есть этот скрипт:

 s3.download_file(bucket, key, download_path)
        with gzip.open(download_path, "r") as f:
            data = json.loads(f.read())
            print json.dumps(data)
            for event in data['Records']:
                if event['eventName'] in event_list:
                    dateEvent = datetime.strptime(event['eventTime'], "%Y-%m-%dT%H:%M:%SZ")
                    for element in event['userIdentity']:
                        for session in element[0]['sessionContext']:
                            username = session['userName']
                            role = session['arn']

Я не могу выйти из события, значение userName и arn, Я получаю эту ошибку:

string indices must be integers: TypeError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 34, in lambda_handler
for session in element[0]['sessionContext']:
TypeError: string indices must be integers

Как заставить это работать? Какой правильный путь?

Вот строка json:

 "userIdentity": {
                "principalId": "aaaaaaaaaaaaaaaaaaaa",
                "accessKeyId": "aaaaaaaaaaaaaaaaaaaaa",
                "sessionContext": {
                    "sessionIssuer": {
                        "userName": "aaaaaaaaaaaaa",
                        "type": "Role",
                        "arn": "arn:aws:iam::aaaaaaaaaaaaaaaaaa:role/aaaaaaa",
                        "principalId": "aaaaaaaaaaaaaaaaaa",
                        "accountId": "aaaaaaaaaaaaaaaaaaa"
                    },
                    "attributes": {
                        "creationDate": "2017-09-14T15:03:08Z",
                        "mfaAuthenticated": "false"
                }
            },
        "type": "AssumedRole",
        "arn": "aaaaaaaaaaaaaaaaaaaaaaaa",
        "accountId": "aaaaaaaaaaaaaaaaaa"
    },

1 ответ

Решение

userIdentity элемент может иметь или не иметь sessionContext элемент, потому что они существуют, только если во время этого события были использованы временные учетные данные IAM.

userIdentity элемент без sessionContext выглядит так:

"userIdentity": {
  "type": "IAMUser",
  "principalId": "AIDAJ45Q7YFFAREXAMPLE",
  "arn": "arn:aws:iam::123456789012:user/Alice",
  "accountId": "123456789012",
  "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
  "userName": "Alice"
}

Но userIdentity с sessionContext Элемент будет выглядеть так:

"userIdentity": {
    "type": "AssumedRole",
    "principalId": "AROAIDPPEZS35WEXAMPLE:AssumedRoleSessionName",
    "arn": "arn:aws:sts::123456789012:assumed-role/RoleToBeAssumed/MySessionName",
    "accountId": "123456789012",
    "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
    "sessionContext": {
      "attributes": {
        "creationDate": "20131102T010628Z",
        "mfaAuthenticated": "false"
      },
      "sessionIssuer": {
        "type": "Role",
        "principalId": "AROAIDPPEZS35WEXAMPLE",
        "arn": "arn:aws:iam::123456789012:role/RoleToBeAssumed",
        "accountId": "123456789012",
        "userName": "RoleToBeAssumed"
      }
    }
}

... или это могло бы выглядеть так, если бы не произошла федерация ролей.

"userIdentity": {
    "type": "IAMUser",
    "principalId": "EX_PRINCIPAL_ID",
    "arn": "arn:aws:iam::123456789012:user/Alice",
    "accountId": "123456789012",
    "accessKeyId": "EXAMPLE_KEY_ID",
    "userName": "Alice",
    "sessionContext": {"attributes": {
        "mfaAuthenticated": "false",
        "creationDate": "2014-03-06T15:15:06Z"
    }}
}

Итак, вернемся к вашему коду:

for element in event['userIdentity']:
    for session in element[0]['sessionContext']:
        username = session['userName']
        role = session['arn']

element[0] не существует, потому что sessionContext это не список

Если вы хотите получить использованное или предполагаемое имя пользователя и роль ARN, я думаю, это сработает. Он учитывает события, которые были сделаны напрямую через IAMUser или через AssumedRole,

user_identity = event['userIdentity']

# check to see if we have a sessionContext[sessionIssuer]
if 'sessionIssuer' in user_identity.get('sessionContext', {}):
    user_name = user_identity['sessionContext']['sessionIssuer']['userName']
    arn = user_identity['sessionContext']['sessionIssuer']['arn']
else:
    user_name = user_identity['userName']
    arn = user_identity['arn']

И как часть вашего цикла обработки:

for event in data['Records']:
    if event['eventName'] in event_list:
        dateEvent = datetime.strptime(event['eventTime'], "%Y-%m-%dT%H:%M:%SZ")
        user_identity = event['userIdentity']

        # check to see if we have a sessionContext[sessionIssuer]
        if 'sessionIssuer' in user_identity.get('sessionContext', {}):
            user_name = user_identity['sessionContext']['sessionIssuer']['userName']
            arn = user_identity['sessionContext']['sessionIssuer']['arn']
        else:
            user_name = user_identity['userName']
            arn = user_identity['arn']
Другие вопросы по тегам