“È sempre colpa del DNS”: come un record vuoto ha bloccato Internet

A cura di Elena Baldino

Introduzione

La vulnerabilità di Internet è un fenomeno noto: errori tecnici, configurazioni errate, componenti critici mal progettati possono causare interruzioni di servizio a livello globale. Il 20 ottobre 2025 un disservizio di Amazon Web Services (AWS) ha interrotto oltre mille servizi a livello globale per circa quindici ore, coinvolgendo milioni di utenti. È stata una delle interruzioni più gravi dell’anno, per impatto e durata, causata da un errore tecnico che ha prodotto un record DNS vuoto e creato effetti a cascata su tutti i servizi cloud interconnessi. Non si è trattato quindi di un attacco informatico, ma di un errore umano e di problemi di progettazione dei sistemi.

L’analisi di questo caso reale offre lo spunto per approfondire le architetture cloud e la progettazione di sistemi resilienti. Per comprendere le dinamiche del disaster recovery è necessario innanzitutto definire alcuni termini tecnici fondamentali:

  • Availability: è la percentuale di tempo in cui un'applicazione o un servizio è accessibile e correttamente funzionante. Si calcola tipicamente su periodi lunghi, come un mese, un anno o tre anni. La disponibilità diminuisce ogni volta che il sistema non è utilizzabile, sia per guasti imprevisti sia per manutenzioni programmate.

  • Failover: è il processo di ripristino di un sistema dopo un arresto anomalo (crash). L’obiettivo è mantenere in funzione il sistema anche in caso di guasti in alcuni suoi componenti.

  • Failback: è il processo di ripristino di un sistema dopo il failover. L’obiettivo è riportare il sistema allo stato precedente al guasto.

  • Resiliency: è la capacità di un sistema o di un'applicazione di resistere ai guasti e di recuperare velocemente in caso di anomalie. Un sistema resiliente continua a funzionare, anche se in modo limitato, nonostante il verificarsi di un problema e si ripristina automaticamente senza perdere dati o richiedere interventi manuali prolungati. Per esempio, se un server si blocca, un sistema resiliente passa automaticamente a un server di backup e gli utenti continuano a usare l'applicazione senza accorgersene.


 

1. Il cloud di AWS

1.1 L’infrastruttura

L’infrastruttura cloud di AWS è organizzata in una struttura gerarchica a tre livelli:

  1. AWS Region: una regione è un’area geografica in cui AWS ha concentrato un insieme di data center. Attualmente ci sono 38 regioni sparse in tutto il mondo, con altre in arrivo. Ogni regione è del tutto indipendente dalle altre. La prima regione, chiamata US-EAST-1, è stata creata nel 2006 in Virginia (U.S.A.).

  2. Availability Zone (AZ): ogni regione è suddivisa in almeno tre AZ. Ogni AZ è composta da uno o più data center fisicamente separati, ma abbastanza vicini tra loro (entro 100 km) per essere collegati con cavi in fibra ottica ad altissima velocità e bassissima latenza. Gli utenti distribuiscono le loro applicazioni su più AZ; in questo modo, se una zona fallisce, l'applicazione continua a funzionare nelle altre.

  3. Edge Location: sono centinaia di piccoli data center distribuiti in tutto il mondo, si trovano ancora più vicini agli utenti finali rispetto alle AZ. Non ospitano applicazioni complete, ma vengono utilizzati per:
    - caching di contenuti (servizio CloudFront): copie temporanee di immagini, video e pagine web vengono salvate vicino all'utente, che così li riceve rapidamente senza dover aspettare che arrivino dal data center principale;
    - ottimizzazione del traffico (AWS Global Accelerator): l’acceleratore instrada il traffico attraverso la rete privata di AWS anziché su Internet, migliorando le prestazioni;
    - servizi DNS (Route 53): traducono i nomi di dominio in indirizzi IP più velocemente; Route 53 funge anche da registrar di domini. Il nome Route 53 sottolinea che si tratta di un servizio di instradamento del traffico (route) che utilizza il protocollo DNS standard (porta 53).


Esempio

 
Vediamo un semplice esempio di come funzionerebbe un ipotetico servizio di streaming video su AWS.

Supponiamo di trovarci a Milano e di volere guardare una serie TV su una piattaforma di streaming video.

La piattaforma ha distribuito la sua applicazione in più regioni AWS contemporaneamente: Europa (Milano), US-EAST-1 (Virginia), Asia Pacific (Tokyo), ecc. Il sistema di login, il database con il nostro profilo e le raccomandazioni personalizzate potrebbero essere gestiti dalla regione Europa (Milano), che è la più vicina a noi. Se l'applicazione fosse stata rilasciata solo in Virginia, ogni volta che facciamo login o cerchiamo un film, la richiesta attraverserebbe l'Atlantico, con la conseguenza di aumentare la latenza e di avere un servizio lento.

All'interno della regione Europa (Milano), l'applicazione viene distribuita su almeno tre Availability Zone diverse. Il database principale si trova in una AZ, mentre le altre AZ mantengono copie sincronizzate (repliche). Se ci fosse un blackout nel data center di una zona, il sistema passerebbe automaticamente a una delle altre zone e l'utente non si accorgerebbe di nulla.

Una volta scelto il film da guardare, il video non viene scaricato dal data center di Milano, ma, tramite Cloud Front, da una Edge Location ancora più vicina, magari proprio a Milano città. CloudFront è la CDN (Content Delivery Network) di AWS: la prima volta che qualcuno in Italia guarda quel film, il video viene copiato (messo in cache) nell'Edge Location italiana, così quando lo selezioniamo parte quasi istantaneamente.

Riassumendo, in questo scenario, il flusso che si genera quando vogliamo vedere un video sarebbe il seguente:

  1. apriamo l'app della piattaforma di streaming, Route 53 identifica la nostra posizione geografica e ci indirizza automaticamente alla regione più vicina, cioè Europa (Milano);

  2. effettuiamo il login e scegliamo il film; questa fase è gestita dalla Regione Milano distribuita su tre AZ. Un load balancer distribuisce automaticamente le richieste tra le diverse zone per bilanciare il carico e offrire una maggiore resilienza;

  3. iniziamo a guardare il video scaricato tramite CloudFront da una Edge Location vicinissima, che ci garantisce la massima velocità possibile.



1.2 I servizi di AWS

Sull’infrastruttura di rete descritta, il cloud computing di Amazon fornisce numerosi servizi web (figura 1): dalle infrastrutture per il calcolo, l’archiviazione e i database, fino alle nuove tecnologie, quali il machine learning e l’intelligenza artificiale.

Un importante servizio offerto sin dalla nascita di AWS è Amazon EC2 (Elastic Compute Cloud), utilizzato per ospitare le applicazioni degli utenti. EC2 offre dei server virtuali che l’utente costruisce in base alle proprie esigenze. Il termine tecnico con cui si fa riferimento a questi server virtuali è istanza: l’utente crea delle istanze nel cloud Amazon dove può eseguire applicazioni, siti web, database o qualsiasi altro software. In base alle necessità del momento è possibile aumentare o diminuire la capacità di calcolo, ossia il numero di server virtuali (il termine elastic sta proprio a indicare la scalabilità on demand).

EC2 è un esempio di IaaS (Infrastructure as a Service).
Figura 1: I principali servizi AWS utilizzati per realizzare soluzioni serverless
Fonte: https://docs.aws.amazon.com/serverless/latest/devguide/serverless-core-services.html


1.3 Il Virtual Private Cloud (VPC)


Inizialmente le istanze EC2 operavano in uno spazio di rete condiviso, chiamato EC2-Classic, che era analogo all’avere un server in un data center pubblico. Per rispondere alle esigenze aziendali di isolamento e di connettività ibrida (collegare il cloud alla rete aziendale fisica), AWS ha introdotto il Virtual Private Cloud (VPC).

Il VPC è un data center virtuale isolato all'interno di AWS, con un proprio range di indirizzi IP privati. Dal 2013 in poi AWS ha rimosso la modalità Classic; ora ogni istanza EC2 deve appartenere a un VPC e risiedere in una subnet specifica.

Per avere un’idea di cosa ciò significhi, possiamo immaginare il VPC come un data center virtuale, le subnet sono le sue stanze (reti logiche più piccole) e le istanze EC2 sono i server collocati in quelle stanze.

AWS crea automaticamente un VPC preconfigurato con subnet pubbliche in ogni AZ per semplificarne l'uso immediato da parte degli utenti.

 

VPC peering: collegare data center virtuali isolati

Per default i VPC sono completamente isolati tra loro, infatti due VPC non possono comunicare direttamente, nemmeno se appartengono allo stesso account AWS. Questo isolamento è fondamentale per la sicurezza, ma crea un problema quando è necessario far comunicare risorse distribuite su VPC diversi, come succede quando si implementano strategie di disaster recovery.

Il VPC peering è la soluzione che consente di creare una connessione di rete privata tra due VPC, permettendo alle risorse in ciascun VPC di comunicare tra loro come se fossero sulla stessa rete.

Il concetto è simile alla VPN site-to-site realizzata nelle reti aziendali tradizionali: quando un'azienda ha due sedi distanti tra loro, utilizza una VPN per creare un tunnel sicuro attraverso Internet che collega le due reti locali. Il VPC peering funziona in modo analogo, ma con differenze importanti:

  • VPN aziendale: crea un tunnel cifrato attraverso una rete pubblica, Internet;

  • VPC peering: crea una connessione diretta sulla rete privata globale di AWS, senza mai transitare su Internet.


Entrambe le soluzioni permettono alle risorse che si trovano in reti separate di comunicare in modo sicuro, ma il VPC peering offre una latenza minore e una maggiore bandwidth, poiché il traffico dati rimane completamente all'interno dell'infrastruttura fisica di AWS.

Un VPC peering può essere stabilito tra VPC nello stesso account AWS o tra account diversi, così come tra regioni differenti (inter-region peering). Una volta accettata la connessione di peering, è necessario aggiornare le route table di entrambi i VPC per instradare il traffico attraverso la connessione creata.

Nell’ottica del disaster recovery, il VPC peering è essenziale per le architetture multi-region. Se abbiamo un’applicazione attiva nella region us-east-1 e una replica in stanby nella region eu-west-1, l’inter-region peering permette la sincronizzazione continua e sicura dei dati tra i database. In caso di emergenza, mentre il peering garantisce che i dati siano già pronti in Europa, sistemi come Route 53 provvederanno a reindirizzare il traffico degli utenti verso la regione secondaria.

Tornando all'analogia precedente, se ogni VPC è un data center virtuale, il VPC peering è come costruire un tunnel privato dedicato tra due edifici distanti: permette ai server di scambiarsi informazioni come se fossero nella stessa stanza, con la massima velocità e senza mai uscire sulla strada pubblica (Internet).

 

2. Il servizio DynamoDB di AWS

Dopo aver visto come funziona l'infrastruttura di AWS e il VPC, approfondiamo DynamoDB, un servizio centrale e nativo di AWS. Si tratta di un database NoSQL completamente gestito, dove l'utente si concentra esclusivamente sui dati e AWS gestisce tutta l'infrastruttura sottostante.

Capire come funziona DynamoDB è importante non solo per comprendere le moderne architetture cloud, ma anche per analizzare cosa può accadere quando sorgono problemi in sistemi così complessi e interconnessi. Infatti, l’interruzione dei servizi AWS del 20 ottobre 2025 è stata causata proprio da un’anomalia nel servizio DNS di AWS, Route 53, conseguenza di problemi con gli endpoint di DynamoDB, evidenziando così quanto i servizi AWS siano interdipendenti.

DynamoDB è un database NoSQL progettato per le applicazioni che richiedono prestazioni elevate e una scalabilità automatica. La differenza principale rispetto ai database tradizionali è nella modalità di gestione:

  • database tradizionale: l'utente installa il software su un server, fisico o EC2, configura il server e gestisce backup, aggiornamenti, monitoraggio, ecc.

  • DynamoDB (managed): AWS gestisce tutta l'infrastruttura sottostante; l'utente crea semplicemente una tabella, definisce la struttura dei dati e AWS si occupa automaticamente di provisioning, aggiornamenti, backup, ecc.


Quando un utente crea una tabella DynamoDB, deve scegliere in quale AWS Region ospitarla. AWS replica i dati su almeno tre Availability Zone della regione scelta, così da garantirne la disponibilità in caso di guasto di una AZ. Questa replica avviene in modo sincrono e automatico.

 

Esempio
Riprendiamo l'esempio della piattaforma di streaming video e introduciamo l’utilizzo di DynamoDB.

Il fornitore del servizio di streaming ha creato le seguenti tabelle nel database DynamoDB nella Regione Europa (Milano):

  • Utenti: memorizza i dati degli utenti della piattaforma, per esempio l’email, la password criptata, le preferenze linguistiche;

  • Profili: memorizza i profili degli utenti, la cronologia delle visualizzazioni, ecc.;

  • Preferenze: salva i film aggiunti ai preferiti, le valutazioni date, ecc.


Quando un utente effettua il login da Milano, l'applicazione di streaming interroga la tabella Utenti in DynamoDB Europa (Milano). I dati vengono recuperati velocemente perché il database è geograficamente vicino. Dal momento che i dati utente sono replicati su tre AZ diverse, se sorgesse un problema in una zona, DynamoDB continuerebbe a funzionare leggendo/scrivendo sulle tabelle nelle altre due zone.

Supponiamo inoltre che il fornitore del servizio di streaming utilizzi il servizio AWS DynamoDB Global Tables: in tal caso, le tabelle verrebbero replicate in automatico in più regioni, per esempio Milano, Virginia e Tokyo. L’utente che si spostasse da Milano negli Stati Uniti in Virginia, una volta effettuato il login troverebbe i suoi dati già disponibili nella regione us-east-1. Quindi, se aggiungesse un nuovo film ai preferiti, la tabella Preferenze verrebbe sincronizzata in tutte le regioni coinvolte.

Questa architettura multi-AZ automatica è uno dei motivi per cui DynamoDB è considerato altamente resiliente. Tuttavia, come vedremo analizzando l'interruzione del 20 ottobre, anche sistemi progettati per l'alta disponibilità possono sperimentare interruzioni quando si verificano problemi a livello di servizi condivisi dell'infrastruttura AWS.

 

2.1 DynamoDB endpoint e la risoluzione DNS

Nei servizi web e cloud, come AWS, un endpoint è l'URL di ingresso, il punto di accesso, per un servizio web. Nel nostro caso, il servizio è DynamoDB. Quando un’applicazione deve leggere o scrivere dati su DynamoDB, deve inviare la richiesta a un endpoint pubblico e unico, che, per una regione AWS, ha una forma simile a:
dynamodb.<regione>.amazonaws.com

Per esempio:
 dynamodb.us-east-1.amazonaws.com

Quando ci connettiamo a questo endpoint, non stiamo raggiungendo un singolo server statico, ma stiamo accedendo a una complessa rete di load balancer e server che AWS utilizza per garantire che DynamoDB sia scalabile (deve gestire enormi quantità di traffico) e sempre disponibile (deve risultare attivo anche quando alcuni server smettono di funzionare).

Per trovare l’indirizzo IP corrispondente all’URL dell’endpoint, si procede come per una normale risoluzione dei nomi su Internet, utilizzando il DNS per arrivare al server autorevole, che in questo caso è il DNS di AWS, ossia Route 53.

Analizziamo passo dopo passo come avviene il processo di risoluzione:

  1. l’applicazione (o il browser) chiede al resolver DNS locale l'indirizzo IP per dynamodb.us-east-1.amazonaws.com;

  2. il resolver DNS locale inizia una ricerca nel sistema DNS: interroga i root server DNS che lo reindirizzano ai server che gestiscono il dominio .com che lo reindirizzano ai server che gestiscono il dominio amazonaws.com;

  3. i server DNS globali reindirizzano la richiesta ai server autoritativi per amazonaws.com, che sono i server di Amazon Route 53;

  4. Amazon Route 53 è il sistema che detiene l'informazione corretta, aggiornata e dinamica per l'endpoint di DynamoDB. Quindi è Route 53 che risponde al resolver DNS locale fornendo l'indirizzo IP del load balancer di DynamoDB più appropriato;

  5. infine, il resolver invia l'indirizzo IP all’applicazione, che può connettersi e comunicare con DynamoDB.


È importante notare che Route 53 non restituisce un indirizzo statico, bensì l’indirizzo IP del load balancer che in quel momento è il più appropriato per gestire la richiesta. Infatti, poiché l'infrastruttura di DynamoDB cambia continuamente, AWS aggiunge o rimuove server per via della scalabilità, il DNS AWS è dinamico e viene aggiornato in tempo reale per puntare sempre all'insieme corretto di indirizzi IP dei load balancer.

 

2.2 La gestione del traffico interno di DynamoDB e l’interazione con Route 53

Il sistema di gestione del traffico interno di DynamoDB si basa su una gestione avanzata dei record DNS, orchestrata da DynamoDB ma applicata tramite Route 53. Per far funzionare questo sistema complesso, DynamoDB gestisce centinaia di migliaia di record DNS interni, che non sono visibili dagli utenti in quanto fanno parte dell’infrastruttura stessa del servizio.

Per garantire l’efficienza e l’affidabilità degli aggiornamenti DNS, DynamoDB divide il lavoro in due sistemi separati ma coordinati:

  • DNS Planner: pianifica come distribuire il traffico in tempo reale, infatti monitora lo stato e la capacità dei load balancer di DynamoDB e genera periodicamente nuovi piani DNS per ciascun endpoint del servizio. In un piano, DNS stabilisce quali load balancer devono ricevere il traffico e qual è la distribuzione del peso tra loro;

  • DNS Enactor: applica il piano elaborato dal DNS Planner; opera in modo indipendente e ridondante su tre diverse AZ, ogni istanza in una zona controlla se ci sono nuovi piani emessi dal DNS Planner e per applicarne le modifiche invia le richieste di aggiornamento dei record DNS al servizio Route 53.


Esempio
Ipotizziamo uno scenario di guasto e vediamo come reagirebbe il sistema appena descritto.

Alle tre del mattino nella regione Europe (Milan) (codice: eu-south-1) un intero rack di load balancer (LB) si spegne:

  1. DNS Planner (entro 1-2 minuti):
    - rileva che 20 LB non rispondono ai controlli (health check);
    - calcola come redistribuire il traffico sui rimanenti LB;
    - pubblica un nuovo piano v1234 in cui non sono più presenti i 20 LB guasti e i pesi sono stati ricalcolati.



  1. DNS Enactor (entro 30 secondi):
    - le tre istanze leggono il piano v1234;
    - aggiornano i record DNS in Route 53;
    - il traffico viene reindirizzato in automatico.



  1. l'utente non ha rilevato un’interruzione del servizio ma solo una latenza un poco più alta per un paio di minuti; le sue query al database DynamoDB continuano a funzionare.



 

3. Il disservizio di AWS del 20 ottobre 2025

Il 20 ottobre 2025, AWS ha subito un’interruzione nella sua regione us-east-1 (Virginia settentrionale, USA) della durata di oltre 15 ore. Si tratta della regione default di AWS, che spesso è la prima a ricevere nuovi servizi e funzionalità. Il disservizio ha coinvolto i servizi globali che si basano sugli endpoint us-east-1, con un impatto a livello mondiale su servizi come Slack, Snapchat, Ring, Canvas, giochi online come Fortnite, applicazioni bancarie e molti altri servizi.

AWS ha identificato la causa principale in una race condition nel sistema di gestione automatico del DNS di DynamoDB, che ha generato un record DNS vuoto per l'endpoint regionale del servizio
(dynamodb.us-east-1.amazonaws.com).

Una race condition (letteralmente, una “condizione di corsa”) è un problema tipico della programmazione concorrente che si verifica quando due o più processi (o thread) accedono e modificano contemporaneamente una risorsa condivisa, e il risultato finale dell'operazione dipende dall'ordine (dalla "corsa") in cui queste operazioni vengono eseguite. Infatti, il processo che completa l'operazione di scrittura per ultimo sovrascriverà con questo ultimo valore tutti i precedenti.

Questo problema non si verifica sempre, ma solo quando i tempi di esecuzione dei processi si intersecano in un certo modo e ciò rende difficile diagnosticare questo tipo di errore.

Vediamo come si è verificata la race condition di AWS.

  1. Un primo DNS Enactor inizia ad applicare un piano DNS (chiamiamolo Piano-100), ma deve riprovare più volte per via di insoliti ritardi nell’esecuzione. Quindi sta lavorando molto lentamente.

  2. Nel frattempo, il DNS Planner continua a produrre nuovi piani più aggiornati (Piano-101, Piano-102, ecc.).

  3. Un secondo DNS Enactor prende uno dei piani più recenti (per esempio il Piano-102) e lo applica rapidamente a tutti gli endpoint, compreso l'endpoint regionale di DynamoDB. Al termine attiva un processo di pulizia automatico per eliminare i piani vecchi, incluso il Piano-100.

  4. Nello stesso momento in cui è eseguita la pulizia, il primo Enactor finalmente applica il Piano-100 all'endpoint regionale di DynamoDB, sovrascrivendo il piano più recente. Il Piano-100 era però già stato segnato per la cancellazione.

  5. La conseguenza è la generazione di un record DNS vuoto per us-east-1.amazonaws.com, con la conseguenza che il DynamoDB della regione risulta irraggiungibile, non trovandosi il suo attuale indirizzo IP.


A questo punto tutti i sistemi che dovevano connettersi a DynamoDB nella regione us-east-1 hanno iniziato a ricevere errori DNS: le applicazioni degli utenti che utilizzano DynamoDB non riuscivano ad accedere al database, molti servizi interni di AWS dipendenti da DynamoDB non funzionavano più.

Una volta identificato il problema, i record DNS sono stati ripristinati manualmente per permettere di raggiungere nuovamente il database. Purtroppo questa soluzione ha creato un problema ancora più grande, perché migliaia di server che dipendono da DynamoDB hanno provato a riconnettersi simultaneamente provocando un collasso del sistema causato dalla congestione delle richieste di connessione (congestive collapse). Tale situazione ha generato a cascata sovraccarichi in altri sistemi creando uno stato di blocco generale: tecnicamente tutto funzionava, ma il sovraccarico impediva il ritorno alla normalità, che è avvenuto dopo molte ore.

L'architettura con tre DNS Enactor indipendenti va bene per garantire la continuità del servizio (se uno non funziona, gli altri prendono in carico anche la sua parte), ma comporta il problema che essi possono interferire tra loro. Infatti, la race condition è emersa proprio nel punto di forza del sistema: la ridondanza.

Un sistema con un solo Enactor non avrebbe avuto questo problema, ma sarebbe stato un single point of failure, quindi un guasto avrebbe bloccato tutto.

 

Il caso di Netflix

Nel 2011, Netflix aveva subito un’interruzione del servizio a causa di un guasto di AWS e aveva quindi deciso di fare in modo che il suo servizio di streaming non fosse più bloccato dal disservizio di una regione di AWS. Pertanto, Netflix implementò un deployment multi-region realizzando un’architettura che funzionasse su più regioni AWS in contemporanea: us-east-1 (Virginia), us-west-2 (Oregon) ed eu-west-1 (Irlanda), configurando Route 53 per svolgere un failover automatico tra esse. Quando il 20 ottobre del 2025 la regione Virginia si è bloccata per il guasto, i sistemi di Netflix hanno automaticamente reindirizzato le richieste alle regioni Oregon e Irlanda, garantendo così agli utenti la continuità del servizio.

 

4. Attività di laboratorio con Cisco Packet Tracer

Problema

L’azienda IT Agency ha eseguito il deployment di un’applicazione web nel suo VPC creato nella AWS Region us-east-1. L’applicazione è stata distribuita su due istanze EC2 collocate in due diverse Availability Zone per garantirne un’elevata disponibilità. L'applicazione utilizza il servizio DynamoDB tramite l'endpoint DNS dynamodb.us-east-1.aws.internal.

Durante l’outage del 20 ottobre 2025 gli utenti hanno segnalato all’azienda l’impossibilità di accedere all’applicazione, nonostante l’infrastruttura fosse stata progettata con ridondanza su più AZ.

Realizza in Packet Tracer una simulazione dello scenario descritto e configura i server DNS con i resource record necessari per simulare gli endpoint AWS. Riproduci il guasto al DNS così da impedire all’applicazione web di raggiungere DynamoDB. Infine, simula il ripristino del servizio con un failover al DNS secondario.

Analisi

La realizzazione con Packet Tracer di uno scenario di rete che soddisfi le richieste del problema, e riproduca l’infrastruttura di AWS, comporta alcune semplificazioni dovute alla natura dello strumento, infatti con Packet Tracer non è possibile:

  1. realizzare un failover automatico in caso di guasto DNS, in quanto non c’è modo di indicare nei PC e nei server l’indirizzo IP di un secondo DNS; inoltre, in AWS sono implementate delle policy, dette di routing failover, che permettono di instradare il traffico a un record principale (primario) e, se questo non è integro, a un record di riserva (secondario), il tutto gestito in automatico con il servizio Route 53. Anche queste policy non possono essere realizzate con Packet Tracer;

  2. rappresentare il servizio DynamoDB, infatti DynamoDB non è un database su un server fisico bensì un servizio gestito da AWS e accessibile solo via API REST attraverso gli endpoint regionali come, per esempio,
    dynamodb.us-east-1.amazonaws.com. Quindi, DynamoDB non ha un indirizzo IP statico visibile.


Pertanto operiamo alcune scelte che permettono di riprodurre, con qualche compromesso, quanto avviene nella realtà AWS attraverso:

  1. la simulazione del failover con la sostituzione manuale dell’indirizzo del DNS primario con quello secondario quando si spegne il server DNS primario e la definizione di più record con lo stesso nome che puntano alla risorsa principale (per esempio un’istanza EC2 in una AZ) e alla risorsa di backup (per esempio un’istanza EC2 in un’altra AZ);

  2. la simulazione del servizio DynamoDB con l’introduzione di un DB server che simula l’endpoint così da permettere al web server con l’applicazione web di raggiungere un database esterno per le query.


Rappresentiamo una AWS Region, che chiamiamo us-east-1 come la regione in cui è avvenuta l’interruzione di ottobre, con due reti:

  • AWS Regional Services: sono i servizi offerti a livello regionale, in particolare DynamoDB;

  • Virtual Private Cloud (VPC): un cloud privato che creiamo per la gestione dell’applicazione web, utilizzando due Availability Zone (AZ1 e AZ2) connesse a un router (VPC-Router) che svolge la funzione di router virtuale del VPC. Collochiamo in AZ1 il server web che ospita l’applicazione web citata nel problema, in AWS sarebbe un’istanza EC2. In AZ2 replichiamo il server web così da aumentare l’availability dell’applicazione.


Il servizio DNS è gestito da AWS a livello globale, quindi simuliamo questa realtà creando la rete AWS Global Services in cui inseriamo due server che simulano il servizio DNS (Route 53-Service). Poiché è un servizio globale e distribuito nella rete backbone globale di AWS attraverso name server ridondanti, simuliamo questo servizio creando due subnet in cui inseriamo un server DNS, uno indicato come primario e l’altro, identico, come secondario.

Infine, creiamo una Client Network che simula la rete degli utenti finali.

Svolgimento

1. Architettura di rete realizzata

La figura seguente mostra lo scenario da realizzare in Packet Tracer.

Il router Cisco 2911 ha di default tre interfacce GigabitEthernet; nel caso dei collegamenti WAN (Internet Backbone) tra i tre router, Internet-Gateway, AWS-Region-Router e AWS-GS-Router, scegliamo un link seriale. Quindi su ciascun router apriamo la scheda Physical, spegniamo il router e inseriamo in uno slot vuoto il modulo HWIC-2T con due interfacce seriali, quindi accendiamo il router.
La tabella seguente descrive le reti create in Packet Tracer per la simulazione mostrando anche un confronto con l’infrastruttura AWS reale.
La tabella seguente mostra il piano di indirizzamento per le subnet create. Per ogni device inserito nel workspace di Packet Tracer configuriamo le interfacce di rete come indicato nella tabella.
Nota: i link punto-punto che connettono due router hanno un prefix /30 e solitamente utilizziamo indirizzi bassi, per esempio 172.16.0.1 e 172.16.0.2. Nella AWS Region abbiamo scelto di utilizzare indirizzi alti, 10.0.254.x/30, per le interconnessioni tra i router per simulare quanto accade nella realtà, per cui si lasciano gli indirizzi bassi, 10.0.0.x, per le subnet con host e server, così da rendere semplice aggiungere nuove AZ o nuovi servizi regionali evitando il rischio di generare conflitti. Per queste espansioni future si utilizzano gli indirizzi nel range da 10.0.3.0/24 a 10.0.253.0/24.


2. Configurazione del routing


Scegliamo di configurare il routing dinamico con OSPFv2 (Open Shortest Path First versione 2) realizzando un’architettura multi-area con le seguenti tre aree:

  • Area 0 (Backbone): Internet Backbone + Client Network;

  • Area 1 (Global Services): AWS Global Services (Route 53);

  • Area 2 (Regional): AWS Region us-east-1 (DynamoDB + VPC).


Tutte le aree non-zero devono connettersi direttamente o logicamente all'Area 0, quindi i router AWS-GS-Router e AWS-Region-Router diventano Area Border Router (ABR) connettendo l’Area 1 e l’Area 2 all’Area 0.

Su ciascun router eseguiamo i comandi da CLI per la configurazione delle route con il protocollo OSPF. Abilitiamo il protocollo ospf e diamo il comando di log, opzionale, utile per il troubleshooting. Infatti, esso permette di ricevere informazioni dal router su ciò che accadrà da questo momento in poi, per esempio se rileva errori di configurazione. La notifica più utile è la segnalazione del cambiamento di stato delle adiacenze OSPF mostrando quando un neighbor diventa FULL o DOWN.

Proseguiamo inserendo un identificativo del router e le route. Nella definizione delle route OSPF non si usa la subnet mask ma la wildcard mask che è l’inverso della subnet mask. Per esempio, per una rete /30 la wildcard mask è 0.0.0.3, per una rete /24 è 0.0.0.255.

Al termine, salviamo in modo permanente la configurazione con il comando copy. Viene richiesto di confermare il nome del file di destinazione (startup-config): premere Invio per confermare. Le modifiche vengono così salvate nella NVRAM del router.

 

Internet-Gateway
Router>enable
Router#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)#router ospf 1
Router(config-router)#log-adjacency-changes
Router(config-router)#router-id 1.1.1.1
Router(config-router)#network 203.0.113.0 0.0.0.3 area 0
Router(config-router)#network 203.0.113.4 0.0.0.3 area 0
Router(config-router)#network 192.168.1.0 0.0.0.255 area 0
Router(config-router)#exit
Router(config)#exit
Router#copy running-config startup-config
Destination filename [startup-config]?
Building configuration...
[OK]
Router#

Per i prossimi router riportiamo solo i comandi relativi al router-id e alle route da definire, infatti i comandi precedenti e seguenti a questi sono gli stessi mostrati per il router Internet-Gateway.

AWS-GS-Router
Router(config-router)#router-id 2.2.2.2
Router(config-router)#network 203.0.113.4 0.0.0.3 area 0
Router(config-router)#network 203.0.113.8 0.0.0.3 area 0
Router(config-router)#network 172.16.0.0 0.0.0.3 area 1

AWS-Router1
Router(config-router)#router-id 3.3.3.3
Router(config-router)#network 172.16.0.0 0.0.0.3 area 1
Router(config-router)#network 172.16.1.0 0.0.0.255 area 1
Router(config-router)#network 172.16.2.0 0.0.0.255 area 1

AWS-Region-Router
Router(config-router)#router-id 4.4.4.4
Router(config-router)#network 203.0.113.0 0.0.0.3 area 0
Router(config-router)#network 203.0.113.8 0.0.0.3 area 0
Router(config-router)#network 10.0.254.0 0.0.0.3 area 2
Router(config-router)#network 10.0.254.4 0.0.0.3 area 2

AWS-RS-Router
Router(config-router)#router-id 5.5.5.5
Router(config-router)#network 10.0.254.0 0.0.0.3 area 2
Router(config-router)#network 10.0.0.0 0.0.0.255 area 2

VPC-Router
Router(config-router)#router-id 6.6.6.6
Router(config-router)#network 10.0.254.4 0.0.0.3 area 2
Router(config-router)#network 10.0.1.0 0.0.0.255 area 2
Router(config-router)#network 10.0.2.0 0.0.0.255 area 2


Verifica delle configurazioni di routing


Dopo aver applicato le configurazioni sui singoli router, verifichiamone la correttezza eseguendo i seguenti comandi da CLI su ogni router:

  • show ip ospf neighbor → adiacenze OSPF

  • show ip ospf interface brief → stato delle interfacce OSPF

  • show ip route ospf → route apprese via OSPF

  • show ip ospf database → database OSPF

  • show ip protocols → protocolli di routing attivi


Eseguiamo anche i seguenti test per verificare la raggiungibilità dei server:

  • ping 172.16.1.10 → test Route53-Service-Primary

  • ping 172.16.2.10 → test Route53-Service-Secondary

  • ping 10.0.0.30 → test DynamoDB

  • ping 10.0.1.20 → test EC2-AZ1

  • ping 10.0.2.20 → test EC2-AZ2


 

3. Configurazione dei servizi

Su ogni server nella scheda Services abilitiamo (On) solo il servizio relativo e disabilitiamo (Off) tutti gli altri. Per esempio, nei due server Route53 mettiamo On il servizio DNS e disabilitiamo i servizi HTTP, TFTP, SYSLOG, NTP, EMAIL, FTP, VM Management.

Configurazione dei Resource Record DNS

Su entrambi i server Route53 selezioniamo la scheda Services e il servizio DNS, quindi configuriamo i Resource Record elencati nella tabella seguente. Per garantire la ridondanza è necessario che il server secondario abbia gli stessi record del primario.
Abbiamo scelto il dominio example.com, riservato per scopi di documentazione (RFC 2606), per simulare un dominio pubblico. Lo utilizziamo per i nomi relativi ai servizi web (applicazione e web server).

Per quanto concerne i servizi AWS interni scegliamo il dominio aws.internal (nel 2024 ICANN ha proposto di riservare .internal per uso privato).


Configurazione della pagina index.html dei web server


Configurazione di EC2-WebApp-AZ1 10.0.0.20:
<html>
<head><title>EC2 Web Application</title></head>
<body style="font-family: Arial; padding: 20px;">
<h1>Cloud Web Application</h1>
<p>Status: <span style="color: green;">ONLINE</span></p>
<p>Private IP: 10.0.1.20</p>
<hr>
<p>Simulazione di un'istanza di AWS EC2 (Elastic Compute Cloud)</p>
<small>Availability Zone 1 (us-east-1a)</small>
</body>
</html>

Su EC2-WebApp-AZ2 copiamo lo stesso codice HTML sostituendo l’indirizzo IP del server con: 10.0.2.20 e indicando l’Availability Zone 2 (us-east-1b).


Configurazione del DB server


Utilizziamo il protocollo HTTP per verificare se il database è funzionante (il servizio DynamoDB reale di AWS offre interfacce API REST accessibili con HTTP).

Abilitiamo il servizio HTTP e scriviamo il seguente codice HTML nel file index.html:
<html>
<head><title>Database Service</title></head>
<body style="font-family: Arial; padding: 20px; background: #f0f0f0;">
<h1>DynamoDB Simulation</h1>
<p>Service: <span style="color: green;">RUNNING</span></p>
<p>Service Endpoint: dynamodb.us-east-1.aws.internal</p>
<p>Private IP: 10.0.0.30</p>
<hr>
<p>Simulazione del servizio AWS DynamoDB</p>
<small>Regional Service (us-east-1)</small>
</body>
</html>

Verifica del corretto funzionamento dei servizi

Apriamo la scheda Desktop del PC Internet-Client1 o di Internet-Client2 e utilizziamo gli strumenti Commad Prompt per il comando nslookup e Web Browser per l’accesso alla pagina web. Svolgiamo le prove seguenti per verificare il funzionamento dei servizi specificati nei server web, database e DNS:

  • test DNS sulla risoluzione dei nomi di un dominio pubblico e del servizio www:

    • nslookup example.com

    • nslookup www.example.com



  • test DNS sulla risoluzione dei nomi dei servizi interni:

    • nslookup ec2-webapp-az1.aws.internal

    • nslookup dynamodb.us-east-1.aws.internal



  • test HTTP:

    • http://webapp.example.com

    • http://www.example.com

    • http://webapp-az1.example.com

    • http://webapp-az2.example.com

    • http://database.aws.internal





4. Simulazione di un guasto DNS considerato un single point of failures (SPF)


Come abbiamo descritto nell’analisi del problema, in Packet Tracer non è possibile configurare un DNS secondario con failover automatico, come avviene sui dispositivi reali. Pertanto, quando simuliamo un guasto a Route53-Service-Primary, non avviene un passaggio automatico al server Route53-Service-Secondary. Anche un sovraccarico di traffico DNS, come quello avvenuto nell'outage AWS di ottobre 2025, non è riproducibile in Packet Tracer.

Applichiamo quindi un approccio manuale per creare un’interruzione del servizio e il failover. Lavoriamo sui due scenari seguenti che operano su Route53-Service-Primary:

  • spegnimento del server: nella scheda Physical clicchiamo sul pulsante Power; questa azione simula un crash completo del servizio DNS, equivalente a quanto è successo nell'interruzione di AWS di ottobre 2025, dove Route53 non si è spento fisicamente, ma il sovraccarico a cui è stato sottoposto ha reso le sue risposte così lente da generare un timeout come se il servizio non rispondesse;

  • disabilitazione del servizio DNS: nella scheda Services selezioniamo DNS e clicchiamo su Off; il server continua a funzionare, ma non è in grado di risolvere i nomi, simulando così un guasto specifico del software DNS mentre l'hardware resta operativo.


Apriamo la finestra del Command Prompt dal PC Internet-Client1 ed effettuiamo i seguenti test:

  • ping 172.16.1.10 → funziona, il server Route53-Service-Primary è acceso quindi risponde → la rete funziona, non è un problema di connettività;

  • ping dns1.aws.internal → fallisce, il servizio DNS non risponde → il componente guasto è il DNS.


Svolgiamo alcuni test anche dal web server EC2-WebApp-AZ1:

  • ping 10.0.0.30 → funziona, il server DynamoDB-Service è acceso, quindi risponde → il database funziona;

  • ping dynamodb.us-east-1.aws.internal → fallisce, il servizio DNS non risponde → anche l'applicazione non può usare i nomi DNS per raggiungere il database.


Per simulare il failover cambiamo manualmente l’indirizzo del server DNS: 172.16.2.10 (Route53-Service-Secondary) sia sul PC Internet-Client1 sia sul server EC2-WebApp-AZ1. Ripetiamo i test precedenti e questa volta avranno tutti successo, il failover, manuale, ha funzionato.


Funzionante non significa raggiungibile


"Ping by IP works, ping by name fails": i server EC2-WebApp-AZ1 e EC2-WebApp-AZ2 possono essere funzionanti, ma se il servizio Route53 è down, nessuno può raggiungerli tramite il nome. Questo è il motivo per cui il DNS è considerato un Single Point of Failure critico.


5. Simulare l’effetto a cascata dovuto alle dipendenze


L’outage di ottobre 2025 ha evidenziato la criticità delle dipendenze tra le risorse, che hanno scatenato un effetto a cascata (cascading failure).

Analizziamo l’ordine delle dipendenze nello scenario che abbiamo creato:

Client → Internet-Gateway → AWS-Region-Router → Route53 (per risolvere i nomi) → VPC-Router → istanze EC2 (server con l’applicazione) → DynamoDB (database)

Se un elemento nella catena si guasta, tutti gli elementi sottostanti diventano irraggiungibili, anche se funzionanti.

Per simulare l'effetto a cascata possiamo:

  • spegnere il router Global Services (AWS-GS-Router) → i server Route53 non sono più raggiungibili, il DNS non risponde → le applicazioni non sono più raggiungibili anche se i server EC2 funzionano;

  • spegnere il router della regione us-east-1 (AWS-Region-Router) → non è più possibile raggiungere l’applicazione web dall’esterno (dagli Internet-Client) → l'intera region us-east-1 diventa isolata e tutti i servizi nella regione non sono più accessibili da Internet;

  • spegnere il router del cloud privato (VPC-Router) → le istanze EC2 nel VPC 10.0.1.0/22 non sono più raggiungibili → l'applicazione web non funziona, anche se il DNS e il database sono funzionanti → gli utenti ricevono errori di timeout o connection refused.


La simulazione di guasti è fondamentale per capire dove migliorare un'architettura. È possibile provare a simulare guasti in altri punti dell’infrastruttura creata e verificare come variano le risposte con i comandi ping e nslookup e con l’accesso alle pagine web dell’applicazione e del database.

Lo scenario realizzato con Packet Tracer è disponibile nel file Lab_AWS_Outage.pkt, allegato al presente articolo.

 

5. Attività di laboratorio con Python

Problema

Vogliamo creare un sistema per il monitoraggio continuo della disponibilità del DNS. Il sistema deve rilevare se il DNS non risponde alle query, misurare i tempi di risposta e verificare la coerenza tra le risposte di DNS server diversi al fine di rilevare configurazioni DNS non valide.

Il sistema realizzato deve permettere di verificare che i domini di un’azienda siano sempre raggiungibili, di controllare che i servizi offerti da terze parti, come AWS, siano operativi e di rilevare eventuali interruzioni DNS prima che gli utenti segnalino il problema.


Analisi


Per soddisfare le richieste del problema sviluppiamo uno script Python che automatizza il monitoraggio continuo di alcuni domini che andremo a specificare nel main del programma. Lo script è realizzato a scopo didattico, pertanto offre alcune funzioni di base, semplici, e non prende in esame altri elementi importanti per la verifica dell’integrità del DNS quali il controllo di tutti i tipi di record (si considera solo il record A), il rilevamento di traffico anomalo, la verifica di chi ha effettuato modifiche ai record DNS, ecc.

Lo script Python da realizzare per soddisfare le richieste del problema utilizza dnspython, una libreria completa e flessibile che offre moduli specializzati per manipolare interrogare e gestire il sistema DNS. Consente di effettuare query di vario tipo (A, MX, TXT, ecc.), gestire i trasferimenti di zona, aggiornare dinamicamente i record e validare firme DNSSEC.


Svolgimento


Per sviluppare lo script Python utilizziamo l’editor Visual Studio Code con le estensioni per Python. Creiamo la cartella DNS_health_monitor, la apriamo in VS Code e creiamo l’ambiente virtuale .venv. Quindi creiamo il file dns_health_monitor.py che conterrà il codice Python.

Per la risoluzione DNS utilizziamo la funzione dns.resolver.resolve() contenuta nel modulo resolve.py che fa parte della libreria dnspython. Installiamo la libreria da terminale con il seguente comando:
pip install dnspython

Per la gestione di data e ora utilizziamo i moduli time e datetime che fanno parte della libreria standard, pertanto non sono da installare.

Sviluppiamo le seguenti funzioni:

  • check_dns_health(): verifica se un dominio viene risolto correttamente dal DNS; restituisce una tupla con i seguenti risultati:

    • success (bool): True se la risoluzione è riuscita;

    • response_time (float): tempo impiegato in secondi;

    • ips (list): lista degli indirizzi IP restituiti;

    • msg (str): descrizione del risultato.



  • monitor_multiple_dns(): controlla la risoluzione di un dominio svolta da server DNS differenti; restituisce un dizionario con i risultati, dove la chiave è un server DNS e il valore contiene la seguente lista:

    • success (bool): True se la query è riuscita;

    • time (float): tempo di risposta in secondi;

    • ips (list): lista degli indirizzi IP ottenuti;

    • error (str): eventuale messaggio di errore.



  • continuous_monitor(): svolge un monitoraggio continuo di un elenco di domini controllati con la funzione check_dns_health(), ripetendo i controlli a intervalli regolari. A ogni iterazione raccoglie i risultati della funzione di check e li restituisce subito grazie all’istruzione yield.
    In Python yield trasforma una funzione in un generatore restituendo i valori uno alla volta in real-time, anziché tutti insieme alla fine come avviene con l’istruzione return. Inoltre, congela e salva lo stato della funzione tra una chiamata e l'altra, rendendo così efficiente la sua esecuzione.


Mostriamo di seguito il codice della funzione.
Infine, scriviamo la funzione main() in cui specifichiamo quali sono i domini da testare, inseriamo il richiamo della funzione continuous_monitor() e ne visualizziamo i risultati.

Terminata la stesura del codice apriamo il terminale in VS Code (View → Terminal) e avviamo l’esecuzione dello script con il seguente comando:
python .\dns_health_monitor.py

Eseguiamo lo script scrivendo nel main() il richiamo della funzione con i seguenti parametri:
continuous_monitor(domains, interval=7, max_iterations=3)

L’output ottenuto è mostrato nella figura seguente.
Per testare il programma, simulando un malfunzionamento, possiamo:

  • inserire un dominio inesistente;

  • utilizzare server DNS fittizi;

  • bloccare il server DNS locale e osservare il tempo in cui è stato rilevato il guasto dallo script.


Per visualizzare il codice completo, scaricare il file dns_health_monitor.py, allegato al presente articolo.

 

Conclusioni

“It’ always DNS” è un mantra tra i sistemisti che l’interruzione di AWS del 20 ottobre 2025 ha confermato: il DNS e la risoluzione dei nomi sono elementi fondamentali per il funzionamento dei servizi di rete. Il DNS rappresenta un elemento invisibile, ma cruciale, dell'infrastruttura digitale: quando fallisce, anche risorse funzionanti diventano irraggiungibili. Come dimostrato nelle simulazioni con Packet Tracer, un guasto al DNS equivale a un'interruzione fisica della rete, ma con conseguenze potenzialmente più estese. Il monitoraggio DNS che abbiamo implementato in Python è un semplice esempio di controllo automatico sul DNS per quanto riguarda la latenza e la coerenza della risoluzione.

L'aspetto più critico dell'outage di AWS, che ha reso inaccessibili i servizi per molte ore, non è stato tanto il guasto iniziale, quanto il cascading failure che ne è seguito. Le dipendenze tra i servizi hanno innescato reazioni a cascata che hanno paralizzato infrastrutture apparentemente indipendenti, colpendo economie e servizi essenziali su scala globale. I test svolti nel laboratorio Packet Tracer hanno evidenziato questa fragilità: piccole anomalie in componenti centrali possono propagarsi rapidamente attraverso l'intera catena di dipendenze.

L'analisi dell'outage, svolta dagli analisti, ha evidenziato questioni fondamentali sulla centralizzazione delle infrastrutture cloud. Anche giganti tecnologici come AWS, con tutte le loro ridondanze, non sono immuni da guasti causati da errori software o di configurazione. La vera resilienza non risiede solo nella ridondanza, ma richiede distribuzione geografica reale, architetture multi-cloud e governance condivisa.

Questa tematica, attuale e stimolante, può essere ulteriormente approfondita. Ecco alcuni spunti:

  • svolgere un’analisi comparativa di altri outage importanti per identificare eventuali elementi in comune;

  • approfondire le architetture multi-cloud e le strategie di failover cross-provider;

  • approfondire le metodologie di Chaos Engineering adottate dai principali fornitori di servizi SaaS per testare preventivamente la resilienza dei propri sistemi (Netflix è stato uno dei precursori, con la creazione di Chaos Monkey);

  • analizzare l'impatto economico e sociale delle interruzioni infrastrutturali critiche.



Fonti