checker-resolver-propagation/checker/resolvers.go

174 lines
8.6 KiB
Go

package checker
// Region is a coarse bucket for the report, not a geolocation claim (Anycast → "global").
type Resolver struct {
// ID is a stable identifier, exposed in JSON/metrics.
ID string
// Name is the human-readable provider + flavor (shown in the report).
Name string
// IP is the plain-text UDP/TCP address (without port).
IP string
// Region tags the resolver geographically. One of: global, na, eu, asia,
// ru, me, oceania, sa, africa.
Region string
// Filtered marks resolvers that intentionally rewrite or block answers
// (malware / adult / ad / family filters). These are expected to differ
// from the consensus on some zones and therefore kept out of the default
// unfiltered probe set.
Filtered bool
// DoHURL is the RFC 8484 endpoint, when the provider publishes one.
DoHURL string
// DoTHost is the DNS-over-TLS server name (SNI target), when available.
// DoT always runs on port 853 against this same hostname.
DoTHost string
}
// Derived from happydomain3/web/src/lib/resolver.ts; regions are best-effort from AS paths and provider docs.
var allResolvers = []Resolver{
// ── Unfiltered / Anycast global ──────────────────────────────────────
{ID: "cloudflare", Name: "Cloudflare DNS", IP: "1.1.1.1", Region: "global",
DoHURL: "https://cloudflare-dns.com/dns-query", DoTHost: "cloudflare-dns.com"},
{ID: "google", Name: "Google Public DNS", IP: "8.8.8.8", Region: "global",
DoHURL: "https://dns.google/dns-query", DoTHost: "dns.google"},
{ID: "quad9-unfiltered", Name: "Quad9 (no blocklist)", IP: "9.9.9.10", Region: "global",
DoHURL: "https://dns10.quad9.net/dns-query", DoTHost: "dns10.quad9.net"},
{ID: "opendns", Name: "OpenDNS", IP: "208.67.222.222", Region: "global"},
{ID: "he", Name: "Hurricane Electric", IP: "74.82.42.42", Region: "global"},
{ID: "dns-sb", Name: "DNS.SB", IP: "185.222.222.222", Region: "global",
DoHURL: "https://doh.dns.sb/dns-query", DoTHost: "dns.sb"},
{ID: "adguard-unfiltered", Name: "AdGuard (non-filtering)", IP: "94.140.14.140", Region: "global",
DoHURL: "https://unfiltered.adguard-dns.com/dns-query", DoTHost: "unfiltered.adguard-dns.com"},
// ── North America ──
{ID: "level3", Name: "Level3", IP: "4.2.2.1", Region: "na"},
{ID: "verisign", Name: "Verisign", IP: "64.6.64.6", Region: "na"},
{ID: "comodo", Name: "Comodo Secure DNS", IP: "8.26.56.26", Region: "na"},
{ID: "norton", Name: "Norton ConnectSafe", IP: "199.85.126.10", Region: "na"},
{ID: "safeserve", Name: "Namecheap SafeServe", IP: "198.54.117.10", Region: "na"},
{ID: "dyn", Name: "Dyn", IP: "216.146.35.35", Region: "na"},
{ID: "neustar", Name: "Neustar / DNS Advantage", IP: "156.154.70.1", Region: "na"},
{ID: "smartviper", Name: "SmartViper", IP: "208.76.50.50", Region: "na"},
{ID: "alternate", Name: "Alternate DNS", IP: "23.253.163.53", Region: "na"},
{ID: "strongdns", Name: "StrongDNS", IP: "216.131.65.63", Region: "na"},
// ── Europe ──
{ID: "dns-watch", Name: "DNS.WATCH (DE)", IP: "84.200.69.80", Region: "eu"},
{ID: "freedns", Name: "FreeDNS (AT)", IP: "37.235.1.174", Region: "eu"},
{ID: "freenom", Name: "Freenom World (NL)", IP: "80.80.80.80", Region: "eu"},
{ID: "uncensored", Name: "UncensoredDNS (DK)", IP: "91.239.100.100", Region: "eu"},
{ID: "fdn", Name: "French Data Network (FR)", IP: "80.67.169.12", Region: "eu"},
{ID: "fooldns", Name: "FoolDNS (IT)", IP: "87.118.111.215", Region: "eu"},
{ID: "puntcat", Name: "puntCAT (ES)", IP: "109.69.8.51", Region: "eu"},
{ID: "opennic", Name: "OpenNIC", IP: "185.121.177.177", Region: "eu"},
{ID: "dns4eu-unfiltered", Name: "DNS4EU (unfiltered)", IP: "86.54.11.100", Region: "eu",
DoHURL: "https://unfiltered.joindns4.eu/dns-query", DoTHost: "unfiltered.joindns4.eu"},
{ID: "dns4all", Name: "DNS4ALL", IP: "194.0.5.3", Region: "eu"},
// ── Asia (East & SE) ──
{ID: "ntt-jp", Name: "NTT (JP)", IP: "129.250.35.250", Region: "asia"},
{ID: "alidns", Name: "AliDNS (CN)", IP: "223.5.5.5", Region: "asia"},
{ID: "cnnic-sdns", Name: "CNNIC SDNS (CN)", IP: "1.2.4.8", Region: "asia"},
{ID: "dnspod", Name: "DNSPod (CN)", IP: "119.29.29.29", Region: "asia"},
{ID: "onedns", Name: "oneDNS (CN)", IP: "114.215.126.16", Region: "asia"},
{ID: "cloudxns", Name: "CloudXNS (CN)", IP: "124.251.124.251", Region: "asia"},
{ID: "114dns", Name: "114DNS (CN)", IP: "114.114.114.114", Region: "asia"},
{ID: "dnspai", Name: "DNSpai (CN)", IP: "101.226.4.6", Region: "asia"},
{ID: "quad101", Name: "Quad101 (TW)", IP: "101.101.101.101", Region: "asia"},
{ID: "hinet", Name: "HiNet (TW)", IP: "168.95.1.1", Region: "asia"},
// ── Russia ──
{ID: "yandex", Name: "Yandex.DNS", IP: "77.88.8.8", Region: "ru",
DoTHost: "common.dot.dns.yandex.net"},
// ── Middle East ──
{ID: "greenteam", Name: "GreenTeam DNS (IL)", IP: "81.218.119.11", Region: "me"},
// ── Filtered (opt-in) ─────────────────────────────────────────────────
{ID: "cloudflare-malware", Name: "Cloudflare (malware blocking)", IP: "1.1.1.2", Region: "global", Filtered: true,
DoHURL: "https://security.cloudflare-dns.com/dns-query", DoTHost: "security.cloudflare-dns.com"},
{ID: "cloudflare-family", Name: "Cloudflare (malware + adult)", IP: "1.1.1.3", Region: "global", Filtered: true,
DoHURL: "https://family.cloudflare-dns.com/dns-query", DoTHost: "family.cloudflare-dns.com"},
{ID: "quad9", Name: "Quad9 (blocklist)", IP: "9.9.9.9", Region: "global", Filtered: true,
DoHURL: "https://dns.quad9.net/dns-query", DoTHost: "dns.quad9.net"},
{ID: "adguard", Name: "AdGuard (default)", IP: "94.140.14.14", Region: "global", Filtered: true,
DoHURL: "https://dns.adguard-dns.com/dns-query", DoTHost: "dns.adguard-dns.com"},
{ID: "adguard-family", Name: "AdGuard (family protection)", IP: "94.140.14.15", Region: "global", Filtered: true,
DoHURL: "https://family.adguard-dns.com/dns-query", DoTHost: "family.adguard-dns.com"},
{ID: "yandex-safe", Name: "Yandex Safe", IP: "77.88.8.2", Region: "ru", Filtered: true,
DoTHost: "common.dot.dns.yandex.net"},
{ID: "yandex-family", Name: "Yandex Family", IP: "77.88.8.3", Region: "ru", Filtered: true,
DoTHost: "common.dot.dns.yandex.net"},
{ID: "dns-advantage-threat", Name: "DNS Advantage Threat", IP: "156.154.70.2", Region: "na", Filtered: true},
{ID: "dns-advantage-family", Name: "DNS Advantage Family", IP: "156.154.70.3", Region: "na", Filtered: true},
{ID: "dns-advantage-business", Name: "DNS Advantage Business", IP: "156.154.70.4", Region: "na", Filtered: true},
{ID: "cleanbrowsing-family", Name: "CleanBrowsing Family", IP: "185.228.168.168", Region: "global", Filtered: true,
DoHURL: "https://doh.cleanbrowsing.org/doh/family-filter/", DoTHost: "family-filter-dns.cleanbrowsing.org"},
{ID: "cleanbrowsing-adult", Name: "CleanBrowsing Adult", IP: "185.228.168.10", Region: "global", Filtered: true,
DoHURL: "https://doh.cleanbrowsing.org/doh/adult-filter/", DoTHost: "adult-filter-dns.cleanbrowsing.org"},
{ID: "dns4eu-protective", Name: "DNS4EU Protective", IP: "86.54.11.1", Region: "eu", Filtered: true,
DoHURL: "https://protective.joindns4.eu/dns-query", DoTHost: "protective.joindns4.eu"},
{ID: "dns4eu-child", Name: "DNS4EU Child Protection", IP: "86.54.11.12", Region: "eu", Filtered: true,
DoHURL: "https://child.joindns4.eu/dns-query", DoTHost: "child.joindns4.eu"},
{ID: "dns4eu-adblock", Name: "DNS4EU Ad-blocking", IP: "86.54.11.13", Region: "eu", Filtered: true,
DoHURL: "https://ads.joindns4.eu/dns-query", DoTHost: "ads.joindns4.eu"},
}
// A non-empty allowlist takes precedence; filter and region knobs are then ignored.
func selectedResolvers(includeFiltered bool, region string, allowlist []string) []Resolver {
if len(allowlist) > 0 {
allow := make(map[string]bool, len(allowlist))
for _, a := range allowlist {
allow[a] = true
}
var out []Resolver
for _, r := range allResolvers {
if allow[r.ID] || allow[r.IP] {
out = append(out, r)
}
}
return out
}
var out []Resolver
for _, r := range allResolvers {
if r.Filtered && !includeFiltered {
continue
}
if region != "" && region != "all" && region != r.Region {
continue
}
out = append(out, r)
}
return out
}
func regionLabel(region string) string {
switch region {
case "global":
return "Global / Anycast"
case "na":
return "North America"
case "eu":
return "Europe"
case "asia":
return "Asia"
case "ru":
return "Russia"
case "me":
return "Middle East"
case "oceania":
return "Oceania"
case "sa":
return "South America"
case "africa":
return "Africa"
default:
return region
}
}