
스위스 지방자치단체 도메인을 분석하고, 웹사이트에서 이메일 주소를 스크래핑하며, MX, SPF, DKIM, DMARC 및 SMTP 프로브를 통해 이메일 제공업체를 분류하여 디지털 의존성을 매핑하는 자동화 파이프라인입니다.
[!IMPORTANT] MXmap에는 후속 프로젝트가 있습니다. 이 프로젝트는 독일, 오스트리아, 스위스의 모든 지방자치단체를 포괄하는 팀 연구 프로젝트로 성장했습니다: secassure2026.mxmap-project.org (소스). mxmap.ch의 스위스 지도는 계속 온라인으로 제공되지만, 데이터는 2026년 4월 기준으로 동결되어 더 이상 업데이트되지 않습니다.
스위스 지방자치단체가 이메일을 어디에 호스팅하는지, 그리고 DNS가 스위스 제공업체 및 자체 호스팅 솔루션과 비교하여 미국 하이퍼스케일러(Microsoft, Google, AWS)에 얼마나 깊이 연결되어 있는지 보여주는 대화형 지도입니다.
데이터 파이프라인은 두 단계로 구성됩니다:
도메인 확인 — Wikidata와 BFS(스위스 통계청) API에서 약 2,100개의 스위스 지방자치단체를 가져오고, 수동 재정의를 적용하며, 지방자치단체 웹사이트에서 이메일 주소를 스크랩하고, 지방자치단체 이름에서 도메인을 추측하며, MX 조회를 통해 후보를 검증합니다. 최상의 도메인을 선택하기 위해 출처 일치도를 평가합니다. municipality_domains.json을 출력합니다.
제공업체 분류 — 확인된 각 도메인에 대해 모든 MX 호스트를 조회하고 패턴 매칭한 다음, 10개의 동시 프로브(SPF, DKIM, DMARC, Autodiscover, CNAME 체인, SMTP 배너, 테넌트, ASN, TXT 검증, SPF IP)를 실행합니다. 가중 증거를 집계하고 신뢰도 점수(0–100)를 계산합니다. data.json(전체)과 data.min.json(프런트엔드용 축소 버전)을 출력합니다.
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"]
전체 구현 세부 사항은 classifier.py를 참조하세요. 간단히 요약하면, 각 프로브가 서로 다른 제공업체 분류에 다양한 강도의 신호를 기여하는 가중 증거 시스템을 사용합니다.
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
국가별 포크, 국가 코드 알파벳순:
새로운 국가 포크를 환영합니다 — DANE/DNSSEC/SPF/DMARC 스캔 단계가 추가된 후속 프로젝트의 파이프라인에서 시작하는 것을 고려해 보세요.
관련 프로젝트:
이 저장소의 포크도 참조하세요.
잘못된 분류를 발견하면 BFS 번호와 올바른 제공업체를 명시하여 이슈를 열어 주세요.
자동 감지가 실패하는 지방자치단체의 경우 overrides.json에 수정 사항을 추가할 수 있습니다.