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

Автор: | 16/06/2021

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?

Собственно, в этом посте рассмотрим CloudTrail и его возможности в целом, настроим экспорт событий в CloudWatch, создадим аларм и настроим и отправку алертов в Slack через Opsgenie.

AWS CloudTrail Events

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

Event в CloudTrail это запись о любом событии в AWS-аккаунте. События могут быть трёх типов: management event, data event, insight 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-корзинами, такие как GetObject, DeleteObject и PutObject
  • вызовы AWS Lambda-функций
  • операции с Amazon DynamoDB, например PutItem, DeleteItem и UpdateItem

И т.д.

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

Insights events

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

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

CloudTrail trail

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

Создание CloudTrail trail

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

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

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

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

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

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

Оставляем 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() для полей:

{{Message.extract(/AlarmDescription":"(.+)","AWSAccountId"/)}}

AWS account ID: {{Message.extract(/AWSAccountId":"(.+)","NewStateValue"/)}}

AWS region: {{Message.extract(/Region":"(.+)","AlarmArn"/)}}

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

Готово.