This article explains how FakeDNS substitutes virtual IPs for real DNS answers and how to configure it. It's written for users setting up TUN transparent proxy who want domain-based routing rules to keep working, and it helps you decide whether to enable it and how to verify it afterwards.
The full path of a request: where FakeDNS steps in
Without FakeDNS, an app first asks the system DNS server for the domain's real IP and then connects to that address. Under TUN mode the core sees IP packets, so if the destination doesn't match any rule, the domain information is lost and routing has to fall back to IP-based rules.
With FakeDNS enabled, DNS queries are handled by the Xray DNS module. Instead of asking the upstream DNS server for a real address, it picks an unused IP from the 198.18.0.0/15 range and records a domain-to-virtual-IP mapping in memory.
The app then connects to that virtual IP. When the traffic enters the TUN interface, the routing engine sees that the destination falls inside the FakeDNS range, looks up the original domain through the mapping table, and geosite, domain, and other rules match as usual before the traffic is handed to the right outbound.
Real DNS resolution is deferred to the outbound stage and performed by the proxy server on the remote end. For proxied traffic, that saves one local DNS round trip and makes connection establishment faster.
The point of FakeDNS is not to forward DNS queries through the proxy, but to skip local resolution entirely and resolve only at the outbound stage. The round trip you save comes from the virtual IP letting the app connect immediately.
The virtual IP pool: where 198.18.0.0/15 comes from and why it won't conflict
198.18.0.0/15 covers 198.18.0.0 through 198.19.255.255, for a total of 131,072 addresses. This range is reserved by RFC 2544 for network device performance testing, and no public service is deployed there, so using it for virtual addresses won't conflict with any real site.
The mapping table stays in memory and entries are reclaimed as soon as a connection ends, so the default pool is more than enough for everyday use. Xray also lets you change the range through the root-level fakedns pool field, but the default is fine in most cases.
Configuration: fake server entries and the root-level fakedns field
{
"dns": {
"servers": [
"https://1.1.1.1/dns-query",
{
"address": "fake",
"domains": ["geosite:geolocation-!cn"]
}
]
}
}
The first entry is a regular DoH server that handles real resolution; the second entry with address set to fake hands out virtual IPs. The domains filter decides which domains go through fake — in the example above, only non-China domains get virtual IPs, while domestic domains are still resolved normally by 1.1.1.1.
If you'd rather not edit the servers array by hand, Xray 1.8.0 and later support a root-level fakedns field that is equivalent to injecting a fake server entry automatically. It's a good fit if you just want a switch without touching the config:
{
"fakedns": {
"pool": "198.18.0.0/15",
"skipFallback": false
}
}
skipFallback controls fallback behavior: when set to false, domains not handled by the fake entry keep looking for other DNS servers in the list; when set to true, it returns a failure immediately. Leave it at the default false for everyday use.
- Keep the domain resolution strategy set to AsIs: once FakeDNS takes over queries, routing matches by domain, so there's no need to resolve to an IP locally first.
- Don't switch to IPOnDemand: that makes the core perform real resolution during the matching stage and defeats the round-trip savings of FakeDNS.
- Keep a geosite:cn direct rule in the routing table: domestic domains never enter the fake list, so direct traffic is unaffected.
Enabling FakeDNS in v2rayN and v2rayNG
v2rayN desktop
- Menu location
- Settings → Parameter Settings
- Section
- Routing
- Toggle
- Enable FakeDNS
- Core requirement
- Xray core
- How to apply
- Restart the core
Keep the domain resolution strategy set to AsIs; do not switch to IPOnDemand.
v2rayNG on Android
- Menu location
- Settings → DNS Settings
- Toggle
- Enable FakeDNS
- Core requirement
- Xray core
- How to apply
- Restart the app after going back
The v2fly core also recognizes DNS entries with address set to fake, so v2flyNG users can enable it in a custom config.
In both clients, the toggle only affects the config generated for the core, so you must restart the core or the app for the DNS module to pick up the new state.
The first thing to do after enabling it is to visit a domestic site and confirm it goes direct and isn't taken over by fake. This catches mistakes in the domains filter early and is more effective than testing a foreign site right away.
Four scenarios where you should not enable FakeDNS
- System proxy mode: the app already hands the domain to the proxy and routing can match by domain anyway, so FakeDNS only adds an unnecessary virtual IP translation.
- LAN and intranet resolution: answers for NAS, printers, and corporate intranet domains get replaced with unroutable virtual IPs and only work through fallback resolution, so they often fail outright.
- Local DNS tools: ad blocking and intranet resolution in AdGuard Home, self-hosted DoH, and similar tools get bypassed by fake, so their filtering rules stop working.
- Configs built around IP rules: virtual IPs never match CIDR or IP-based rules, so routing results won't match what you expect.
There's only one test: traffic must go through the TUN interface and routing must be primarily domain-based. If either condition is missing, FakeDNS offers little benefit while its side effects can break connections outright.
Before enabling it, write down your current domain resolution strategy and DNS server list. Most FakeDNS problems come from DNS configuration, and keeping a reference makes it easy to restore.
How to verify FakeDNS and common issues
The quickest way to check whether FakeDNS is active is to look at the core log. After enabling it, visit a foreign site and the log should show something like this:
2026/07/24 10:32:11 [Info] [TCP] dialing to target:198.18.0.7:443 via proxy
If the destination is 198.18.x.x, the connection really used a virtual IP; combined with the domain shown in the routing log, you can confirm that both FakeDNS and your domain rules are working.
Domestic direct sites got slower after enabling FakeDNS?
That means domestic domains are being taken over by fake too. Narrow the domains filter on the fake entry to a set of non-China domains (such as geosite:geolocation-!cn), keep domestic domains on a regular DNS server, then restart the core and test again.
Some apps can't connect at all under TUN mode?
These apps usually validate the destination IP or use custom UDP. Add a direct rule for that app or exclude it by process so its traffic doesn't go through TUN — there's no need to disable FakeDNS globally.
Everything works after turning FakeDNS off — what was wrong?
It's usually the DNS server order or a mistake in the domains filter. Restore the default DNS config first, then add entries back one at a time following the pattern of non-China domains through fake and domestic domains through local resolution, changing only one thing at a time.
Do I need FakeDNS in system proxy mode?
No. Under system proxy, the app already hands the domain to v2rayN and routing matches by domain directly. FakeDNS only pays off with TUN transparent proxy, so leave it off in system proxy mode.