
Pipeline automatizzata che risolve i domini dei comuni svizzeri, estrae gli indirizzi email dai siti web e classifica i provider di posta elettronica tramite sonde MX, SPF, DKIM, DMARC e SMTP per mappare le dipendenze digitali.
[!IMPORTANT] MXmap ha un successore. Questo progetto è diventato un'iniziativa di ricerca di gruppo che copre tutti i comuni di Germania, Austria e Svizzera: secassure2026.mxmap-project.org (sorgente). La mappa svizzera su mxmap.ch resta online, ma i suoi dati sono congelati ad aprile 2026 e non verranno più aggiornati.
Mappe interattive che mostrano dove i comuni svizzeri ospitano la propria email e quanto profondamente il loro DNS sia legato agli hyperscaler statunitensi (Microsoft, Google, AWS) rispetto ai provider svizzeri e alle soluzioni self-hosted.
La pipeline di dati ha due fasi:
Risoluzione dei domini — Recupera tutti i ~2100 comuni svizzeri da Wikidata e dall'API BFS (Statistica svizzera), applica override manuali, estrae indirizzi email dai siti web comunali, deduce i domini dai nomi dei comuni e verifica i candidati con lookup MX. Valuta la concordanza delle fonti per scegliere il dominio migliore. Produce municipality_domains.json.
Classificazione dei provider — Per ogni dominio risolto, individua tutti gli host MX, li confronta con pattern, quindi esegue 10 probe concorrenti (SPF, DKIM, DMARC, Autodiscover, catena CNAME, banner SMTP, Tenant, ASN, verifica TXT, SPF IP). Aggrega le prove ponderate e calcola punteggi di confidenza (0–100). Produce data.json (completo) e data.min.json (minificato per il frontend).
flowchart TD
subgraph resolve ["1 · Resolve domains"]
bfs[/"BFS Statistics API"/] --> merge["Merge ~2100 municipalities"]
wikidata[/"Wikidata SPARQL"/] --> merge
overrides[/"overrides.json"/] --> per_muni
merge --> per_muni["Per municipality"]
per_muni --> scrape["Scrape website for<br/>email addresses"]
per_muni --> guess["Guess domains<br/>from name"]
scrape --> mx_verify["MX lookup to<br/>verify domains"]
guess --> mx_verify
mx_verify --> score["Score source<br/>agreement"]
end
score --> domains[("municipality_domains.json")]
domains --> classify_in
subgraph classify ["2 · Classify providers"]
classify_in["Per unique domain"] --> mx_lookup["MX lookup<br/>(all hosts)"]
mx_lookup --> mx_match["Pattern-match MX<br/>+ detect gateway"]
mx_match --> concurrent["10 concurrent probes<br/>SPF · DKIM · DMARC<br/>Autodiscover · CNAME chain<br/>SMTP · Tenant · ASN<br/>TXT verification · SPF IP"]
concurrent --> aggregate["Aggregate weighted<br/>evidence"]
aggregate --> vote["Primary vote<br/>+ confidence scoring"]
end
vote --> data[("data.json + data.min.json")]
data --> frontend["Leaflet map<br/>mxmap.ch"]
consulta classifier.py per i dettagli completi dell'implementazione, ma in sintesi,
usiamo un sistema di prove ponderate in cui ogni probe contribuisce con segnali di diversa intensità alle diverse classificazioni dei provider.
uv sync
# Stage 1: resolve municipality domains
uv run resolve-domains
# Stage 2: classify email providers
uv run classify-providers
# Serve the map locally
python -m http.server
uv sync --group dev
# Run tests (90% coverage threshold enforced)
uv run pytest --cov --cov-report=term-missing
# Lint & format
uv run ruff check src tests
uv run ruff format src tests
Fork specifici per paese, in ordine alfabetico per codice paese:
I fork per nuovi paesi sono i benvenuti — considera di partire dalla pipeline del successore, che aggiunge una fase di scansione DANE/DNSSEC/SPF/DMARC.
Progetti correlati:
Vedi anche i fork di questo repository.
Se noti una classificazione errata, apri una issue con il numero BFS e il provider corretto.
Per i comuni in cui il rilevamento automatico fallisce, le correzioni possono essere aggiunte a overrides.json.