Question and planning around Mycelium as system-wide dns resolver #3
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
geomind_code/mycelium_network_gui#3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
In order to get Mycelium to be used as a system resolver for all platforms, we'll need to see how we can do that:
From CLaude:
Configuration
Component 1: DNS Stub Resolver
This component is shared across all platforms. It's a lightweight DNS server embedded in the Mycelium daemon.
Responsibilities
127.0.0.1:53(UDP and TCP)Rust Crate Recommendations
hickory-dns(formerly trust-dns)hickory-resolversocket2Code Sketch
Binding to Port 53
Port 53 is privileged (< 1024). Options:
CAP_NET_BIND_SERVICEcapability, or start as root then drop privilegesComponent 2: System DNS Capture
Before hijacking DNS, we need to know where queries were going so we can forward non-Mycelium queries there (in split mode).
Linux
Multiple sources, in order of preference:
Edge cases:
127.0.0.53in resolv.conf means systemd-resolved is in use - dig deeper via D-Bus/etc/NetworkManager/conf.d/resolvconfwhich manages/etc/resolv.confdynamicallymacOS
Alternative using SystemConfiguration framework:
Windows
Native approach using Windows API:
iOS & Android
On mobile, capture happens at VPN configuration time:
iOS: Query
NEDNSSettingsfrom current network configurationAndroid: Use
ConnectivityManager.getLinkProperties().getDnsServers()Store these before applying Mycelium's VPN DNS settings.
Component 3: System DNS Hijack
Make the OS send DNS queries to our stub resolver.
Linux
Option A: Direct /etc/resolv.conf manipulation (simple but fragile)
Option B: systemd-resolved integration (cleaner on systemd systems)
Option C: Split DNS only via resolved (cleanest for split mode)
Detection: Which method to use
macOS
Option A: Per-TLD resolver (split mode only - RECOMMENDED)
This is the cleanest approach - no system-wide DNS changes, works alongside existing DNS.
Option B: System-wide DNS override (full mode)
Option C: Using scutil (more programmatic)
Windows
Option A: netsh (simple, built-in)
Option B: PowerShell (more robust)
Option C: NRPT for split DNS (Windows 7+, RECOMMENDED for split mode)
Name Resolution Policy Table allows routing specific domains to specific servers:
Registry-based NRPT (persistent, survives reboot):
iOS
Using Network Extension framework:
Key considerations:
matchDomains = ["mycelium"]→ only.myceliumqueries go through VPN DNSmatchDomains = [""]→ ALL queries go through VPN DNS10.0.0.1)127.0.0.1from within VPN - traffic wouldn't route correctlyAndroid
Using VpnService:
Split DNS on Android:
Android VpnService doesn't support per-domain DNS like iOS. Workarounds:
Handle in resolver: Route all DNS through Mycelium resolver, which then forwards non-Mycelium queries to original system DNS
Route only port 53: Only capture DNS traffic:
Component 4: Lifecycle Management
Startup Sequence
Shutdown Sequence
Crash Recovery
Store state to allow recovery after crash:
Security Considerations
Port 53 Binding
127.0.0.1:53, never0.0.0.0:53DNS Cache Poisoning
Privilege Management
DNS Leak Prevention
In full mode, ensure DNS doesn't leak via:
Testing
Manual Testing
Integration Tests
Platform Summary
~myceliumdomain~./etc/resolver/myceliumnetworksetup -setdnsservers.myceliummatchDomains: ["mycelium"]matchDomains: [""]addDnsServer+ default routeAppendix: Crate Dependencies