Introducción
En este tutorial, aprenderá a configurar una solución de seguridad de AWS con Terraform. Utilizará los servicios Amazon GuardDuty, Amazon SNS, AWS Lambda y Amazon EvenBridge.
La Detección de Amenazas y Respuesta a Incidentes (TDIR) puede ser un proceso manual y lento para muchas organizaciones. Esto genera procesos de respuesta inconsistentes, resultados de seguridad inconsistentes y un mayor riesgo. En este tutorial, aprenderá a automatizar los hallazgos de detección de amenazas y su proceso de respuesta a incidentes, reduciendo así el tiempo de respuesta. Dado que muchas organizaciones prefieren usar herramientas estándar de infraestructura como código (IaC) para lograr configuraciones consistentes entre proveedores, este tutorial muestra cómo configurar esta solución con Terraform.
Requisitos previos
- cuenta de AWS
Acerca de Amazon GuardDuty
Antes de profundizar en el tutorial, es útil comprender la funcionalidad básica de algunas de las herramientas que utilizaremos. Amazon GuardDuty ofrece detección de amenazas que permite supervisar y proteger continuamente las cuentas de AWS, las cargas de trabajo y los datos almacenados en Amazon Simple Storage Service (S3). GuardDuty analiza los flujos continuos de metadatos generados por su cuenta y la actividad de red que se encuentra en los eventos de AWS CloudTrail, los registros de flujo de Amazon Virtual Private Cloud (VPC) y los registros del Sistema de Nombres de Dominio (DNS). GuardDuty también utiliza inteligencia de amenazas integrada, como direcciones IP maliciosas conocidas, detección de anomalías y aprendizaje automático (ML), para identificar las amenazas con mayor precisión.
GuardDuty funciona con total independencia de sus recursos, por lo que no hay riesgo de que el rendimiento ni la disponibilidad afecten a sus cargas de trabajo. El servicio está totalmente gestionado con inteligencia de amenazas integrada, detección de anomalías y aprendizaje automático. Amazon GuardDuty ofrece alertas precisas y prácticas que se integran fácilmente con los sistemas y flujos de trabajo de gestión de eventos existentes. No hay costes iniciales y solo paga por los eventos analizados, sin necesidad de implementar software adicional ni suscribirse a fuentes de inteligencia de amenazas.
Acerca de Terraform y Cloud9
Terraform es una herramienta de Infraestructura como Código (IaC) creada por Hashicorp que permite gestionar la infraestructura con archivos de configuración en lugar de una interfaz de usuario. Con Terraform, puede crear, modificar y destruir su infraestructura mediante archivos de configuración declarativos legibles. Sí, también puede crear, modificar y destruir la infraestructura de AWS con Terraform, mediante un complemento llamado Provider. El proveedor de AWS permite a Terraform interactuar con la interfaz de programación de aplicaciones (API) de AWS.
Este tutorial utiliza AWS Cloud9 para configurar Terraform. AWS Cloud9 es un entorno de desarrollo integrado (IDE) basado en la nube que permite escribir, ejecutar y depurar código con solo un navegador. Incluye un editor de código, un depurador y una terminal. Cloud9 incluye herramientas esenciales para lenguajes de programación populares, como JavaScript, Python, PHP y Terraform, por lo que no es necesario instalar ningún archivo ni configurar el equipo de desarrollo para comenzar con este taller. Cloud9 se ejecuta en una instancia EC2 que se crea automáticamente al comenzar este taller.
Lo que harás
- Un host de “contacto” interactúa con un host “en riesgo”, lo que hace que GuardDuty informe un hallazgo.
- Este hallazgo se refleja en una regla de EventBridge que creará con Terraform. La regla de EventBridge cumple dos funciones:
- Crea una regla de SNS que se creará con Terraform. Esta regla envía un correo electrónico a un administrador definido con texto legible que explica los hallazgos.
- Activa una función Lambda que crearás con Terraform. Esta función Lambda envía el host comprometido a un grupo de seguridad forense, donde lo aísla para una investigación más profunda.
Paso 1. Descargar la configuración inicial
Este tutorial utiliza una plantilla de AWS CloudFormation para aprovisionar los recursos iniciales. Esto le permite centrarse únicamente en la configuración básica de su solución de seguridad. La plantilla de CloudFormation crea una pila. Esta pila consta de una instancia del IDE de AWS Cloud9. Usamos esta instancia de Cloud9 para que todos los que ejecuten este tutorial tengan la misma experiencia de edición e implementación. Además, al implementar la pila en US-WEST-2, se asegura de que exista una instancia t3.small. Si la plantilla se implementa en otras regiones, es posible que deba modificarla para usar un tipo de instancia diferente si t3.small no está disponible.
1.1. Vaya a AWS CloudFormation en la consola de administración de AWS y cree una pila haciendo clic en el botón "Crear pila".

1.2. Seleccione "Subir archivo de plantilla" y cargue el archivo gd-iac-initial.yml desde el repositorio de código de ejemplo proporcionado anteriormente. Luego, haga clic en "Siguiente".

1.3. Ingrese un nombre para la pila y haga clic en Siguiente.

1.4. En la página Configurar opciones de pila, haga clic en Siguiente.

1.5. En la página de revisión, desplácese hacia abajo y marque la casilla para confirmar que AWS CloudFormation puede crear recursos de IAM. Luego, haga clic en Siguiente.

1.6. Asegúrese de que la pila esté en un estado completamente creado.
En este punto, ya ha implementado los recursos iniciales que usará para seguir este tutorial por su cuenta. En el siguiente paso, accederá a la instancia de Cloud9 que creó la pila e inicializará Terraform.
Paso 2. Acceda a Cloud9 e inicie Terraform
2.1. Abra AWS Cloud9 en la consola de administración de AWS y abra el entorno en el IDE de Cloud9.

2.2. En las preferencias de Cloud9, deshabilite el uso de credenciales temporales administradas por AWS.

2.3. Desde la terminal de la instancia de Cloud9, simule el repositorio de código fuente.
git clone https://github.com/build-on-aws/automating-amazon-guardduty-with-iac.git
2.4. Cambie al directorio automating-amazon-guardduty-with-iac y ejecute terraform init, terraform plan y terraform apply.
Una solicitud exitosa se verá así:

2.5. Verifique que haya dos nuevas instancias EC2, una denominada IAC Tutorial: Instancia comprometida y la otra denominada IAC Tutorial: Instancia maliciosa.
En este punto, ha implementado una VPC y dos instancias de EC2. Ambas instancias de EC2 se comunican entre sí y, posteriormente, al agregar una dirección IP de una de las instancias de EC2 Elastic a la lista de amenazas, GuardDuty genera un hallazgo. A partir de este punto, creará cada uno de los recursos que forman parte de la solución de seguridad.
Paso 3: Crear un depósito S3 para almacenar la lista de amenazas
GuardDuty puede hacer referencia a dos tipos de listas: una lista de IP de confianza y una lista de IP de amenaza. GuardDuty no genera hallazgos para las direcciones IP incluidas en las listas de IP de confianza, pero sí para las incluidas en las listas de IP de amenaza. Dado que en este tutorial queremos forzar un hallazgo, usaremos una lista de IP de amenaza.
3.1. Comience creando una variable en modules/s3/variables.tf para vpc_id.
variable "vpc_id" {
}
3.2. A continuación, en el archivo modules/s3/main.tf, obtenga el número de cuenta actual de AWS y cree un recurso de bucket S3.
# GET CURRENT AWS ACCOUNT NUMBER
data "aws_caller_identity" "current" {}
# CREATE TWO S3 BUCKETS
resource "aws_s3_bucket" "bucket" {
bucket = "guardduty-example-${data.aws_caller_identity.current.account_id}-us-east-1"
force_destroy = true
}
resource "aws_s3_bucket" "flow-log-bucket" {
bucket = "vpc-flow-logs-${data.aws_caller_identity.current.account_id}-us-east-1"
force_destroy = true
}
3.3. A continuación, habilite los registros de flujo de VPC en el bucket S3. Esto no es obligatorio, pero nos permite ver los registros que GuardDuty detecta.
# VPC FLOW LOGS
resource "aws_flow_log" "flow_log_example" {
log_destination = aws_s3_bucket.flow-log-bucket.arn
log_destination_type = "s3"
traffic_type = "ALL"
vpc_id = var.vpc_id
}
3.4. Finalmente, exporte los valores bucket_id y bucket_arn en el archivo modules/s3/outputs.tf.
# S3 Bucket id
output "bucket_id" {
value = aws_s3_bucket.bucket.id
description = "Output of s3 bucket id."
}
# S3 Bucket arn
output "bucket_arn" {
value = aws_s3_bucket.bucket.arn
description = "Output of s3 bucket arn."
}
3.5. Ahora regrese al archivo root/main.tf y agregue el bucket S3.
# CREATES S3 BUCKET
module "s3_bucket" {
source = "./modules/s3"
vpc_id = module.iac_vpc.vpc_attributes.id
}
En este punto, ha creado dos buckets de S3. Si desea revisarlos usted mismo, uno es para los registros de flujo de VPC. El otro contiene la lista de amenazas que creará en el siguiente paso.
Paso 4: Crear módulos Terraform de GuardDuty
4.1. Se han creado los archivos del módulo GuardDuty, pero están vacíos, al igual que los archivos de S3. Comience con el archivo modules/guardduty/variables.tf. Aquí debe crear dos variables. La primera es una variable llamada bucket, que usaremos para definir los detalles de la lista de amenazas del bucket de S3. La segunda es la IP maliciosa que hemos añadido al bucket.
variable "bucket" {
}
variable "malicious_ip" {
}
4.2. Luego vaya al archivo modules/guardduty/main.tf.
En este archivo, agregará tres fuentes. La primera es el detector GuardDuty. En la documentación del proveedor, observará que todas las opciones son opcionales; solo es necesario declarar la fuente. Sin embargo, en nuestro ejemplo, estableceremos el valor habilitado en verdadero y también cambiaremos la frecuencia de publicación de finding_publishing_frequency a 15 minutos. El valor predeterminado es una hora.
# ENABLE THE DETECTOR
resource "aws_guardduty_detector" "gd-tutorial" {
enable = true
finding_publishing_frequency = "FIFTEEN_MINUTES"
}
4.3. A continuación, subimos un archivo al bucket S3 que creamos en el paso anterior. Esto no es obligatorio, pero para fines de demostración, usaremos la dirección IP de una de las instancias de EC2 para garantizar que se generen los hallazgos de este tutorial. En el código a continuación, subimos un archivo de texto a nuestro bucket S3, al que llamaremos MyThreatIntelSet, cuyo contenido será la dirección IP de la variable var.malicious_ip.
# ADD THE EIP/MALICIOUS IP TO THE BUCKET AS A TEXT FILE.
resource "aws_s3_object" "MyThreatIntelSet" {
content = var.malicious_ip
bucket = var.bucket
key = "MyThreatIntelSet"
}
4.4. Finalmente, crearemos un recurso llamado aws_guardduty_threatintelset que le indica a GuardDuty que use el archivo ubicado en la ubicación definida (esto es lo que hace activate = true).
# HAVE GUARDDUTY LOOK AT THE TEXT FILE IN S3
resource "aws_guardduty_threatintelset" "Example-Threat-List" {
activate = true
detector_id = aws_guardduty_detector.gd-tutorial.id
format = "TXT"
location = "https://s3.amazonaws.com/${aws_s3_object.MyThreatIntelSet.bucket}/${aws_s3_object.MyThreatIntelSet.key}"
name = "MyThreatIntelSet"
}
4.5. Luego, vaya al archivo root/main.tf y llame al módulo GuardDuty. Necesitamos proporcionar el ID del bucket y la IP maliciosa. Puede ver que estos provienen del módulo S3 y del módulo de cómputo.
# Enable GuardDuty
module "guardduty" {
source = "./modules/guardduty"
bucket = module.s3_bucket.bucket_id
malicious_ip = module.compute.malicious_ip
}
En esta sección, habilitaste GuardDuty, creaste la lista de amenazas y añadiste la dirección IP elástica de la instancia EC2 maliciosa a dicha lista. A continuación, creamos una regla SNS.
Paso 5: Crear el módulo SNS Terraform
En esta sección, usaremos Terraform para crear una regla de SNS. SNS es un servicio de notificaciones simple que permite enviar notificaciones cuando se cumplen ciertos criterios. SNS en sí no implica enviar un mensaje. Para ello, usaremos EventBridge. Sin embargo, dado que EventBridge requiere una regla para enviar notificaciones, primero debemos crear la regla de SNS.
5.1. Primero, en el archivo modules/sns/variables.tf, debe crear dos variables:
- sns_name para nombrar el tema SNS que crearemos.
- Correo electrónico para guardar la dirección de correo electrónico que usamos para suscribirnos a nuestras notificaciones.
A continuación se muestra un ejemplo de nuestras variables para SNS.
variable "sns_name" {
description = "Name of the SNS Topic to be created"
default = "GuardDuty-Example"
}
variable "email" {
description = "Email address for SNS"
}
5.2. Luego, creamos el tema SNS y la suscripción en el archivo modules/sns/main.tf.
Comience por crear un recurso temático.
# Create the SNS topic
resource "aws_sns_topic" "gd_sns_topic" {
name = var.sns_name
}
En el código anterior, se crea un recurso llamado gd_sns_topic por Terraform. En la consola de AWS, se llama "GuardDuty-Example". Esto se debe a que llamamos a la variable var.sns_name y su configuración predeterminada es "GuardDuty-Example".
5.3. A continuación, cree un recurso de política de SNS. Los valores de ARN y Política son obligatorios. La política creada aquí es un documento de política de AWS IAM. Este documento permite que la entidad de servicio events.amazonaws.com publique en el tema en cuestión.
resource "aws_sns_topic_policy" "gd_sns_topic_policy" {
arn = aws_sns_topic.gd_sns_topic.arn
policy = jsonencode(
{
Id = "ID-GD-Topic-Policy"
Statement = [
{
Action = "sns:Publish"
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
Resource = aws_sns_topic.gd_sns_topic.arn
Sid = "SID-GD-Example"
},
]
Version = "2012-10-17"
}
)
}
5.4. A continuación, crea la suscripción al tema. Esta llama al ARN, define el protocolo (en este caso, correo electrónico) y la dirección de correo electrónico a la que se enviará la notificación. En este caso, la dirección de correo electrónico está predefinida, pero puedes configurarla para que la solicite al aplicar Terraform. Además, si se establece endpoint_auto_confirm en falso, el propietario del correo electrónico recibirá un correo electrónico con un enlace que deberá hacer clic para suscribirse a las notificaciones.
# Create the topic subscription
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
topic_arn = aws_sns_topic.gd_sns_topic.arn
protocol = "email"
endpoint = var.email
endpoint_auto_confirms = false
}
5.5. A continuación, en el archivo modules/sns/outputs.tf, queremos generar el ARN del tema para poder referenciarlo en la configuración de EventBridge que realizaremos más adelante.
output "sns_topic_arn" {
value = aws_sns_topic.gd_sns_topic.arn
description = "Output of ARN to call in the eventbridge rule."
}
5.6. Finalmente, regresa al archivo root/main.tf y agrega el tema SNS. Aquí es donde se especifica la dirección de correo electrónico para la suscripción.
# Creates an SNS Topic
module "guardduty_sns_topic" {
source = "./modules/sns"
email = "[email protected]"
}
En esta sección, creó temas de SNS para que se le enviara un correo electrónico si se generaba un hallazgo específico.
Paso 6: Crear el módulo EventBridge Terraform
En esta sección, usará Terraform para crear una regla de EventBridge. Esta regla conecta los dos elementos de esta solución.
¿Cómo funciona EventBridge? Básicamente, EventBridge recibe un evento (un indicador de un cambio en el entorno) y aplica una regla para dirigirlo a un objetivo. Las reglas asocian eventos con objetivos según la estructura del evento, denominada patrón de evento, o según una programación. En este caso, GuardDuty genera un evento para Amazon EventBridge cada vez que se produce un cambio en los hallazgos. El evento se asocia y Amazon EventBridge dirige la regla a un objetivo. En este caso, el objetivo de la regla es una red social. La regla de red social toma los datos encontrados y genera una notificación por correo electrónico al suscriptor.
6.1. La regla EventBridge requiere información sobre GuardDuty y SNS. Comience creando una variable que pueda usarse para el ARN del sujeto de SNS. Haga esto en el archivo modules/eventbridge/variables.tf.
variable "sns_topic_arn" {
}
6.2. A continuación, cree una fuente de regla de evento en el archivo modules/eventbridge/main.tf. Debe definir la fuente y el tipo de evento deseado.
# EVENT RULE RESOURCE
resource "aws_cloudwatch_event_rule" "GuardDuty-Event-EC2-MaliciousIPCaller" {
name = "GuardDuty-Event-EC2-MaliciousIPCaller"
description = "GuardDuty Event: UnauthorizedAccess:EC2/MaliciousIPCaller.Custom"
event_pattern = <<EOF
{
"source": ["aws.guardduty"],
"detail": {
"type": ["UnauthorizedAccess:EC2/MaliciousIPCaller.Custom"]
}
}
EOF
}
6.3. A continuación, defina la fuente del objetivo del evento. Al crear esta fuente, puede mejorar la legibilidad de la notificación por correo electrónico definiendo un transformador de entrada. Esto personaliza lo que EventBridge envía al objetivo del evento. A continuación, obtenemos el ID de GuardDuty, la región y el ID de la instancia de EC2, y creamos una plantilla de entrada que explica brevemente el mensaje. A continuación, puede ver que hemos creado una plantilla de entrada que utiliza la información detallada del hallazgo de GuardDuty en el correo electrónico enviado.
# EVENT TARGET RESOURCE FOR SNS NOTIFICATIONS
resource "aws_cloudwatch_event_target" "sns" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name
target_id = "GuardDuty-Example"
arn = var.sns_topic_arn
input_transformer {
input_paths = {
gdid = "$.detail.id",
region = "$.detail.region",
instanceid = "$.detail.resource.instanceDetails.instanceId"
}
input_template = "\"First GuardDuty Finding for the GuardDuty-IAC tutorial. | ID:<gdid> | The EC2 instance: <instanceid>, may be compromised and should be investigated. Go to https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?macros=current&fId=<gdid>\""
}
}6.4. En la primera regla de evento que creamos, buscamos el evento GuardDuty-Event-EC2-MaliciousIPCaller. Creamos una segunda regla de evento para buscar GuardDuty-Event-IAMUser-MaliciousIPCaller y también enviamos una notificación por correo electrónico.
# EVENT RULE RESOURCE
resource "aws_cloudwatch_event_rule" "GuardDuty-Event-IAMUser-MaliciousIPCaller" {
name = "GuardDuty-Event-IAMUser-MaliciousIPCaller"
description = "GuardDuty Event: UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom"
event_pattern = <<EOF
{
"source": ["aws.guardduty"],
"detail": {
"type": ["UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom", "Discovery:S3/MaliciousIPCaller.Custom"]
}
}
EOF
}
#EVENT TARGET RESOURCE FOR SNS NOTIFICATIONS
resource "aws_cloudwatch_event_target" "iam-sns" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-IAMUser-MaliciousIPCaller.name
target_id = "GuardDuty-Example"
arn = var.sns_topic_arn
input_transformer {
input_paths = {
gdid = "$.detail.id",
region = "$.detail.region",
userName = "$.detail.resource.accessKeyDetails.userName"
}
input_template = "\"Second GuardDuty Finding for the GuardDuty-IAC tutorial. | ID:<gdid> | AWS Region:<region>. An AWS API operation was invoked (userName: <userName>) from an IP address that is included on your threat list and should be investigated.Go to https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?macros=current&fId=<gdid>\""
}
}6.5. Una vez creados los recursos en el módulo, regrese al archivo root/main.tf y agregue la regla EventBridge.
# Create the EventBridge rule
module "guardduty_eventbridge_rule" {
source = "./modules/eventbridge"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
}En esta sección, creó una regla de EventBridge que usa el tema de SNS que creó para enviar un correo electrónico cuando los hallazgos de GuardDuty coinciden. En la siguiente sección, ampliará esta funcionalidad con Lambda.
Paso 7: Crear el módulo Lambda Terraform
En esta sección, usaremos Terraform para crear una función Lambda que realiza una función de remediación en nuestro entorno. El objetivo de este tutorial es migrar nuestro host comprometido a un nuevo grupo de seguridad. De forma similar a cómo EventBridge usaba SNS para generar correos electrónicos, EventBridge encapsulará la función Lambda.
Es importante tener en cuenta que existen diversas estrategias posibles. Para obtener más información, consulte la documentación sobre la creación de respuestas personalizadas a los hallazgos de GuardDuty con eventos de Amazon CloudWatch y el bloqueo automático de tráfico sospechoso con AWS Network Firewall y Amazon GuardDuty.
Antes de comenzar, veamos qué es necesario para que esto suceda.
Actualmente, nuestros hallazgos de GuardDuty se corresponden con una regla de EventBridge con un objetivo: una regla de SNS que envía un correo electrónico. Para mejorar esta capacidad, EventBridge utiliza AWS Lambda como objetivo.
Dado que planeamos acceder a otros recursos en nombre de AWS Lambda, necesitamos crear un rol de IAM para otorgar permisos al servicio. Este rol se denomina servicio y AWS Lambda lo asumirá cuando cambiemos el grupo de seguridad de nuestra instancia EC2.
La imagen a continuación muestra cómo los primeros tres bloques de código se unen para permitir que el servicio AWS Lambda asuma un rol que puede realizar cambios en los grupos de seguridad asignados a las instancias EC2.

7.1. Comience creando el documento de política de IAM en modules/lambda/main.tf. Esta es la relación de confianza para la política.
data "aws_iam_policy_document" "GD-EC2MaliciousIPCaller-policy-document" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
7.2. A continuación, cree una política en línea que se aplique al rol que asumirá AWS Lambda.
resource "aws_iam_role_policy" "GD-EC2MaliciousIPCaller-inline-role-policy" {
name = "GD-EC2MaliciousIPCaller-inline-role-policy"
role = aws_iam_role.GD-Lambda-EC2MaliciousIPCaller-role.id
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : [
"ssm:PutParameter",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateSecurityGroup",
"ec2:DescribeSecurityGroups",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:DescribeInstances",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:DescribeVpcs",
"ec2:ModifyInstanceAttribute",
"lambda:InvokeFunction",
"cloudwatch:PutMetricData",
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource" : "*",
"Effect" : "Allow"
},
{
"Action" : [
"logs:*"
],
"Resource" : "arn:aws:logs:*:*:*",
"Effect" : "Allow"
},
{
"Action" : [
"sns:Publish"
],
"Resource" : var.sns_topic_arn,
"Effect" : "Allow"
}
]
})
}
7.3. Y ahora crea el rol de IAM que asumirá AWS Lambda.
resource "aws_iam_role" "GD-Lambda-EC2MaliciousIPCaller-role" {
name = "GD-Lambda-EC2MaliciousIPCaller-role1"
assume_role_policy = data.aws_iam_policy_document.GD-EC2MaliciousIPCaller-policy-document.json
}
7.4. Cree una fuente de datos que apunte al código.
data "archive_file" "python_lambda_package" {
type = "zip"
source_file = "${path.module}/code/index.py"
output_path = "index.zip"
}
7.5. A continuación, debemos otorgarle a EventBridge acceso a Lambda.
resource "aws_lambda_permission" "GuardDuty-Hands-On-RemediationLambda" {
statement_id = "GuardDutyTerraformRemediationLambdaEC2InvokePermissions"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.GuardDuty-Example-Remediation-EC2MaliciousIPCaller.function_name
principal = "events.amazonaws.com"
}
El bloque anterior permite que EventBridge llame a la función Lambda.
7.6. Finalmente, creamos la fuente de la función Lambda. Para ello, necesitamos crear algunas variables que nos permitan pasar información. Edite el archivo modules/lambda/variables.tf con las siguientes variables:
variable "sns_topic_arn" {
}
variable "compromised_instance_id" {
}
variable "forensic_sg_id" {
}7.7. Luego, regrese al archivo modules/lambda/main.tf y cree el código fuente de la función Lambda. Tenga en cuenta que en el siguiente bloque de código usamos Python 3.9. También hacemos referencia al código Python que comprimimos en index.zip. Finalmente, configuramos algunas variables de entorno en el código fuente: INSTANCE_ID, FORENSICS_SG y TOPIC_ARN. Estas se pasarán de las variables que creamos al entorno de nuestra función Lambda.
# Create the Lambda function Resource
resource "aws_lambda_function" "GuardDuty-Example-Remediation-EC2MaliciousIPCaller" {
function_name = "GuardDuty-Example-Remediation-EC2MaliciousIPCaller"
filename = "index.zip"
source_code_hash = data.archive_file.python_lambda_package.output_base64sha256
role = aws_iam_role.GD-Lambda-EC2MaliciousIPCaller-role.arn
runtime = "python3.9"
handler = "index.handler"
timeout = 10
environment {
variables = {
INSTANCE_ID = var.compromised_instance_id
FORENSICS_SG = var.forensic_sg_id
TOPIC_ARN = var.sns_topic_arn
}
}
}7.8. En el archivo root/main.tf, llame al módulo Lambda y configure el ARN del sujeto de SNS, el ID de la instancia comprometida y el grupo de seguridad forense. Tenga en cuenta que estos valores provienen de los módulos GuardDuty, Compute y VPC.
# CREATE THE LAMBDA FUNCTION
module "lambda" {
source = "./modules/lambda"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
compromised_instance_id = module.compute.compromised_instance_id
forensic_sg_id = module.forensic-security-group.security_group_id
}
7.9. El grupo de seguridad legal aún no se ha creado. Agregue un grupo de seguridad para usarlo.
# CREATES THE FORENSICS_SG SECURITY GROUP
module "forensic-security-group" {
source = "terraform-aws-modules/security-group/aws"
version = "4.17.1"
name = "FORENSIC_SG"
description = "Forensic Security group "
vpc_id = module.iac_vpc.vpc_attributes.id
}7.10. Para acceder al grupo security-legal, necesitamos generarlo. En el archivo root/outputs.tf, generamos el ID del grupo de seguridad.
output "forensic_sg_id" {
value = module.forensic-security-group.security_group_id
description = "Output of forensic sg id created - to place the EC2 instance(s)."
}7.11. Ahora necesitamos configurar la regla EventBridge para enviar los datos encontrados a Lambda. Lo haremos en la siguiente sección. Regrese al archivo modules/eventbridge/main.tf. Agregue un origen de destino de evento para la función Lambda que analiza la regla aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name y establezca el ID de destino en GuardDuty-Example-Remediation. Aquí necesita el ARN de la función Lambda. Este se puede obtener desde el módulo Lambda.
#EVENT TARGET RESOURCE FOR LAMBDA REMEDIATION FUNCTION
resource "aws_cloudwatch_event_target" "lambda_function" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name
target_id = "GuardDuty-Example-Remediation"
arn = var.lambda_remediation_function_arn
}7.12. Si aún no lo ha hecho, agregue la salida al módulo Lambda (modules/lambda/outputs.tf).
output "lambda_remediation_function_arn" {
value = aws_lambda_function.GuardDuty-Example-Remediation-EC2MaliciousIPCaller.arn
}
7.13. Esta variable también debe aplicarse en el módulo EventBridge (modules/eventbridge/variables.tf).
variable "lambda_remediation_function_arn" {
}7.14. Finalmente, agregue lambda_remediation_function_arn al archivo root/main.tf. Esto se incluye en la regla de EventBridge creada anteriormente. El resultado a continuación muestra el bloque de código completo, parte del cual ya existe. Asegúrese de agregar solo el código lambda_remediation_function_arn = module.lambda.lambda_remediation_function_arn al bloque existente.
module "guardduty_eventbridge_rule" {
source = "./modules/eventbridge"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
lambda_remediation_function_arn = module.lambda.lambda_remediation_function_arn
}
En esta sección, creó una función Lambda que aísla un host en riesgo en un grupo de seguridad diferente. EventBridge llama a esta función Lambda cuando un hallazgo de GuardDuty coincide con una regla de EventBridge. En la siguiente sección, aplicará toda la configuración.
Paso 8: Aplique la configuración a su cuenta de AWS
8.1. Ejecute terraform init. Esto inicializará todos los módulos que agregó en este tutorial de código. El resultado debería ser similar al siguiente.

8.2. Hacer un plano del piso.
8.3. Para aplicar los cambios a AWS, ejecute una aplicación Terraform. Tras la aplicación, el resultado debería ser similar al siguiente:
En esta sección, aplicó la configuración de Terraform a su cuenta de AWS. Actualmente, tiene dos instancias de EC2 comunicándose entre sí. Una es maliciosa y su dirección IP se ha añadido a nuestra lista de IP amenazantes. Cuando GuardDuty detecta que esta IP se comunica con nuestra instancia comprometida, genera un hallazgo. Tenemos una regla de EventBridge que coincide con dicho hallazgo y realiza dos acciones: primero, nos envía un correo electrónico para informarnos de lo sucedido y, segundo, llama a una función Lambda para cambiar el grupo de seguridad del host comprometido. En la siguiente sección, verificaremos la configuración en nuestra consola de AWS.
Paso 9: Verifique la solución en la consola de administración de AWS
En esta sección, revisaremos toda la solución en la consola de AWS y verificaremos que el grupo de seguridad se haya migrado cuando los hallazgos aparezcan en GuardDuty y EventBridge active la función Lambda.
También deberías haber recibido un correo electrónico confirmando tu suscripción. Recuerda que debes suscribirte para recibir las notificaciones que has configurado.
Después de suscribirse, vaya a la Consola de administración de AWS para verificar que haya dos instancias EC2 y que ambas estén en el grupo de seguridad principal.
Primero, verifique si hay hosts comprometidos.
A continuación, compruebe si hay hosts maliciosos.
Luego asegúrese de que GuardDuty informe los hallazgos.

Ahora verifique lo que encontró la regla EventBridge.
Luego, revisa el objetivo de la regla EventBridge. Deberías ver un objetivo SNS y un objetivo Lambda.
Revisa la regla de SNS para ver qué hace. Debería enviar un correo electrónico a la dirección que especificaste.
Luego, comprueba la función Lambda. Puedes acceder a ella desde la regla de EventBridge o navegando directamente.
Por último, verifique que la función Lambda haya movido el host comprometido a un nuevo grupo de seguridad.
Dependiendo de cuánto tiempo haya estado esperando, si su configuración coincide con las capturas de pantalla anteriores, habrá creado con éxito una solución de seguridad de AWS completa utilizando Terraform.
































