
dns-honeypot
Da ingegnere che passa gran parte delle sue giornate immerso negli strumenti di osservabilità, ogni tanto mi viene un'idea che devo assolutamente mettere in pratica. Questo è stato uno di quegli esperimenti: avviare un resolver DNS su un IP pulito che nessuno pubblicizza, e poi lasciare che Internet gli parli comunque. L'unico compito del resolver era rimanere in silenzio, registrare tutto e alimentare Grafana con le query ricevute. Un docker compose up -d dopo, avevo Unbound, Loki, Prometheus, Grafana e Traefik che tracciavano il traffico in tempo reale e stampavano istogrammi di curiosità, configurazioni errate e qualche scanner occasionale. Questo README è il resoconto di quel primo giorno: cosa cattura lo stack, perché mi interessa e cosa evidenzia del panorama di sicurezza attuale.
Ho intenzionalmente introdotto zero segnale da parte mia, nessuna perdita di pacchetti, nessuna risposta personalizzata, nessuna mitigazione. Solo Unbound con logging abilitato, Loki che segue il file di log, Prometheus che raccoglie le metriche degli esportatori, Traefik che fa da frontend a Grafana e Docker Compose che li collega. Il resolver si trovava su 94.130.27.226, un IPv4 rinfrescante "pulito" che avevo trovato (controlla il suo stato su https://www.abuseipdb.com/check/94.130.27.226 se vuoi una baseline pre-rumore), e ho lasciato che il mondo facesse il suo corso. Un singolo laptop poteva guardare ogni pannello, avviare tools/dns_query_storm.sh quando volevo agitare le acque, e poi lasciare che il rumore si stabilizzasse nei pattern che Internet globale sceglieva di inviare.
Puoi dare un'occhiata a quelle dashboard in tempo reale su https://dns.cybersafeintl.co.uk/public-dashboards/eb554b5b74e14f4d95e376c0033ee83d, anche se si trovano sul server più economico dello stack, quindi aspettati aggiornamenti lenti durante le query pesanti.
unbound_total_num_queries dell'esportatore Unbound, quindi il pannello "Throughput (QPS, 5m rate)" mostra le query al secondo e le suddivide per sorgente. Questa vista risponde alla domanda "chi sta martellando il resolver?", picchi improvvisi puntano direttamente a ASN del Bangladesh o della Polonia, e i log rendono facile vedere se tempeste SERVFAIL/NXDOMAIN accompagnano i burst.client_ip, e le dashboard già racchiudono tutto in topk(sort_desc(...)). Questo mantiene i pannelli puliti mentre lo script esportatore mi permette di scaricare le stesse query in CSV per analisi offline, report o storie riproducibili. La prima acquisizione ha mostrato cinque indirizzi IP nei range 45.179.* e 45.6.* che sparavano ciascuno oltre 5k query in cinque minuti, una fattoria di scanner o un client aggressivo.qname in finestre di 5m e 24h. Lo snapshot di 5 minuti presentava scb.se, dhl.com e cmu.edu, mentre l'esportazione su 24 ore includeva cbs.nl, scb.se, atlassian.com, e . Perché questi domini? Questa è la parte interessante: sono servizi legittimi, resolver mal configurati o scanner opportunistici che inseguono record obsoleti? Fammi sapere se hai una teoria.Ogni pannello che vedi ha un CSV corrispondente in exports/; comprimili (zip -r exports.zip exports/) quando vuoi allegare la storia grezza a un post sul blog o a un report di incidente.
docker-compose.yml avvia Unbound, l'esportatore Unbound, Loki + Promtail, Prometheus, Grafana e Traefik con un singolo comando.unbound/ memorizza configurazioni e log del resolver. Controlli TTL, serve-expired e impostazioni cache mantengono la fedeltà in modo da catturare ciò che i client chiedono realmente.prometheus/, loki/ e grafana/ contengono dati e file di provisioning in modo che metriche e dashboard sopravvivano ai riavvii.grafana/dashboards/unbound-traffic-insights.json è pre-provisionato con la vista che vedi; tutte le query PromQL/Loki già aggregano e ordinano per mantenere i pannelli leggibili.tools/dns_query_storm.sh ti permette di simulare tempeste di query quando devi testare i tempi di reazione.redeploy.sh automatizza lo spegnimento dello stack, il download degli aggiornamenti e la ricostruzione con un singolo script.export_dashboard_data.py ora analizza il JSON della dashboard, esegue ogni query Prometheus/Loki e scrive file CSV sanitizzati in una directory exports/ per la condivisione.
cd hetzner_deploy/unbound-dnscp .env.example .env e configura GRAFANA_DOMAIN, le credenziali admin di Grafana, LETSENCRYPT_EMAIL e qualsiasi override TLS di cui hai bisogno.sudo chown -R 472:472 grafana-data && sudo mkdir -p prometheus/data && sudo chown -R 65534:65534 prometheus/datadocker compose build && docker compose up -dpip install requests (l'esportatore è puro Python).python export_dashboard_data.py --duration 24h --outdir exports/24h --timeout 90 per prelevare ogni query della dashboard, convertirla in CSV e posizionare i risultati in exports/24h.zip -r exports.zip exports/ per comprimere le tabelle grezze prima di pubblicarle, allegarle a un post del blog o inviarle a collaboratori.--duration 6h o timestamp --end per fette mirate, o usa --filter domains se vuoi solo i pannelli dei domini.scb.se, dhl.com, cmu.edu, up.pt e utc.fr hanno generato ciascuno centinaia di migliaia di lookup. Perché questi target? La costellazione di domini aziendali europei mi fa sospettare un CDN, un servizio di ripristino o uno scanner che cerca di reidratare cache obsolete.cbs.nl, scb.se, atlassian.com, abb.com e up.pt hanno collettivamente generato oltre 250 milioni di query. Quel livello di volume non è rumore casuale: o client su larga scala o un dispositivo persistente che non smette mai di risolvere.45.179.* e 45.6.*, ciascuno che sparava oltre 5k query nei cinque minuti osservati. Potrebbero far parte di un ISP o di una fattoria di scanner, ma qualunque siano, le dashboard ne rendono banale il tracciamento.Cosa evidenzia questo? Illustra come un'infrastruttura DNS esposta possa diventare un feed passivo di traffico interessante anche quando non viene pubblicizzata. Internet continua a fare domande, e questa configurazione si limita ad ascoltare attentamente. Se sei curioso di come questo esperimento si inserisca nel mio lavoro più ampio, dai un'occhiata agli altri repo: a volte avvio un'idea come questa e devo vedere dove porta.
exports/ o allega direttamente i CSV ovunque racconti la storia.export_dashboard_data.py o le query Loki con metadati aggiuntivi (ASN client, motivo SERVFAIL, paese) per rispondere a domande più profonde.--duration 12h, --end ...), mantieni gli output in directory con timestamp e aggiorna questo README con le statistiche fresche in modo che la trama rimanga attuale.Se stai seguendo con il tuo honeypot, aggiorna questo README con le statistiche dai tuoi export così possiamo confrontare le storie e vedere se gli stessi siti e client continuano a ripresentarsi.
Questo progetto è fornito "così com'è". Non ci sono garanzie di alcun tipo, esplicite o implicite, incluse ma non limitate a commerciabilità, idoneità per uno scopo particolare o non violazione, e non sono responsabile per eventuali danni derivanti dal suo utilizzo. Ti assumi tutti i rischi associati alla distribuzione, configurazione o utilizzo di questo stack.
Se trovi utile questo progetto, considera di supportarlo:
| Valuta | Indirizzo |
|---|---|
| Bitcoin (BTC) | 3QjWqhQbHdHgWeYHTpmorP8Pe1wgDjJy54 |
| Ethereum (ETH) | 0x5851e6145F4773d1585b8686095FB16E368a4dA1 |
| ZCash (ZEC) | t1KSR5YkNPbjqRSCoLKo5AddFWdm9Kzxh1B |
abb.comup.pt