CloudWatch Logs Insights로 CloudTrail Logs를 분석하려면 어떻게 해야 합니까?

9분 분량
0

Amazon CloudWatch Logs Insights를 사용하여 Amazon CloudTrail Logs를 분석하고 싶습니다. 어떻게 해야 합니까?

간략한 설명

CloudWatch Logs에 기록하도록 CloudTrail을 구성할 수 있습니다. 이렇게 하면 CloudWatch Logs Insights를 사용하여 CloudTrail 로그를 분석하여 특정 계정 활동을 모니터링할 수 있습니다.

CloudTrail 로그를 분석하는 Logs Insights 기능을 입증하기 위해 다음 해결 방법에는 샘플 쿼리가 포함되어 있습니다. 이러한 쿼리는 가장 일반적인 사용 사례를 다룹니다.

  • 특정 로그 필드를 격리
  • 다양한 조건에서 필터링
  • 이벤트 집계
  • 시계열 만들기

해결 방법

다음 쿼리는 Amazon Simple Storage Service(Amazon S3) 버킷과 객체 활동을 살펴봅니다. 기본적으로 CloudTrail은 S3 데이터 이벤트를 캡처하지 않습니다. CloudTrail에서 이벤트 로깅을 켤 수 있습니다. 자세한 내용은 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" (출력 잘림)
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": (출력 잘림)

쿼리 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-1관리sts.amazonaws.comAssumeRoleAwsApiCallcloudtrail.amazonaws.comAWSService
2022-02-18 18:00:09.647ca-central-1관리sts.amazonaws.comAssumeRoleAwsApiCallcloudtrail.amazonaws.comAWSService

쿼리 3: Amazon Elastic Compute Cloud(Amazon EC2) RunInstances 기준 필터링

목표

  • 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-0325b4d6ae4e93c75역할AssumedRoleAWSServiceRoleForAutoScaling
2022-02-18T13:45:18ZRunInstancesi-04d17a8425b7cb59a역할AssumedRoleAWSServiceRoleForAutoScaling

쿼리 4: 콘솔 로그인으로 필터링: 최신

목표

  • Cloudtrail 이벤트에서 특정 필드를 검색합니다.
  • 보다 의미 있는 레이블로 필드의 이름을 바꿉니다.
  • API 호출을 기반으로 AWS 콘솔을 통해 최신 로그인을 필터링합니다.

쿼리

#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

결과

eventTimeeventName응답ARNUser_Type
2022-02-18T17:35:44ZConsoleLogin성공arn:aws:iam::123456789012:user/test_userIAMUser
2022-02-17T13:53:58ZConsoleLogin성공arn:aws:sts::123456789012:assumed-role/Admin/test_userAssumedRole

쿼리 5: 콘솔 로그인별 필터링: 인증 실패

목표

  • Cloudtrail 이벤트에서 특정 필드 (예: 사용자 이름, 사용자 유형, 소스 IP)를 검색합니다.
  • 보다 의미 있는 레이블로 필드의 이름을 바꿉니다.
  • AWS 콘솔을 통해 최근 실패한 로그인을 필터링합니다.

쿼리

#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

결과

eventTimeeventName응답사용자User_TypesourceIPAddresserrorMessage
2022-02-18T20:10:55ZConsoleLogin실패echoIAMUser12.34.56.89인증 실패
2022-02-18T20:10:43ZConsoleLogin실패echoIAMUser12.34.56.89인증 실패

쿼리 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

결과

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

쿼리 7: S3 활동 요약

목표

  • 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

결과

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

쿼리 8: AWS Key Management Service(AWS KMS) 복호화 활동 요약

목표

  • KMS 서비스Decrypt API를 기반으로 필터링합니다.
  • fields 명령을 사용하여 필드의 이름을 바꾸고 사용자 친화적인 이름을 집계합니다.
  • 카운트 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • 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_Key사용자Hits
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 서비스, APIerrorCode를 기반으로 결과를 연결합니다.
  • 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 호출 요약

목표

  • 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
AccessDenied액세스가 거부되었습니다.86
NoSuchBucketPolicy버킷 정책이 존재하지 않습니다.80
NoSuchPublicAccessBlockConfiguration공용 액세스 블록 구성을 찾을 수 없습니다.79
ObjectLockConfigurationNotFoundError이 버킷에 대한 객체 잠금 구성이 존재하지 않습니다.3
ServerSideEncryptionConfigurationNotFoundError서버 측 암호화 구성을 찾을 수 없습니다.3

쿼리 11: AWS 서비스, API 및 AWS Identity and Access Management(IAM) 사용자의 AccessDenied/UnauthorizedOperation API 호출 요약

목표

  • AccessDenied 또는UnauthorizedOperation CloudTrail 이벤트를 기준으로 필터링합니다.
  • 카운트 통계를 기반으로 일치하는 모든 이벤트를 집계합니다.
  • errorCode, AWS 서비스, APIIAM 사용자/역할을 기반으로 결과를 연결합니다.
  • 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: 시계열: KMS 시간당 통화량

목표

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

쿼리

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

결과

구간(1시간)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 로그 데이터 모니터링 (동영상)

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

CloudWatch Logs Insights 샘플 쿼리

CloudWatch Logs Insights 쿼리 명령

AWS 공식
AWS 공식업데이트됨 2년 전