Il problema dei picchi di traffico imprevisti sui NAT Gateway
Gestire picchi di traffico imprevisti sul servizio Network Address Translation (NAT) Gateway di AWS può rivelarsi complesso. I VPC Flow Logs offrono informazioni preziose sul traffico di rete, ma registrarli in modo continuativo si traduce in costi di archiviazione superflui e in una mole di dati spesso poco rilevante durante il normale funzionamento.
E se fosse possibile abilitare i VPC Flow Logs in modo selettivo, soltanto al rilevamento di un'impennata del traffico?
Questo articolo illustra una soluzione che crea dinamicamente un registratore temporaneo di VPC Flow Logs al superamento di una soglia di traffico predefinita. Un approccio efficiente sul piano dei costi, che riduce al minimo l'archiviazione dei dati e fornisce al tempo stesso le informazioni indispensabili per analizzare e comprendere pattern di traffico anomali.
Perché tenere d'occhio il traffico sui NAT Gateway?
I NAT Gateway hanno un costo. Si paga per tenerli attivi: nella regione North Virginia la tariffa è di 0,045 $ all'ora. E si paga anche per il volume di traffico che li attraversa, ovvero 0,045 $ per GB in ingresso/uscita. Il conteggio riguarda tutto ciò che transita dal NAT Gateway, comprese le risorse regionali come S3.
I costi possono salire molto in fretta: per ogni TB di dati si pagheranno:
1.024 GB x 0,045 $ = 46,08 $
Per 10 TB il costo sale a 460 $.
E così via.
Questo articolo nasce dalla richiesta di un cliente alle prese con un traffico imprevisto sul NAT Gateway che generava picchi casuali fino a 35 TB, con un costo aggiuntivo e inatteso di 1.600 $ a picco. Non aveva idea della causa e non voleva attivare i VPC Flow Logs per l'intero mese (più avanti, nella sezione sui costi dei VPC Flow Logs, ne capiremo il motivo).
Come funzionano i VPC Flow Logs
Citando la documentazione di AWS, che lo spiega in modo chiaro:
VPC Flow Logs è una funzionalità che consente di acquisire informazioni sul traffico IP da e verso le interfacce di rete del VPC. I dati dei flow log possono essere pubblicati nelle seguenti destinazioni: Amazon CloudWatch Logs, Amazon S3 o Amazon Data Firehose. Una volta creato un flow log, è possibile recuperare e visualizzare i record nel log group, nel bucket o nel delivery stream configurato.
I flow log si rivelano utili per diverse attività, ad esempio:
\* Diagnosticare regole di security group eccessivamente restrittive
\* Monitorare il traffico in arrivo sull'istanza
\* Determinare la direzione del traffico da e verso le interfacce di rete
I dati dei flow log vengono raccolti al di fuori del percorso del traffico di rete e quindi non incidono sul throughput né sulla latenza. È possibile creare o eliminare flow log senza alcun rischio per le prestazioni di rete.
Questo articolo e il repository associato fanno riferimento alla registrazione del traffico e alla sua acquisizione in un log group dedicato di Amazon CloudWatch Logs, dove tutti i log del traffico vengono conservati e resi disponibili per l'analisi.
Per impostazione predefinita, abilitando i VPC Flow Logs su un NAT Gateway, i log assumeranno il formato seguente e saranno consultabili nel rispettivo CloudWatch Log Group:

Tipici record dei Flow Logs in CloudWatch Logs
Il costo della registrazione continua dei VPC Flow Logs
L'articolo fa riferimento all'archiviazione dei dati registrati nei CloudWatch Log Group, perciò è importante comprendere i costi associati ai dati ingeriti nei log. Per riferimento, si rimanda al listino prezzi di CloudWatch Logs qui.
Ipotizziamo di utilizzare 10 NAT Gateway, ciascuno dei quali invia 1K richieste al secondo dai propri servizi verso Internet, ricevendo una sola risposta per ogni richiesta. Registrare questo traffico con i VPC Flow Logs comporta l'ingestione di 2.000 record al secondo (1K inviati + 1K dalle risposte) in CloudWatch Logs tramite i VPC Flow Logs.
Supponiamo che ogni record pesi 100 byte (può essere meno o più, a seconda del livello di dettaglio desiderato). Ogni mese, CloudWatch Logs ingerirà record per una dimensione complessiva di:
10 (NAT Gateway) X 2.000 (record al secondo) X 100 (byte per record) X 86.400 (secondi al giorno) X 30,5 (giorni medi al mese) = 5.270.400.000.000 byte.
Quindi, circa 5,2 TB ingeriti al mese.
Il costo di un mese di ingestione di questi dati si calcola sulla tariffa di 0,5 $ per GB, valida per l'ingestione fino a 10 TB di dati:
5.200 GB * 0,5 ($ per GB ) = 2.600 $ al mese (l'importo può dimezzarsi a "soli" 1.300 $ se l'ingestione avviene in un CloudWatch Logs Group impostato sulla classe di log Infrequent Access).
Ipotizziamo ora che i picchi di traffico da catturare si verifichino solo una o due volte al mese, durino appena 15 minuti e facciano transitare un volume elevato di dati attraverso il NAT Gateway in quell'arco di tempo.
Va notato che la quantità di dati trasmessi non implica necessariamente la creazione di un numero maggiore di record nel VPC Flow Log.
Si pensi, ad esempio, alla differenza tra il transito di un file da 10 MB e di uno da 1 KB attraverso un NAT Gateway. Ogni file trasferito tramite NAT Gateway genera un solo record. Il file da 10 MB non produrrà più di un record VPC Flow Log, pur essendo più grande del file da 1 KB, che a sua volta genererà un singolo record.
Il costo del traffico sul NAT Gateway crescerà di un fattore 10⁰⁴, a causa del volume di traffico molto più elevato.
L'obiettivo è catturare questi picchi senza dover pagare un mese intero di registrazione dei VPC Flow Logs.
Attivare VPC Flow Logs temporanei
La soluzione fa in modo che i VPC Flow Logs vengano registrati quando il traffico di un NAT Gateway supera una determinata soglia. Ad esempio, se il traffico abituale di un NAT Gateway è di 10 MB al minuto, si può impostare un allarme che scatta quando il traffico supera i 100 MB al minuto per un periodo di tempo definito.
La soluzione non è adatta a picchi di traffico molto brevi, dato che i VPC Flow Logs vengono creati solo dopo il rilevamento del picco. Il picco non deve essere lunghissimo per essere catturato, ma deve durare più di 3 minuti per garantire l'avvio della registrazione del traffico.
Architettura della soluzione
La soluzione crea un CloudWatch Alarm per ciascun NAT Gateway specificato in fase di installazione.
Questi allarmi vengono intercettati da una EventBridge Rule che attiva una Step Function.
La Step Function si occupa di avviare la registrazione VPC Flow Log per il NAT Gateway in stato di allarme. Successivamente elimina il processo di registrazione dei VPC Flow Logs, ma conserva i dati registrati. Al termine della registrazione, SNS invia un'email all'indirizzo fornito durante l'installazione.
La soluzione è implementata con AWS SAM ed è composta da due stack CloudFormation. Il primo stack distribuisce alcune macro CloudFormation per snellire il processo di deployment. Tra queste:
- Una macro che genera automaticamente i CloudWatch alarm per ciascun NAT Gateway specificato, semplificando la configurazione.
- Un'altra macro che aggira un limite di CloudFormation, ovvero l'impossibilità di convertire parametri di tipo stringa in interi.
Il secondo stack crea i componenti principali della soluzione:
- Tabella DynamoDB: memorizza il numero di registrazioni effettuate per ciascun NAT Gateway e contiene un callback token utilizzato quando l'allarme torna allo stato "OK".
(Un callback token viene generato all'interno di un Task della Step Function. Quando il task è in esecuzione, attende una notifica prima di passare allo step successivo. La funzione Lambda attivata dal ritorno dell'allarme allo stato "OK" legge il token e lo utilizza per "comunicare" alla Step Function di interrompere l'attesa e riprendere l'esecuzione).
In questo modo si gestisce il processo di registrazione e si garantisce una ripresa fluida una volta risolto l'allarme.
- CloudWatch Alarms: monitorano i NAT Gateway specificati per individuare il traffico che supera la soglia definita.
- EventBridge Rules: due regole EventBridge orchestrano il flusso di lavoro. La prima attiva una Step Function quando il CloudWatch alarm scatta, la seconda attiva una funzione Lambda quando l'allarme torna allo stato "OK". Questo approccio event-driven garantisce una risposta tempestiva alle fluttuazioni del traffico.
- Step Function: orchestra creazione, gestione ed eliminazione dei VPC Flow Logs. Comprende i seguenti passaggi:
— Verifica del mancato raggiungimento del numero massimo di registrazioni desiderato, per evitare registrazioni superflue.
— Creazione dei VPC Flow Logs per ciascuna ENI associata al NAT Gateway, con acquisizione di informazioni di traffico dettagliate.
— Uno stato di attesa che mette in pausa il flusso di lavoro fino al ritorno dell'allarme allo stato "OK" o al raggiungimento di un limite di tempo predefinito, garantendo una durata di registrazione sufficiente.
— Eliminazione della configurazione dei VPC Flow Log, mantenendo i log registrati per il tempo scelto durante il deployment dello Stack CloudFormation.
— Invio di una notifica email tramite SNS ai destinatari designati, con aggiornamenti tempestivi sullo stato della registrazione.
- Funzioni Lambda:
Le funzioni sono due. La prima viene richiamata dalla Step Function per recuperare le ENI del NAT Gateway in stato di allarme e creare i relativi VPC Flow Logs. La seconda viene attivata dalla EventBridge Rule quando il CloudWatch alarm torna allo stato "OK": recupera il callback token della Step Function da DynamoDB e richiama la Step Function per farle riprendere l'esecuzione.
Di seguito la struttura della Step function:

Archiviazione e analisi efficiente dei log
La soluzione utilizza la classe di archiviazione Infrequent Access dei CloudWatch Logs Group per memorizzare i VPC Flow Logs. Si tratta di un'opzione conveniente, che consente di interrogare e analizzare i dati in modo efficiente con CloudWatch Logs Insights.
Analizzare i dati dei VPC Flow Log
Al termine di una sessione di registrazione dei VPC Flow Logs, viene inviata un'email con un deep link al VPC Flow Logs Group creato e con il prefisso degli stream di log registrati.
La soluzione fornisce un formato di query predefinito per CloudWatch Logs Insights, che permette di estrarre informazioni significative dai dati raccolti. Per ottenere un output leggibile è possibile eseguire la seguente CloudWatch Logs Insight Query sul Flow Log: basta accedere a CloudWatch Logs Insights e selezionare la query "Serverless Auto VPC Flow Log Recorder" nella sezione "Saved Queries".
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
Di seguito un esempio dell'output di questa query, che evidenzia come il VPC S3 Gateway Endpoint non sia stato configurato nel VPC. Di conseguenza, il traffico verso S3 transita dal NAT Gateway e da Internet.
Identificare il traffico instradato via Internet
La soluzione mette in luce anche la possibilità di individuare il traffico che transita via Internet anziché tramite VPC endpoint. Se il traffico è diretto a un servizio AWS attraverso Internet, il nome del servizio compare nei campi SrcService o DstService dell'output di CloudWatch Logs Insights (si veda l'esempio precedente per il traffico verso il servizio S3). È un'informazione utile per valutare se configurare VPC endpoint per servizi specifici, allo scopo di rafforzare la sicurezza e ridurre i costi.
Repository GitHub di riferimento
È possibile consultare la soluzione e seguirne le istruzioni di installazione in questo repository GitHub.
Invito all'azione
Mi auguro che questo articolo Le abbia offerto spunti utili. Se desidera saperne di più o è interessato ai nostri servizi, non esiti a contattarci. Può farlo qui
Riferimenti aggiuntivi
Aggiornamento di febbraio 2025
Il repository GitHub associato include un nuovo branch chiamato JSONata, con una versione aggiornata della Step Function ASL che sfrutta JSONata e variabili per un codice più compatto, chiaro e intelligente. La ASL stessa è stata estratta dal SAM YAML Template e spostata in un proprio file JSON, referenziato dal Template.
La soluzione proposta registra i metadati del traffico che attraversa i NAT Gateway solo quando il volume supera una determinata soglia, riducendo costi e logging di dati irrilevanti. Una soluzione Serverless abbatte ulteriormente i costi: non si paga finché non viene registrato nulla.