AWS EC2 как автоматизировать реакцию на инцидент безопасности

Существует стандартная рекомендованная практика реакции на инцидент безопасности для AWS EC2, которая подробно описана в AWS Security Incident Response Guide. Если пересказать коротко: если есть подозрения, что для данного инстанса EC2 произошел какой-либо инцидент безопасности, необходимо как можно быстрее выполнить следующие действия:

1) Изолировать инстанс - поместить его в карантинную группу безопасности, для которой закрыты все входящие порты, за исключением, например, 22го порта с определенных IP-адресов, чтобы системный администратор смог подключиться по ssh. Такая карантинная группа может существовать заранее или должна быть создана в ходе реакции на инцидент.

2) Необходимо сохранить текущее состояние инстанса: снять скриншот консоли, сохранить его в соответствующем S3-бакете, снять снапшоты жестких дисков.

3) Необходимо включить для инстанса защиту от удаления, если она не включена.

4) Пометить инстанс тегами, которые в последствии дадут понять, что этот инстанс на карантине и нуждается в дальнейшем исследовании - в расследовании инцидента.

5) Необходимо отправить сообщения ответственным лицам о том, что перечисленные мероприятия были проведены.

Конечно, если инстансов не много, то проделать 5 перечисленных пунктов руками - это дело 10 минут, но когда их сотни, как у моего клиента, необходима автоматизация данных действий.

В маркетплейсе AWS есть готовое решение для автоматизации реакции на инцидент безопасности, но оно не устроило моего клиента по нескольким причинам, главная из которых в том, что  это сложное и универсальное решение не учитывает конкретную специфику инфраструктуры клиента, регламентов именования и других маленьких нюансов, например, данное решение некорректно ведет себя со spot-инстансами, не применяет шифрование при сохранении данных в бакет. Так же клиенту хотелось, чтобы решение было оформлено в виде консольного скрипта, принимающего минимум параметров: чтобы обязательным параметром был только идентификатор инстанса.

Я не буду приводить здесь полный код моего решения на python и boto3, покажу только основную часть:

if __name__ == "__main__":
account_id = boto3.resource('iam').CurrentUser().arn.split(':')[4]
# Define Argument Parser
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--iid', required=True, help='instance id')
parser.add_argument('-g', '--sgid', required=False, help='security group id')
parser.add_argument('-r', '--region', required=False, help='region')
parser.add_argument('-b', '--bucket', required=False, help='bucket')
parser.add_argument('-t', '--topic', required=False, help='topic')
#разбираю аргумеенты командной строки
args = parser.parse_args()
AREGION = 'us-west-2'
if args.region:
AREGION=args.region
instance_id = args.iid
#проверяю существует ли вообще инстанс с данным ИД
instanceid_is_valid(instance_id)
ec2Client = boto3.client('ec2', region_name=AREGION)
asgClient = boto3.client('autoscaling', region_name=AREGION)
ssmClient = boto3.client('ssm', region_name=AREGION)
#заливать данные в S3-бакет будем с шифрованием ключем - выбираю ключек
kmsClient = boto3.client('kms',region_name=AREGION)
kmskeys = kmsClient.list_keys()
for cmk in kmskeys["Keys"]:
key_info = kmsClient.describe_key(KeyId=cmk["KeyId"])
if key_info["KeyMetadata"]["Description"] == 'test':
KEYID = cmk["KeyId"]
print(KEYID)
break
#если название S3-бакета не передано в аргументах, сформируем название сами согласно правилам, принятым в компании
BUCKET_NAME = "s3-access-logs."+account_id+"-"+AREGION
if args.bucket:
BUCKET_NAME = args.bucket
#для отправки оповещений будем использовать SNS-топик
SNS_TOPIC = "arn:aws:sns:"+AREGION+":"+account_id+":slack-events"
if args.topic:
SNS_TOPIC = args.topic
try:
instance_describe_metadata = ec2Client.describe_instances(
InstanceIds=[
instance_id
],
)
except ValueError as e:
message = 'Unable to get instance metadata' + str(e['ErrorMessage'])
VPC_ID = instance_describe_metadata['Reservations'][0]['Instances'][0]['VpcId']
isolateSG = args.sgid
#изолируем инстанс в карантинную группу
isolate_instance(ec2Client, instance_id, VPC_ID, isolateSG)
#делаем скриншот консоли
console_screenshot(ec2Client, instance_id)
#делаем снапшот дисков
snapshot(ec2Client, instance_id)
#включаем защиту от удаления, если она еще не включена
try:
set_termination_protection(ec2Client, instance_id)
except:
pass
#ставим теги
set_tags(ec2Client, instance_id)
message = 'Security Response mechanism complete for instance: ' + instance_id
print(message)

А если вам необходимо автоматизировать реакцию на инциденты безопасности в вашем аккаунте AWS, обращайтесь.

Комментарии

Популярные сообщения из этого блога

Настройка почты через biz.mail.ru в БитриксВМ

Git обновить текущую ветку из master

AWS S3 - Лучшие практики