AWS: CloudTrail – обзор и интеграция с CloudWatch

Thank you for reading this post, don't forget to subscribe!

AWS CloudTrail явлет­ся сер­ви­сом для ауди­та собы­тий в AWS-акка­ун­те и вклю­чен в каж­дом акка­ун­те по-умолчанию.

В него запи­сы­ва­ют­ся собы­тия обо всех собы­ти­ях в акка­ун­те, кото­рые были сде­ла­ны поль­зо­ва­те­лем, ролью или сер­ви­сом AWS через AWS Console, AWS CLI или AWS SDK.

Запи­сы­ва­ет API-вызо­вы, логи­ны в систе­му, собы­тия сер­ви­сов и явля­ет­ся неза­ме­ни­мым инстру­мен­том для обес­пе­че­ния без­опас­но­сти AWS-аккаунта.

Собы­тия хра­нят­ся в CloudTrail 90 дней, но мож­но настро­ить trail, кото­рый будет сохра­нять выбран­ные собы­тия в AWS S3, и/или отправ­лять их в CloudWatch, а уже в CloudWatch мож­но настро­ить Alarms, что бы полу­чать уведомления.

Трей­лы могут быть двух типов – гло­баль­ные, при­ме­ня­е­мые ко всем реги­о­нам, и локаль­ные в рам­ках одно­го реги­о­на, см. How does CloudTrail behave regionally and globally?

AWS CloudTrail Events

См. What are CloudTrail events? и Logging management events for trails.

Event в CloudTrail это запись о любом собы­тии в AWS-акка­ун­те. Собы­тия могут быть трёх типов: management eventdata eventinsight event.

Management events

К Management events отно­сят­ся все опе­ра­ции, кото­рые выпол­ня­ют­ся с ресур­са­ми в акка­ун­те – control plane operations, напри­мер:

  • настрой­ки без­опас­но­сти (напри­мер, API-вызов AttachRolePolicy)
  • созда­ние устройств (напри­мер, API-вызов CreateDefaultVpc)
  • настрой­ка пра­вил для роутинг (напри­мер, API-вызов CreateSubnet)
  • настрой­ки логги­ро­ва­ния (напри­мер, API-вызов CreateTrail)

Так­же, сюда вхо­дят не-API опе­ра­ции, такие как логин в AWS Management Console, см. Non-API Events Captured by CloudTrail.

Кро­ме того, собы­тия могут быть о read и write опе­ра­ци­ях с API. Read, оче­вид­но, это опе­ра­ции, кото­рые толь­ко запра­ши­ва­ют инфор­ма­цию о ресур­сах (напри­мер, DescribeSubnets), а write – моди­фи­ка­ция ресур­сов (напри­мер, TerminateInstances), см. Read and write events.

Data events

См. Data events.

Инфор­ма­ция об опе­ра­ци­ях выпол­нен­ных с ресур­сом, или самим ресур­сом – data plane operations, напри­мер:

  • опе­ра­ции с S3-кор­зи­на­ми, такие как GetObjectDeleteObject и PutObject
  • вызо­вы AWS Lambda-функций
  • опе­ра­ции с Amazon DynamoDB, напри­мер PutItemDeleteItem и UpdateItem

И т.д.

По-умол­ча­нию они не логги­ру­ют­ся, и долж­ны быть добав­ле­ны в trail при его создании.

Insights events

CloudTrail Insights отсле­жи­ва­ет ано­ма­лии в собы­ти­ях и при обна­ру­же­нии такой ано­ма­лии – созда­ёт event.

Таки­ми ано­ма­ли­я­ми могут быть, к при­ме­ру, необыч­ное коли­че­ство API-вызо­вов к S3 кор­зине на уда­ле­ние запи­сей, или необыч­но высо­кое (или наобо­рот – низ­кое) коли­че­ство вызо­вов AuthorizeSecurityGroupIngress.

CloudTrail trail

Как уже гово­ри­лось выше, trail поз­во­ля­ет во-пер­вых хра­нить собы­тия доль­ше 90 дней, во-вто­рых – инте­гри­ро­вать CloudTrail и CloudWatch, в-тре­тих – соби­рать инфор­ма­цию о собы­ти­ях во всех реги­о­нах, так как CloudTrail Dashboard выво­дит инфор­ма­цию о собы­ти­ях толь­ко из теку­ще­го региона.

Создание CloudTrail trail

Пере­хо­дим в Trails, кли­ка­ем Create trail:

Ука­зы­ва­ем имя, выби­ра­ем Create new S3 bucket, ука­зы­ва­ем имя кор­зи­ны, пока отклю­ча­ем шиф­ро­ва­ние логов в корзине:

Что бы настро­ить алер­тинг – вклю­ча­ем отправ­ку собы­тий в CloudWatch Logs:

Остав­ля­ем Management events, вклю­ча­ем Insights.

В Management events вклю­ча­ем и Read и Write, для Insights events вклю­ча­ем API call rate:

Про­ве­ря­ем в CloudWatch Logs:

Теперь мож­но создать мет­ри­ки из этих собы­тий, и настро­ить Alarms.

Интеграция CloudTrail и CloudWatch

Далее, созда­дим мет­ри­ку на осно­ве каких-то собы­тий, а потом доба­вим Alarm, кото­рый будет в AWS SNS слать сооб­ще­ния, а SNS заин­те­гри­ру­ем с Opsgenie, кото­рый будет слать нам сооб­ще­ния в Slack.

Вопрос за каки­ми имен­но собы­ти­я­ми сле­дить, но мож­но погуг­лить запро­сом типа “cloudtrail security alerts”, по кото­ро­му находт­ся два доста­точ­но тол­ко­вых мате­ри­а­ла – Threat Hunting with CloudTrail and GuardDuty in Splunk и Key CloudTrail Events To Monitor for Security in AWS, или берём при­ме­ры из шаб­ло­на Creating CloudWatch Alarms with an AWS CloudFormation Template.

Напри­мер:

  • логин в AWS Console не из офи­са (в при­ме­ре IP офи­са == 8.8.8.8): { ($.eventName = ConsoleLogin) && ($.sourceIPAddress != "8.8.8.8") }
  • руто­вый логин в AWS Console: { ($.eventName = ConsoleLogin) && ($.userIdentity.type = "Root") }
  • ошиб­ки логи­нов в AWS Console: { ($.eventName = ConsoleLogin) && ($.errorMessage = "Failed authentication") }
  • попыт­ки выпол­не­ния запре­щён­ных опе­ра­ций: { ($.errorCode = "*UnauthorizedOperation") || ($.errorCode = "AccessDenied*") }
  • уве­дом­ле­ния о запус­ке сверх­боль­ших инстан­сов, напри­мер мы не поль­зу­ем­ся сер­ве­ра­ми свы­ше х4 (c5.4xlarge самый боль­шой): { ($.eventName = RunInstances) && (($.requestParameters.instanceType = *.8xlarge) || ($.requestParameters.instanceType = *.4xlarge)) }
  • добав­ле­ние новых поль­зо­ва­те­лей в систе­му: { $.eventName="CreateUser" }

См. Filter and pattern syntax.

Пока доба­вим алер­тинг про все логи­ны в AWS-аккаунт.

Посмот­рим, как выгля­дит сам евент – логи­ним­ся, и через ~15 минут смот­рим собы­тия, филь­тру­ем по Event name == ConsoleLogin:

Создание AWS CloudWatch custom metric

Пере­хо­дим к создан­ной выше Log group, во вклад­ке Metric filters кли­ка­ем Create metric filter.

В Filter pattern исполь­зу­ем { ($.eventName = ConsoleLogin) }:

Запол­ня­ем поля:

Про­ве­ря­ем мет­ри­ку в графиках:

Opsgenie и AWS Simple Notifications Service

Пере­хо­дим в AWS SNS, созда­ём новый топик с типом Standart:

В Opsginie в Integration list нахо­дим Incoming Amazon SNS:

Сохра­ня­ем инте­гра­цию, запи­сы­ва­ем API-ключ:

Воз­вра­ща­ем­ся к SNS, кли­ка­ем Create Subscription, выби­ра­ем метод HTTPS, ука­зы­ва­ем URL и API-ключ из Opsgenie:

Полу­ча­ем под­твер­жде­ние, что под­пис­ка подтверждена:

Создание AWS CloudWatch Alarm

Пере­хо­дим в Alarms, кли­ка­ем Create alarm:

Выби­ра­ем метрику:

Опи­сы­ва­ем усло­вия алер­та – боль­ше или рав­но 1 собы­тию (логи­ну):

Настра­и­ва­ем отправ­ку в создан­ный выше SNS-топик:

Ука­зы­ва­ем имя алар­ма, сохра­ня­ем его:

Через несколь­ко минут про­ве­ря­ем ста­тус – вме­сто Insufficient data ста­нет ОК (либо In alarm, если логи­ни­лись в систему):

Теперь мож­но зало­ги­нить­ся в AWS Console, через 15 минут, когда до CloudTrail-а дой­дёт новое собы­тие, и полу­чим аларм:

И алерт в Slack:

Opsgenie и кастомные поля из AWS SNS

Из того, что хоте­лось бы ещё сде­лать – это отфиль­тро­вать сооб­ще­ние в Slack, что бы выво­дить толь­ко нуж­ные поля. Мож­но реа­ли­зо­вать с помо­щью стро­ко­вых функ­ций Opsgenie.

Пере­хо­дим к инте­гра­ции Incoming SNS, кли­ка­ем Advanced:

В поле Description добав­ля­ем вызов Message.extract() для полей:

Теперь, когда Opsgenie полу­ча­ет JSON от AWS SNS, он из него возь­мёт толь­ко три объ­ек­та – AlarmDescriptionAWSAccountId и Region, и в резуль­та­те в Slack полу­ча­ем сооб­ще­ние в таком виде:

гото­во