Un filtro DNS capace di bloccare oltre mezzo milione di domini non richiede necessariamente una Raspberry Pi, un mini PC o gigabyte di memoria. Il progetto esp32-c3-adblock (repository GitHub) dimostra che un microcontrollore ESP32-C3 con 400 KB di SRAM e 4 MB di flash può svolgere il lavoro con circa 50 KB di RAM occupata e tempi di risposta vicini ai 10 millisecondi. Il risultato è ottenibile eliminando dalla memoria i nomi di dominio completi, conservandone soltanto impronte numeriche compatte.
L’idea riprende il principio dei DNS sinkhole, adottato da tempo da soluzioni come Pi-hole e AdGuard Home. Un resolver di questo tipo intercetta le richieste DNS della rete locale; quando riconosce un dominio pubblicitario, di tracciamento o potenzialmente dannoso, restituisce un indirizzo non utilizzabile invece di inoltrare la richiesta. Fino a pochi anni fa, una configurazione domestica richiedeva quasi sempre un computer Linux sempre acceso. La disponibilità di microcontrollori WiFi economici apre però una strada diversa, almeno per installazioni essenziali o di emergenza.
Perché una normale blocklist non entra nella memoria del microcontrollore
Il modello scelto dallo sviluppatore è una scheda ESP32-C3 SuperMini. Il chip integra un processore RISC-V a 32 bit con frequenza massima di 160 MHz, connettività WiFi 2,4 GHz 802.11 b/g/n e 400 KB di SRAM, dei quali una parte serve alla cache e alle funzioni interne. La scheda utilizzata dispone inoltre di 4 MB di memoria flash e non monta PSRAM esterna.
Una lista con centinaia di migliaia di domini in formato testuale supera rapidamente tali limiti. Anche ipotizzando una lunghezza media contenuta, ogni voce richiede i caratteri del dominio, un terminatore o un separatore e strutture che consentano al programma di trovare il dato. Una raccolta da 141.000 elementi può occupare circa 2,5 MB quando caricata come stringhe, una quantità incompatibile con la RAM del C3.
La soluzione consiste nel trasformare ogni dominio in un valore di dimensione fissa tramite FNV-1a, una funzione hash non crittografica nota per la semplicità dell’implementazione e per il costo computazionale ridotto. Il progetto conserva soltanto 40 bit del risultato: cinque byte per voce, indipendentemente dalla lunghezza originale del nome.
In pratica, 141.000 hash richiedono circa 705.000 byte; una lista da 537.000 domini occupa invece poco più di 2,68 MB. La compressione non deriva da un algoritmo tradizionale: il firmware rinuncia deliberatamente alla possibilità di ricostruire il dominio originale, dato che durante il filtraggio serve soltanto stabilire se l’impronta della richiesta compare nell’archivio.
Come nasce il database da caricare nella flash di ESP32-C3 SuperMini
La blocklist non arriva sul dispositivo come raccolta di stringhe: uno script eseguito sul computer di sviluppo scarica una o più liste pubbliche, elimina commenti e duplicati, normalizza le voci e calcola l’hash a 40 bit di ciascun dominio. Poi ordina i valori numerici e genera un file binario pronto per la scrittura nella memoria del microcontroller.
Quando arriva una richiesta di risoluzione DNS, il firmware estrae il nome richiesto, ne calcola l’impronta e controlla anche i suffissi genitore. Una query per un host come ads.example.com, per esempio, può richiedere la verifica sia del nome completo sia di example.com. Tale passaggio consente di bloccare interi rami senza archiviare ogni possibile sottodominio.
Il programma cerca poi il valore nella tabella ordinata tramite ricerca binaria. Con circa 537.000 elementi servono al massimo una ventina di confronti, perché il numero di passaggi cresce secondo il logaritmo in base due della dimensione della lista. Gli accessi avvengono direttamente nella flash, evitando di copiare l’intero archivio nella SRAM.
Se trova una corrispondenza, il server risponde con 0.0.0.0, realizzando il cosiddetto DNS sinkhole: ne abbiamo parlato nell’articolo sulle differenze tra 0.0.0.0 e 127.0.0.1.
In caso contrario inoltra il pacchetto a un resolver superiore e restituisce al client la risposta ricevuta. I circa 10 millisecondi dichiarati includono anche il tragitto WiFi; non rappresentano quindi il solo tempo necessario alla ricerca nell’archivio.
Come lavora ESP32 collegato alla porta USB del router
Nel video YouTube condiviso dall’autore del progetto, si vede che il microcontroller ESP32 è collegato – servendosi di un apposito adattatore – alla porta USB del router.
La porta USB del router svolge un compito molto più semplice di quanto si possa pensare: alimenta la scheda a 5 volt. Non trasporta le richieste DNS e non crea un collegamento di rete cablato tra il router e il microcontrollore. ESP32-C3 usa infatti il proprio modulo WiFi per collegarsi alla rete locale, ottenere un indirizzo IP e ascoltare le interrogazioni DNS sulla porta UDP 53.
Il dispositivo si comporta come un piccolo server indipendente sistemato dietro al router: la porta USB evita un alimentatore esterno, mentre tutte le comunicazioni viaggiano via radio. Una volta avviato, il firmware legge la configurazione WiFi, monta la partizione che contiene la blocklist e rende disponibile il resolver. Il router o i singoli client devono poi conoscere l’indirizzo IP del C3 e usarlo come server DNS.
Quando un computer, uno smartphone o un dispositivo IoT deve risolvere un nome, invia al microcontrollore una query come quella relativa a ads.example.com.
Le differenze rispetto a Pi-hole e AdGuard Home
L’ESP32-C3 svolge bene una funzione circoscritta: riceve una query DNS, controlla se il dominio appartiene alla lista di blocco e risponde localmente oppure inoltra la richiesta.
Pi-hole e AdGuard Home, citati in apertura, coprono invece una parte molto più ampia dell’amministrazione DNS di una rete.
Pi-hole usa il resolver FTL, basato sul progetto dnsmasq, e conserva informazioni sulle query, sui client, sulle risposte e sulle regole applicate. L’interfaccia permette di analizzare quali dispositivi generano traffico, individuare i domini richiesti più spesso, creare gruppi con politiche differenti e consultare dati storici.
AdGuard Home aggiunge funzioni analoghe e integra direttamente supporto per protocolli come DNS over HTTPS (DoH), DNS over TLS e DNS over QUIC, oltre a controlli parentali e filtri per servizi specifici.
Il progetto per ESP32 rinuncia intenzionalmente a gran parte di queste capacità. Una tabella di hash da cinque byte non contiene il nome originale del dominio; di conseguenza il dispositivo può stabilire che una voce è bloccata, ma non può ricavare dalla tabella quale stringa abbia prodotto quella corrispondenza. Per mostrare log leggibili, statistiche dettagliate o spiegazioni sulle regole servirebbero dati aggiuntivi, più memoria e una struttura meno compatta.
Gestione di eccezioni e uso di protocolli cifrati
Pi-hole e AdGuard Home risultano inoltre più flessibili nella gestione delle eccezioni. Possono applicare allowlist, espressioni regolari, regole per singolo client e filtri basati sul tipo di richiesta. Su ESP32-C3 sono disponibili domini personalizzati e alcune funzioni di controllo, ma il modello resta volutamente più semplice: il microcontrollore privilegia la densità della blocklist e il basso consumo, non la capacità di analisi.
La gestione dei protocolli rappresenta un’altra differenza importante: il firmware lavora principalmente come resolver DNS tradizionale sulla rete locale. Non può intercettare automaticamente le applicazioni che usano un proprio server DoH esterno; lo stesso limite interessa Pi-hole quando opera da solo, ma AdGuard Home può terminare direttamente connessioni DNS cifrate se l’amministratore configura certificati e client. Un computer Linux offre inoltre più possibilità per applicare regole firewall, redirect della porta 53 e controlli sui resolver autorizzati.
Pi-hole e AdGuard Home possono assumere anche il ruolo di server DHCP, distribuendo il proprio indirizzo come DNS e semplificando la configurazione dei dispositivi. Nel progetto ESP32 tale funzione figura tra le possibili evoluzioni, ma non costituisce il nucleo attuale: senza DHCP integrato, l’amministratore deve affidarsi alle opzioni del router o intervenire sui singoli client.