1. Separate DNS routing, web traffic, and your rules
Seeing your proxy's public IP on a website doesn't mean DNS lookups also went through the proxy. A visit involves at least two paths: the app first resolves the domain, then connects to the destination address. A system proxy usually handles only apps that honor its settings. The system resolver, an app's built-in DNS, and a browser's Secure DNS may each use a different route.
Here, “DNS leak” means a query that should use a specified resolution path is instead sent to an unexpected resolver or sent directly over the local network. If your rules intentionally send local domains directly and resolve them locally, seeing a local resolver isn't necessarily a problem. But if all regular queries are meant to go through the proxy, the same result warrants investigation.
| What you observe | What it tells you | What it doesn't prove |
|---|---|---|
| Public IP shown by the website | The egress IP used for that website request | That other apps or DNS queries use the same egress |
| DNS IPs listed by the test site | The egress IPs of servers involved in recursive resolution | Whether traffic from your device to the resolver went through a proxy |
| A 198.18.x.x address is returned | This query received a mapping from a commonly used fake-ip address range | That all system queries are being intercepted |
| A local ISP resolver appears | There's a local DNS resolution path to investigate | That all connections bypass the proxy |
2. Run three comparisons on a DNS test site—not just by country
Record the test conditions first
Try the Standard and Extended tests at dnsleaktest.com, and compare the results with browserleaks.com/dns. These sites trigger lookups for test domains and record the recursive resolvers seen by the authoritative servers. They don't read your operating system's DNS settings directly from the browser.
- Note your current network, such as home Wi-Fi, along with the client mode, selected node, TUN status, and browser Secure DNS setting.
- Turn off the proxy and run a test as your baseline. Note the public IP, DNS provider, and resolver addresses. There's no need to share a full screenshot.
- Turn the proxy on without changing nodes, then run another test. Record system proxy and TUN mode separately, changing only one condition at a time.
- Temporarily turn off browser Secure DNS, restart the browser, and test again. If the results change, investigate the browser's own DoH route first.
These are recommended steps, not test results from this site. Focus on whether the results change when you toggle settings and whether they match your configuration policy. Don't treat a country label as the only criterion. Public DNS services use anycast, and geolocation databases can lag; a resolver's registered location may differ from the location of the server actually handling your request.
Narrow down the cause from the results
- Web IP changes, but DNS still shows your home ISP: Check whether system DNS queries reach the core and whether the browser has its own DNS settings.
- Only one browser shows different DNS results: Check that browser's Secure DNS, extensions, and independent proxy settings first.
- Two public DNS providers appear: You may have multiple upstream or fallback resolvers configured. The number alone doesn't prove a leak.
- Results match expectations only after enabling TUN: The system proxy wasn't covering the original DNS path. Continue by checking app coverage and IPv6.
3. Use fake-ip for domain mappings, then verify DNS upstreams
fake-ip returns a virtual address to the app and stores the domain mapping in the core. When a connection reaches the core, it can use that mapping to apply domain-based rules. fake-ip isn't an encryption protocol and doesn't automatically intercept operating system DNS. If the option is enabled but the system keeps querying the router, those queries may still bypass this path.
The following is a DNS snippet to merge into your existing configuration, not a complete subscription. Keep your existing nodes, proxy groups, and rules. Review and edit the existing top-level dns: section as a whole; don't add a second section with the same name to the file.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '+.lan'
- '+.local'
respect-rules: true
default-nameserver:
- 223.5.5.5
proxy-server-nameserver:
- 223.5.5.5
nameserver:
- https://cloudflare-dns.com/dns-query
listenis the core's DNS listening address. The example's1053is useful for targeted testing, but it won't make the system use that port automatically.default-nameserverresolves the domain names of DNS servers. It's part of the bootstrap resolution chain, not the regular upstream list for everyday queries.proxy-server-nameserverresolves proxy node hostnames and prevents the circular dependency of needing to connect to the proxy before resolving its hostname, while needing the hostname to connect.- The DoH URLs under
nameserverare used for regular upstream resolution. HTTPS encrypts the connection to the resolver; it doesn't guarantee that the connection goes through the proxy. - Domains in
fake-ip-filterdon't receive fake-ip mappings. This list isn't a direct-connection rule, nor does it mean those domains stop making DNS queries.
4. respect-rules controls upstream routing, not system interception
respect-rules: true makes relevant DNS upstream connections follow routing rules. It determines which egress the core uses for upstream requests; it doesn't determine whether system requests reach the core in the first place. Test these separately to avoid going in circles during troubleshooting.
Check which rule actually matches
- Make sure the current mode is rule mode:
mode: rule. Behavior in global or direct mode doesn't validate how rule mode works. - Check whether an earlier rule or rule set matches the DNS provider's domain to
DIRECT. If it matches a direct-connection rule, enablingrespect-ruleswon't make it use the proxy. - Use the client's connections panel and logs to check the rule and egress used by upstream connections. If needed, raise the log level briefly, then restore it to avoid continuously logging too many domains.
- To route DNS provider domains through a specific egress, use the exact name of an existing proxy group and place the rule before any broad rules that would match first. Don't use a group name that doesn't exist in the configuration.
If the existing configuration includes nameserver-policy, direct-nameserver, or fallback, check those too. Changing only nameserver may not change which resolver some domains actually use. For initial troubleshooting, reduce the variables; once the minimal configuration works, restore policies one at a time.
fallback isn't a simple “use this only when the primary DNS times out” switch. Fallback selection depends on conditions such as fallback-filter. Adding multiple resolvers at random to fix a suspected leak usually just makes the results noisier.
5. System DNS interception: what TUN and port 53 each do
Most desktop network settings accept a DNS server address but not a custom port such as 1053. So setting system DNS to 127.0.0.1 while the core listens only on 127.0.0.1:1053 creates a port mismatch. For a setup where the system sends DNS directly to a local listener, you need port 53 and must handle permissions and port conflicts. Don't blindly expose the listener to the entire LAN.
Another common approach is to use TUN to capture network traffic and send regular DNS requests entering the TUN interface to the core. This is still a merge-in snippet; first make sure the client hasn't generated a separate TUN configuration through its UI.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53andtcp://any:53cover UDP and TCP DNS requests on port 53 entering the TUN interface, respectively.auto-routeconfigures the relevant routes automatically. If startup fails, check service permissions, route conflicts, and other VPNs first instead of repeatedly changing DNS addresses.- DNS requests sent over the local link or excluded by routing may not enter the TUN interface. Check router DNS, other virtual adapters, and local loopback resolvers separately.
- DoH usually uses HTTPS on port 443, while DoT typically uses port 853. Intercepting port 53 doesn't automatically convert either into a DNS query handled by the core.
6. Retest on Windows, macOS, Linux, and Android
Windows: distinguish core listener tests from system-path tests
After starting any required client service or TUN with administrator privileges, run the two commands below. The first explicitly queries the local port 1053; the second uses the system's default DNS. They test different paths.
nslookup -port=1053 example.com 127.0.0.1
nslookup example.com
ipconfig /all
ipconfig /flushdns
For a domain not in the filter list, the first command should usually return a fake-ip from the configured address pool. Even if the second query is intercepted by TUN, the UI may still show the originally configured DNS server name, so that line alone doesn't prove a failure. Cross-check the returned address, logs, and test site. Clear the cache and revisit the test domain to avoid stale results.
macOS: check the resolver list, not just the Wi-Fi pane
scutil --dns
dig @127.0.0.1 -p 1053 example.com A
dscacheutil -q host -a name example.com
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
scutil --dns shows resolver configurations, including those scoped to an interface or domain. Use a targeted dig query to test the core listener; dscacheutil provides additional insight into the system resolution path. After granting the permissions required for TUN, retest in a browser. Don't skip system-level checks just because dig succeeds.
Linux: check systemd-resolved and loopback addresses
resolvectl status
resolvectl query example.com
dig @127.0.0.1 -p 1053 example.com A
sudo resolvectl flush-caches
If /etc/resolv.conf contains 127.0.0.53, apps are usually querying a local resolver stub; that doesn't mean the final upstream is on the same machine. Check per-interface DNS with resolvectl status. On distributions that don't use systemd-resolved, check NetworkManager or the DNS service actually in use. Don't overwrite a file managed automatically by a service.
Android: troubleshoot Private DNS separately from browser Secure DNS
On stock Android, temporarily disable any configured Private DNS under the usual path: Settings → Network & internet → Private DNS, then rerun the same tests. Menu names vary by manufacturer. Make sure the client has VPN permission and that per-app proxy settings don't exclude the test browser. Android typically allows only one regular VPN service at a time; another VPN or local filtering app may already be using this path.
In desktop Chrome, the usual path is Settings → Privacy and security → Security → Use secure DNS. Turn it off temporarily to isolate variables; after testing, you can turn it back on and check the actual egress for the DoH connection. Keeping browser DoH enabled isn't necessarily a leak—the key is whether it matches your DNS and routing policy.
7. If fake-ip works but problems remain, check these four things
- IPv6 takes a different route:
dns.ipv6: falsecontrols how the core handles AAAA queries; it doesn't disable system IPv6. Apps may still connect using cached data, built-in resolvers, or existing IPv6 addresses. Check IPv6 routing and TUN coverage. - A subscription update overwrote your changes: After reloading, check the effective configuration in use, not just the file in your editor. Manage fields that need to persist through the client's supported override, merge, or persistent configuration features.
- The filter list is too broad: Adding lots of public domains to
fake-ip-filtermakes them return real addresses but doesn't fix DNS egress automatically. Add exceptions only for domains with a confirmed compatibility issue, and retest after each change. - Stale cache entries or connections: System caches, browser caches, core mappings, and established connections all have their own lifetimes. After reloading, close test tabs; restart the browser if needed, then run a fresh test. Don't judge a new configuration using an old connection.
Finish with a verification checklist
- A targeted query to
127.0.0.1:1053gets a response, and regular test domains receive the expected fake-ip mappings. - You've checked both system-default resolution and an actual browser test—not just the core's listening port.
- DNS upstream egress matches your rules, and exceptions for node hostnames and bootstrap resolution are documented.
- You've checked regular DNS, browser DoH, IPv6, and per-app exclusions separately; you haven't mistaken port 53 interception for full-protocol interception.
- Retesting after subscription updates, client restarts, and Wi-Fi changes still produces results that match your policy.
The troubleshooting sequence boils down to three steps: prove queries reach the core, prove upstream connections use the right egress, then prove your everyday apps aren't taking another route. fake-ip handles domain mappings, respect-rules handles upstream routing, and system DNS interception handles the entry point. Each has a distinct role, so the logs don't have to become a guessing game.