Skip to content

tsvb/itisalwaysdns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

It Is Always DNS (iiadns)

A comprehensive, platform-native DNS troubleshooting tool for macOS. This first iteration nails the fundamentals of two features: nslookup (what does a name resolve to, from which server, and why) and DNS leak testing (are my queries actually going where I think they are).

See DESIGN.md for the full architecture and rationale.


Status — foundation

Component What's built Validated
DNSKit (engine) Wire-format codec (RFC 1035 + EDNS0), UDP/TCP transport, multi-server resolver, system-DNS reader, idns CLI swift build + swift test (16 tests), cross-checked against system dig for every record type
iiadns.app (macOS) SwiftUI app: window (NavigationSplitView) + MenuBarExtra, working Lookup feature, Resolvers view, leak-test scaffold ✅ Builds & runs — xcodebuild produces iiadns.app and it launches on macOS 26.5
leakd (backend) Authoritative DNS responder (miekg/dns) + session/results HTTP API + enrichment, anti-abuse go build + go vet + go test; end-to-end validated with dig + curl

Repository layout

itisalwaysdns/
├── DESIGN.md                 Architecture & rationale
├── packages/DNSKit/          Swift package: the DNS engine + `iiadns` CLI
├── apps/iiadns/              SwiftUI macOS app (project generated by xcodegen)
└── server/leakd/             Go: authoritative DNS + leak-test API

Prerequisites

  • macOS 26 (Tahoe), Xcode 26, Swift 6.3+
  • xcodegenbrew install xcodegen (for the app project)
  • Go 1.25+ (for leakd)

DNSKit — the engine + CLI

cd packages/DNSKit
swift build                 # build library + CLI
swift test                  # 11 offline codec tests (golden vectors, compression, fuzz)
IIADNS_LIVE=1 swift test    # + 5 live tests against public resolvers

The idns CLI is a dig-style front end (and the engine's headless test harness). It's named idns rather than iiadns so it doesn't collide with the app's iiadns scheme under xcodebuild:

.build/debug/idns @1.1.1.1 example.com A          # query a specific resolver
.build/debug/idns example.com MX +short           # short output
.build/debug/idns -x 8.8.8.8                       # reverse (PTR) lookup
.build/debug/idns cloudflare.com A +dnssec --raw   # DO bit + raw hexdump
.build/debug/idns --compare example.com A          # compare across resolvers
.build/debug/idns example.com A +tcp               # force TCP

iiadns.app — the macOS app

cd apps/iiadns
xcodegen generate                                    # regenerate iiadns.xcodeproj from project.yml
open iiadns.xcodeproj                                 # build & run from Xcode (⌘R)

# or headless:
xcodebuild -project iiadns.xcodeproj -scheme iiadns -destination 'platform=macOS' build

The Lookup tab is wired to the engine; the Resolvers tab reads the live system DNS config; the Leak Test tab is scaffolded for the leakd backend.

Troubleshooting

If xcodebuild ever aborts at startup with a loader error in IDESimulatorFoundation (a stale DVTDownloads.framework), Xcode's component install is incomplete. It's an Xcode issue, not a project issue — fix it once with sudo xcodebuild -runFirstLaunch.

leakd — the leak-test backend

cd server/leakd
go test ./...                                         # unit + end-to-end DNS observation tests
go build -o leakd .

# Run locally (high ports so no root needed):
./leakd -zone leak.example.test -dns 127.0.0.1:5354 -http 127.0.0.1:8088

End-to-end smoke test against the running server:

SESSION=$(curl -s -XPOST http://127.0.0.1:8088/v1/session)
TOKEN=$(echo "$SESSION" | python3 -c 'import sys,json;print(json.load(sys.stdin)["token"])')
PROBE=$(echo "$SESSION" | python3 -c 'import sys,json;print(json.load(sys.stdin)["probes"][0])')

dig @127.0.0.1 -p 5354 "$PROBE" A +short             # -> 192.0.2.1 (sink)
curl -s http://127.0.0.1:8088/v1/session/$TOKEN/results | python3 -m json.tool
# observed_resolvers now lists 127.0.0.1 (the resolver that queried us)

In production, delegate a real zone (e.g. a subdomain you own) to leakd's authoritative server, run it dual-stack, and put per-source rate limiting in front.


What's next (per DESIGN.md roadmap)

  • Wire the app's Leak Test tab to a deployed leakd endpoint + a verdict engine.
  • Local-network permission handling for system-resolver queries (incl. the macOS 26 reboot bug).
  • ASN/geo enrichment (MaxMind GeoLite2) in leakd.
  • Encrypted transports (DoH/DoT/DoQ) and dig +trace in the engine.

About

A native macOS DNS troubleshooting tool — nslookup + DNS leak testing. SwiftUI app, dependency-free DNSKit engine, and a self-hosted leak-test backend.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors