A privacy-friendly macOS menu bar app that monitors and visualizes DNS queries in real-time. All data stays on your device.
- Real-time DNS capture using libpcap
- Smart interface detection (supports Tailscale/VPN)
- Beautiful charts — top domains, query types, timeline
- Persistent history with configurable retention (1–90 days)
- Privacy-first — all data stays local
git clone https://github.com/mr-karan/dnswatch.git
cd dnswatch
make buildGrab the latest from GitHub Releases.
Since the app isn't signed with an Apple Developer ID, macOS will show a warning. To open:
- Right-click the app → Open → Open (in the dialog)
Or remove the quarantine flag:
xattr -cr /Applications/DNSWatch.appDNSWatch needs BPF permissions to capture packets. Recommended (one-time admin prompt):
# Install the helper to restore permissions at boot
sudo /Applications/DNSWatch.app/Contents/Resources/BPFHelper/install_bpf_helper.shYou can also install the helper from DNSWatch → Settings → Capture Permissions. If you're running from source, use:
sudo .build/DNSWatch.app/Contents/Resources/BPFHelper/install_bpf_helper.shTemporary alternatives:
# Grant permissions (resets on reboot)
sudo chmod o+rw /dev/bpf*
# Or run with sudo
sudo .build/DNSWatch.app/Contents/MacOS/DNSWatchThen click the network icon in your menu bar.
DNSWatch passively captures DNS traffic using macOS's Berkeley Packet Filter (BPF):
Your App (browser, curl, etc.)
↓
DNS query to resolver (e.g. 8.8.8.8:53)
↓
Network stack sends UDP packet
↓
BPF copies packet to /dev/bpf* ←── DNSWatch reads here
↓
Packet continues to network (unmodified)
Key components:
- BPF devices (
/dev/bpf*) — Kernel-level packet capture points exposed by macOS - libpcap — Opens the interface, sets a filter (
udp port 53), reads packets in a loop - Interface detection — Queries
scutil --dnsfor active resolver, thenroute getto find which interface (en0, utun3, etc.) carries DNS traffic - DNS parsing — Strips Ethernet/IP/UDP headers, parses DNS wire format to extract domain and query type (A, AAAA, MX, etc.)
The app sees a copy of packets — it doesn't intercept or modify your traffic.
./Scripts/compile_and_run.sh # Dev loop
make build # Release build
./Scripts/package_app.sh --sign # Package DMGSee AGENTS.md for architecture details.
All data stays on your device in ~/Library/Application Support/DNSWatch/. Nothing is sent anywhere.
MIT