내용으로 건너뛰기

CloudWatch Logs Insights를 사용하여 CloudTrail Logs를 검색하고 분석하려면 어떻게 해야 하나요?

9분 분량
0

Amazon CloudWatch Logs Insights를 사용하여 Amazon CloudTrail Logs를 검색하고 분석하려고 합니다.

간략한 설명

CloudTrail을 구성하여 CloudWatch Logs를 기록하도록 설정한 후에는 CloudWatch Logs Insights에서 쿼리를 사용하여 CloudTrail Logs를 검색할 수 있습니다. 그런 다음 특정 계정 활동을 모니터링할 수 있습니다.

해결 방법

다음 쿼리를 사용해 CloudWatch 로그을 검색하여 Amazon Simple Storage Service(Amazon S3) 버킷 및 객체 활동을 분석하고 탐색합니다. 기본적으로 CloudTrail은 Amazon S3 데이터 이벤트를 캡처하지 않습니다. S3 버킷 및 개체에 대한 이벤트 로그를 검색하려면 CloudTrail에서 이벤트 로깅을 사용 설정해야 합니다.

이러한 예제 쿼리를 기반으로 사용 사례에 맞는 더 복잡한 Logs Insights 쿼리를 추가로 만들 수 있습니다. 또한 쿼리를 CloudWatch 대시보드와 통합하여 쿼리를 관련 지표와 함께 차트 및 그래프로 시각화할 수 있습니다.

쿼리 1: 최신 이벤트

목표

기본 @timestamp@message 필드를 사용하여 가장 최근의 CloudTrail Log 이벤트를 검색합니다.

쿼리

#Retrieve the most recent CloudTrail events
fields @timestamp, @message
| sort @timestamp desc
| limit 2

결과

@timestamp@message
2022-02-18 17:52:31.118{"eventVersion":"1.08","userIdentity":{"type":"AssumedRole","principalId":"AROAWZKRRJU47ARZN7ECC:620d7d78144334d6933c27195cae2a98", "arn":"arn:aws:sts::123456789012:assumed- role/Amazon_EventBridge_Invoke_Run_Command_371790151/620d7d78144334d6933c27195cae2a98","accountId":"123456789012", "accessKeyId":"ASIAWZKRRJU4Y45M4SC6","sessionContext":{"sessionIssuer": {"type":"Role","principalId":"AROAWZKRRJU47ARZN7ECC","arn":"arn:aws:iam::123456789012:role/service- role/Amazon_EventBridge_Invoke_Run_Command_371790151","accountId":"123456789012","userName": "Amazon_EventBridge_Invoke_Run_Command_371790151" (output truncated)
2022-02-18 17:51:52.137{"eventVersion":"1.08","userIdentity":{"type":"AssumedRole","principalId":"AROAWZKRRJU43YP4FHR2N:StateManagerService","arn":"arn:aws:sts::123456789012:assumed-role/AWSServiceRoleForAmazonSSM/StateManagerService","accountId":"123456789012","sessionContext":{"sessionIssuer":{"type":"Role","principalId":"AROAWZKRRJU43YP4FHR2N","arn":"arn:aws:iam::123456789012:role/aws-service-role/ssm.amazonaws.com/AWSServiceRoleForAmazonSSM","accountId":"123456789012","userName":"AWSServiceRoleForAmazonSSM"}, "webIdFederationData":{},"attributes":{"creationDate":"2022-02-18T17:50:06Z","mfaAuthenticated":"false"}},"invokedBy":"ssm.amazonaws.com"},"eventTime":"2022-02-18T17:50:06Z","eventSource":"ec2.amazonaws.com","eventName":"DescribeInstances","awsRegion":"eu-west-1","sourceIPAddress":"ssm.amazonaws.com","userAgent":"ssm.amazonaws.com","requestParameters":{"maxResults":50,"instancesSet": (output truncated)

쿼리 2: 개별 필드 나누기

목표

  • @message에서 개별 필드를 분리합니다.
  • CloudTrail 이벤트에서 선택한 필드를 표시합니다.

쿼리

#Breakout Individual Fields
fields @timestamp, awsRegion, eventCategory, eventSource, eventName, eventType, sourceIPAddress, userIdentity.type
| sort @timestamp desc
| limit 2

결과

@timestampawsRegioneventCategoryeventSourceeventNameeventTypesourceIPAddressuserIdentity.type
2022-02-18 18:00:09.647ca-central-1Managementsts.amazonaws.comAssumeRoleAwsApiCallcloudtrail.amazonaws.comAWSService
2022-02-18 18:00:09.647ca-central-1Managementsts.amazonaws.comAssumeRoleAwsApiCallcloudtrail.amazonaws.comAWSService

쿼리 3: Amazon Elastic Compute Cloud(Amazon EC2) 실행 인스턴스별 필터링

목표

  • CloudTrail 이벤트에서 특정 필드를 검색합니다.
  • 보다 의미 있는 레이블을 사용하려면 필드 이름을 변경합니다.
  • API 직접 호출을 기반으로 이 계정에서 시작된 최신 EC2 인스턴스를 필터링합니다.

쿼리

#EC2: Recently Launched Instances
fields eventTime, eventName as API, responseElements.instancesSet.items.0.instanceId as InstanceID, userIdentity.sessionContext.sessionIssuer.type as IssuerType, userIdentity.type as IdentityType, userIdentity.sessionContext.sessionIssuer.userName as userName
| filter eventName = 'RunInstances'
| sort eventTime desc
| limit 2

결과

eventTimeAPIInstanceIDIssuerTypeIdentityTypeuserName
2022-02-18T17:36:38ZRunInstancesi-0325b4d6ae4e93c75RoleAssumedRoleAWSServiceRoleForAutoScaling
2022-02-18T13:45:18ZRunInstancesi-04d17a8425b7cb59aRoleAssumedRoleAWSServiceRoleForAutoScaling

쿼리 4: 가장 최근의 콘솔 로그인을 기준으로 필터링

목표

  • CloudTrail 이벤트에서 특정 필드를 검색합니다.
  • 보다 의미 있는 레이블을 사용하려면 필드 이름을 변경합니다.
  • API 직접 호출을 기반으로 콘솔의 최신 로그인을 필터링합니다.

쿼리

#Console Login: Most Recent API Calls
fields eventTime, eventName, responseElements.ConsoleLogin as Response, userIdentity.arn as ARN, userIdentity.type as User_Type
| filter eventName = 'ConsoleLogin'
| sort eventTime desc
| limit 10

결과

eventTimeeventNameResponseARNUser_Type
2022-02-18T17:35:44ZConsoleLoginSuccessarn:aws:iam::123456789012:user/test_userIAMUser
2022-02-17T13:53:58ZConsoleLoginSuccessarn:aws:sts::123456789012:assumed-role/Admin/test_userAssumedRole

쿼리 5: 인증에 실패한 콘솔 로그인을 기준으로 필터링

목표

  • CloudTrail 이벤트에서 특정 필드를 검색합니다.
  • 보다 의미 있는 레이블을 사용하려면 필드 이름을 변경합니다.
  • 콘솔에서 최근에 실패한 로그인을 필터링합니다.

쿼리

#ConsoleLogin: Filter on Failed Logins
fields eventTime, eventName, responseElements.ConsoleLogin as Response, userIdentity.userName as User, userIdentity.type as User_Type, sourceIPAddress, errorMessage
| filter eventName = 'ConsoleLogin' and responseElements.ConsoleLogin = 'Failure'
| sort eventTime desc
| limit 10

결과

eventTimeeventNameResponseUserUser_TypesourceIPAddresserrorMessage
2022-02-18T20:10:55ZConsoleLoginFailureechoIAMUser12.34.56.89Failed authentication
2022-02-18T20:10:43ZConsoleLoginFailureechoIAMUser12.34.56.89Failed authentication

쿼리 6: Amazon Simple Storage Service(Amazon S3) 객체 업로드를 기준으로 필터링

목표

  • CloudTrail 이벤트에서 특정 필드를 검색합니다.
  • 보다 의미 있는 레이블을 사용하려면 필드 이름을 변경합니다.
  • API 직접 호출 및 대상 S3 버킷을 기준으로 필터링합니다.

쿼리

#Filter PutObject API Calls on a specific S3 Bucket
fields @timestamp, eventName as API, requestParameters.bucketName as BucketName, requestParameters.key as Key, userIdentity.sessionContext.sessionIssuer.userName as UserName
| filter eventName = 'PutObject' and BucketName = 'target-s3-bucket'
| sort @timestamp desc
| limit 2

결과

@timestampAPIBucketNameKeyUserName
2022-02-12 17:16:07.415PutObjecttest_bucket1w4r9Hg4V7g.jpg
2022-02-12 16:29:43.470PutObjecttest_bucket26wyBy0hBoB.jpg

쿼리 7: S3 활동 요약

목표

  • Amazon S3 서비스를 기반으로 필터링합니다.
  • 개수 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • API, S3 버킷 및 키를 기준으로 결과를 나눕니다.
  • stats 명령을 사용하여 필드 이름을 변경합니다.
  • 내림차순으로 정렬합니다.

쿼리

#S3 Activity: Bucket Key Details
filter eventSource = 's3.amazonaws.com'
| stats count(*) as Hits by eventName as API, requestParameters.bucketName as BucketName, requestParameters.key as Key
| sort Hits desc
| limit 5

결과

APIBucketNameKeyHits
ListAccessPoints44
GetBucketAclteam1-ctrail-multi-region27
GetBucketAclteam2-dub-cloudtrail27
GetBucketAclaws-cloudtrail-logs-123456789012-ba940dd726
GetObjectdevsupport-prodrdscr/individual/12345678901218

쿼리 8: AWS KMS 암호 해독 활동 요약

목표

  • AWS Key Management Service(AWS KMS) 서비스 및 Decrypt API를 기반으로 필터링합니다.
  • fields 명령을 사용하여 필드 이름을 변경한 다음 사용자에게 친숙한 이름을 기준으로 집계합니다.
  • 개수 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • AWS KMS 키와 사용자를 기준으로 결과를 나눕니다.
  • 내림차순으로 정렬합니다.

쿼리

#KMS Decrypt Activity: Key User Details
fields resources.0.ARN as KMS_Key, userIdentity.sessionContext.sessionIssuer.userName as User
| filter eventSource='kms.amazonaws.com' and eventName='Decrypt'
| stats count(*) as Hits by KMS_Key, User
| sort Hits desc
| limit 2

결과

KMS_KeyUserHits
arn:aws:kms:us-east-1:123456789012:key/03f2923d-e213-439d-92cf-cbb444bd85bdAWSServiceRoleForConfig12
arn:aws:kms:us-east-1:123456789012:key/03f2923d-e213-439d-92cf-cbb444bd85bdFoxTrot-1UQJBODTWZYZ68

쿼리 9: 오류가 있는API 직접 호출 요약

목표

  • ErrorCode 필드의 존재 여부를 기반으로 필터링합니다.
  • 개수 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • AWS 서비스, API 및 errorCode를 기반으로 결과를 나눕니다.
  • stats 명령을 사용하여 필드 이름을 변경합니다.
  • 일치하는 항목 수가 가장 많은 순으로 정렬합니다.

쿼리

#Summarize API Calls with Errors
filter ispresent(errorCode)
| stats count(*) as Num_of_Events by eventSource as AWS_Service, eventName as API, errorCode
| sort Num_of_Events desc
| limit 5

결과

AWS_ServiceAPIerrorCodeNum_of_Events
s3.amazonaws.comGetBucketPublicAccessBlockNoSuchPublicAccessBlockConfiguration79
lambda.amazonaws.comGetLayerVersionPolicy20181031ResourceNotFoundException66
s3.amazonaws.comGetBucketPolicyStatusNoSuchBucketPolicy60
s3.amazonaws.comHeadBucketAccessDenied47
logs.amazonaws.comCreateLogStreamResourceNotFoundException21

쿼리 10: S3 API 직접 호출을 오류 코드와 함께 요약합니다.

목표

  • Amazon S3 서비스 및 errorCode 필드의 존재 여부를 기반으로 필터링합니다.
  • 개수 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • errorCodeerrorMessage를 기준으로 결과를 나눕니다.
  • 일치하는 항목 수가 가장 많은 순으로 정렬합니다.

쿼리

#S3: Summarize Error Codes
filter eventSource = 's3.amazonaws.com' and ispresent(errorCode)
| stats count(*) as Hits by errorCode, errorMessage
| sort Hits desc
| limit 5

결과

errorCodeerrorMessageHits
AccessDeniedAccess Denied86
NoSuchBucketPolicyThe bucket policy does not exist80
NoSuchPublicAccessBlockConfigurationThe public access block configuration was not found79
ObjectLockConfigurationNotFoundErrorObject Lock configuration does not exist for this bucket3
ServerSideEncryptionConfigurationNotFoundErrorThe server side encryption configuration was not found3

쿼리 11: AWS 서비스, API, AWS Identity and Access Management(IAM) AccessDenied/UnauthorizedOperation API 직접 호출을 요약합니다.

목표

  • AccessDenied 또는 UnauthorizedOperation CloudTrail 이벤트를 기준으로 필터링합니다.
  • 카운트 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • errorCode, AWS 서비스, API, IAM 사용자 또는 역할을 기준으로 결과를 나눕니다.
  • stats 명령을 사용하여 필드 이름을 변경합니다.
  • 내림차순으로 정렬합니다.

쿼리

#Summarize AccessDenied/UnauthorizedOperation API Calls by AWS Service, API, IAM User
filter (errorCode='AccessDenied' or errorCode='UnauthorizedOperation')
| stats count(*) as NumberOfEvents by errorCode, eventSource as AWS_Service, eventName as API, userIdentity.type as IdentityType, userIdentity.invokedBy as InvokedBy
| sort NumberOfEvents desc
| limit 10

결과

errorCodeAWS_ServiceAPIIdentityTypeInvokedByNumberOfEvents
AccessDenieds3.amazonaws.comHeadBucketAWSServicedelivery.logs.amazonaws.com83
AccessDenieds3.amazonaws.comGetObjectAssumedRole9

쿼리 12: AWS KMS 시간당 직접 호출량

목표

  • AWS KMS 서비스 및 암호 해독 API를 기반으로 필터링합니다.
  • 일치하는 모든 이벤트를 1시간 빈으로 집계합니다.
  • 결과를 선 그래프로 시각화합니다.

쿼리

#KMS: Hourly Decrypt Call Volume
filter eventSource='kms.amazonaws.com' and eventName='Decrypt'
| stats count(*) as Hits by bin(1h)

결과

bin(1h)Hits
2022-02-18 19:00:00.00016
2022-02-18 18:00:00.00025
2022-02-18 17:00:00.00028
2022-02-18 16:00:00.00014
2022-02-18 15:00:00.00016

관련 정보

Amazon CloudWatch에서 AWS CloudTrail 로그 데이터를 모니터링합니다(동영상)

대시보드에 쿼리 추가 또는 쿼리 결과 내보내기