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, обращайтесь.
Комментарии