El problema de los picos de tráfico inesperados en NAT Gateway
Lidiar con picos de tráfico inesperados en el servicio Network Address Translation (NAT) Gateways de AWS puede ser todo un desafío. Si bien los VPC Flow Logs aportan información valiosa sobre el tráfico de red, registrarlos de forma continua puede generar costos de almacenamiento innecesarios y una avalancha de datos que tal vez no sean relevantes en la operación normal.
¿Y si pudieras habilitar los VPC Flow Logs de forma selectiva, solo cuando se detecta un aumento de tráfico?
En este artículo se explora una solución que crea de forma dinámica un grabador temporal de VPC Flow Logs cuando se supera un umbral de tráfico predefinido. Con este enfoque se logra rentabilidad al minimizar el almacenamiento de datos y, a la vez, se obtiene información clave para investigar y entender patrones de tráfico inesperados.
¿Por qué prestar atención al tráfico que pasa por los NAT Gateways?
Usar NAT Gateways tiene un costo. Pagas por mantenerlo activo, lo que en la región de North Virginia equivale a $0.045 por hora. También pagas por el volumen de tráfico que lo atraviesa: $0.045 por GB de entrada/salida. Esto aplica a todo lo que pasa por el NAT Gateway, incluso cuando se trata de un recurso regional como S3.
Esto puede sumar muy rápido, ya que por cada TB de datos pagarás:
1,024GB x $0.045 = $46.08
Para 10TB, serán $460.
Y así sucesivamente.
Este blog surgió porque un cliente nos pidió consejo sobre un tráfico inesperado a través de su NAT Gateway que se disparaba aleatoriamente a 35TB y le generaba un costo adicional e inesperado de $1600 por pico. No tenía idea de por qué ocurría y no quería activar VPC Flow Logs durante todo el mes (más abajo, en la sección sobre los costos de VPC Flow Logs, verás por qué).
Cómo funcionan los VPC Flow Logs
Citando la documentación de AWS, que lo explica con claridad:
VPC Flow Logs es una funcionalidad que te permite capturar información sobre el tráfico IP que entra y sale de las interfaces de red en tu VPC. Los datos del flow log pueden publicarse en las siguientes ubicaciones: Amazon CloudWatch Logs, Amazon S3 o Amazon Data Firehose. Una vez creado un flow log, puedes recuperar y visualizar los registros en el log group, bucket o stream de entrega que configuraste.
Los flow logs sirven para varias tareas, como:
\* Diagnosticar reglas de security group demasiado restrictivas
\* Monitorear el tráfico que llega a tu instancia
\* Determinar la dirección del tráfico hacia y desde las interfaces de red
Los datos del flow log se recolectan fuera de la ruta del tráfico de red, por lo que no afectan el throughput ni la latencia. Puedes crear o eliminar flow logs sin riesgo de impactar el desempeño de la red.
Este blog y su repositorio asociado se refieren a la grabación del tráfico y a su ingesta en un log group específico de Amazon CloudWatch Logs, donde se conservan todos los logs de tráfico para su análisis.
Por defecto, si habilitas VPC Flow Logs para un NAT Gateway, los logs tendrán el siguiente formato y podrás verlos en su respectivo CloudWatch Log Group:

Registros típicos de Flow Logs en CloudWatch Logs
El costo de grabar VPC Flow Logs de forma continua
Este blog se enfoca en almacenar los datos grabados en CloudWatch Log Groups, así que es importante entender los costos asociados a la ingesta de datos en los logs. Consulta los Precios de CloudWatch Logs como referencia aquí.
Supongamos que estás usando 10 NAT Gateways, cada uno enviando 1K solicitudes por segundo desde tus servicios hacia Internet y recibiendo solo una respuesta por cada solicitud. Grabar este tráfico con VPC Flow Logs hará que se ingesten 2000 registros (1K enviados + 1K de la respuesta) por segundo en CloudWatch Logs vía VPC Flow Logs.
Asumamos que cada registro pesa 100 bytes (puede ser menos o más, según el nivel de detalle que quieras). Cada mes, CloudWatch Logs ingestará registros con un tamaño total de:
10 (NAT Gateways) X 2000 (registros por segundo) X 100 (bytes por registro) X 86,400 (segundos por día) X 30.5 (días promedio por mes) = 5,270,400,000,000 bytes.
Es decir, alrededor de 5.2TB ingestados por mes.
El cálculo del costo de un mes de ingesta de estos datos se basa en el precio de $0.5 por GB para ingestar hasta 10TB de datos:
5200GB * 0.5 ($ por GB )= $2600 por mes (puede ser la mitad, es decir, "solo" $1300 si lo ingestas en un CloudWatch Logs Group configurado en la clase Infrequent Access Log).
Ahora supón que los picos de tráfico que quieres detectar ocurren solo una o dos veces al mes, duran apenas 15 minutos y mueven mucho dato a través del NAT Gateway durante ese lapso.
Ten en cuenta que la cantidad de datos transferidos no implica necesariamente que se generen más registros en el VPC Flow Log.
Considera, por ejemplo, la diferencia entre pasar un archivo de 10MB o uno de 1KB por un NAT Gateway. Cada archivo transferido a través de un NAT Gateway generará solo un registro. El archivo de 10MB no generará más de un registro de VPC Flow Log, aunque sea más grande que el de 1KB, que también generará un único registro.
El costo del tráfico del NAT Gateway se multiplicará por un factor de 10⁰⁴ debido al volumen de tráfico mucho más alto.
Queremos capturar estos picos sin pagar un mes entero de grabación de VPC Flow Logs.
Activar VPC Flow Logs temporales
La solución asegura que los VPC Flow Logs se graben cuando el tráfico de un NAT Gateway supera cierto umbral. Por ejemplo, si el patrón de tráfico habitual de un NAT Gateway es de 10MB por minuto, podrías configurar una alarma para que se active cuando el tráfico exceda los 100MB por minuto durante un tiempo determinado.
Esta solución no es práctica para picos de tráfico muy cortos, ya que los VPC Flow Logs solo se crean después de detectar el pico. Aunque el pico no necesita ser muy largo para ser capturado, debe durar más de 3 minutos para asegurar que se inicie la grabación del tráfico.
Arquitectura de la solución
La solución crea una alarma de CloudWatch para cada NAT Gateway que especifiques durante la instalación.
Estas alarmas son detectadas por una EventBridge Rule que dispara una Step Function.
La Step Function se encarga de iniciar la grabación de VPC Flow Logs para el NAT Gateway en estado de alarma. Luego elimina el proceso de grabación de VPC Flow Logs, pero conserva los datos ya registrados. Al finalizar la grabación, SNS envía un correo electrónico a la dirección proporcionada durante la instalación.
La solución se implementa con AWS SAM y consta de dos stacks de CloudFormation. El primer stack despliega macros de CloudFormation para agilizar el proceso de implementación. Estas macros incluyen:
- Una macro para generar automáticamente alarmas de CloudWatch para cada NAT Gateway especificado, simplificando la configuración.
- Otra macro que aborda una limitación de CloudFormation que no permite convertir parámetros tipo string a enteros.
El segundo stack crea los componentes principales de la solución:
- Tabla DynamoDB: esta tabla almacena el conteo de grabaciones realizadas por NAT Gateway y guarda un callback token que se utiliza cuando la alarma vuelve al estado "OK".
(Un callback token se genera dentro de un Task de Step Function. Cuando este task se ejecuta, espera a ser notificado antes de continuar al siguiente paso. La función Lambda que se dispara cuando la alarma vuelve a "OK" lo lee y lo usa para "avisarle" a la Step Function que deje de esperar y reanude la operación).
Esto ayuda a gestionar el proceso de grabación y asegura una reanudación fluida una vez que se resuelve la alarma.
- Alarmas de CloudWatch: estas alarmas monitorean los NAT Gateways especificados para detectar tráfico que supere el umbral definido.
- EventBridge Rules: se configuran dos reglas de EventBridge para orquestar el flujo de trabajo. Una regla dispara una Step Function cuando se activa la alarma de CloudWatch, mientras que la otra dispara una función Lambda cuando la alarma vuelve a "OK". Con este enfoque event-driven se garantiza una respuesta oportuna ante las fluctuaciones de tráfico.
- Step Function: la Step Function orquesta la creación, gestión y eliminación de los VPC Flow Logs. Incluye los siguientes pasos:
— Verificación para asegurar que no se haya alcanzado el número máximo de grabaciones deseadas, evitando grabaciones innecesarias.
— Creación de VPC Flow Logs para cada ENI asociada al NAT Gateway, capturando información detallada del tráfico.
— Un estado de espera que pausa el flujo hasta que la alarma vuelva a "OK" o se alcance un límite de tiempo predefinido, asegurando que la grabación continúe el tiempo suficiente.
— Eliminación de la configuración de VPC Flow Log, conservando los logs grabados durante el tiempo elegido al desplegar el Stack de CloudFormation.
— Envío de una notificación por correo electrónico vía SNS a los destinatarios designados, con actualizaciones oportunas sobre el estado de la grabación.
- Funciones Lambda:
Hay dos funciones. Una se invoca desde la Step Function para obtener las ENIs del NAT Gateway en estado de alarma y crear los VPC Flow Logs para esas ENIs. La otra se dispara con la EventBridge Rule cuando la alarma de CloudWatch vuelve a "OK". Recupera el callback token de la Step Function desde DynamoDB y llama a la Step Function para que reanude su operación.
La estructura de la Step Function se ve así:

Almacenamiento y análisis eficiente de logs
Esta solución utiliza la clase de almacenamiento Infrequent Access de CloudWatch Logs Group para guardar los VPC Flow Logs. Esta clase ofrece una opción rentable y permite consultar y analizar los datos de forma eficiente con CloudWatch Logs Insights.
Análisis de los datos de VPC Flow Log
Al final de una sesión de grabación de VPC Flow Logs, se envía un correo electrónico con un deep link al VPC Flow Logs Group creado y el prefijo de los log streams grabados.
La solución incluye un formato de consulta predefinido para CloudWatch Logs Insights que te permite extraer información valiosa de los datos recolectados. Puedes ejecutar la siguiente consulta de CloudWatch Logs Insight sobre el Flow Log entrando a CloudWatch Logs Insights y eligiendo la consulta llamada "Serverless Auto VPC Flow Log Recorder" en la sección "Saved Queries" para obtener una salida legible.
fields @timestamp, @message
| parse @message "* * * * * * * * * * * * * *" as action, flowDirection, trafficPathNum, srcAddr, srcPort, dstAddr, dstPort, proto, bytes, type, pkt_srcaddr, SrcService, pkt_dstaddr, DstService
| display @timestamp, action, flowDirection,
if(trafficPathNum == 1, "Through another resource in the same VPC",
if(trafficPathNum == 2, "Through an internet gateway or a gateway VPC endpoint",
if(trafficPathNum == 3, "Through a virtual private gateway",
if(trafficPathNum == 4, "Through an intra-region VPC peering connection",
if(trafficPathNum == 5, "Through an inter-region VPC peering connection",
if(trafficPathNum == 6, "Through a local gateway",
if(trafficPathNum == 7, "Through a gateway VPC endpoint (Nitro-based instances only)",
if(trafficPathNum == 8, "Through an internet gateway (Nitro-based instances only)",
"unknown")))))))) as trafficPath,
srcAddr, srcPort, dstAddr, dstPort,
if(proto == 6, "TCP",
if(proto == 17, "UDP",
proto)) as protocol,
bytes, type, pkt_srcaddr, SrcService, pkt_dstaddr, DstService
| sort @timestamp desc
| limit 1000
A continuación, un ejemplo de la salida de esta consulta, que muestra que el VPC S3 Gateway Endpoint no estaba configurado en la VPC. Como resultado, el tráfico hacia S3 pasa por el NAT Gateway y por Internet.
Identificar tráfico enrutado a través de Internet
La solución también destaca la capacidad de identificar el tráfico que circula por Internet en lugar de hacerlo por VPC endpoints. Si el tráfico se dirige a un servicio de AWS por Internet, el nombre del servicio aparece en los campos SrcService o DstService de la salida de CloudWatch Logs Insights (ver el ejemplo anterior con tráfico hacia el servicio S3). Con esta información se puede determinar si conviene configurar VPC endpoints para servicios específicos, mejorando la seguridad y reduciendo costos.
Repositorio de GitHub asociado
Puedes revisar y seguir las instrucciones de instalación de esta solución en este repositorio de GitHub.
Llamada a la acción
Espero que este artículo te haya aportado información valiosa. Si quieres saber más o te interesan nuestros servicios, no dudes en escribirnos. Puedes contactarnos aquí
Referencias adicionales
Actualización de febrero de 2025
El repositorio de GitHub asociado tiene una nueva rama llamada JSONata, que contiene una versión actualizada del ASL de la Step Function que utiliza JSONata y variables para lograr un código más compacto, claro e inteligente. El propio ASL fue extraído del template YAML de SAM a su propio archivo JSON, referenciado desde el template.
La solución propuesta solo registra metadatos del tráfico que pasa por los NAT Gateways cuando el volumen supera cierto umbral, con lo que se reducen los costos y el logging de datos irrelevantes. Una solución serverless reduce aún más los costos al asegurar que no pagas mientras no se grabe nada.