For macOS users who have imported a subscription and can connect to a node, but find that some domains won't load or websites in mainland China are slow. First, distinguish system DNS from core DNS, then configure direct DNS, remote DNS, and domain rules. Finally, use Terminal and logs to verify the actual paths. This guide focuses on v2rayN with the Xray core. If you switch cores, check the DNS fields again rather than copying the configuration as is.
1. Understand the three DNS paths
DNS translates domain names into IP addresses. v2rayN is the client; the selected core handles the actual connections and some DNS resolution. The browser, macOS system resolver, and the core's built-in DNS may all take part in a single request. Changing one setting does not mean every request will use the new configuration.
This simplified flow shows what happens when an app passes a domain to the proxy. If the app resolves the domain locally first, the proxy may receive only an IP address. If the proxy server resolves the domain, the local core may not send a DNS query for it at all. So if a domain doesn't appear in the logs, that doesn't necessarily mean the configuration isn't working.
- Resolver selection: Send domains in mainland China to a direct resolver and domains that need a proxy to a remote resolver.
- DNS transport path: Check separately whether the query itself goes out directly or through the proxy.
- Connection route: After an address is resolved, routing rules determine how the web connection is sent.
2. Configure direct and remote DNS
In v2rayN, open Settings → DNS Settings, then check the active core under Settings → Parameter Settings. Fields may differ by version and core. If the interface has separate DNS settings for each core, edit the set for the one in use. Save a copy of the current configuration first, and change the resolvers without also changing routing, TUN, and IPv6 settings.
| Role | Example to start with | What to check |
|---|---|---|
| Direct DNS | 223.5.5.5 | Reachable on the current network; standard DNS queries are usually unencrypted |
| Direct DoH | https://dns.alidns.com/dns-query | The core supports this format; the endpoint domain can be resolved during bootstrap |
| Remote DoH | https://dns.google/dns-query | Queries use the intended proxy route; TLS verification and system time are correct |
These are example addresses for public services, not a speed ranking for every network. Start with one clearly reachable resolver for each role. Adding many addresses increases fallback and parallel-query complexity, and makes logs harder to troubleshoot. On corporate or campus networks, or wherever local domain resolution is required, keep the relevant internal resolver path.
Port numbers identify transport types; they do not mean your Mac is listening on those ports. v2rayN's proxy listening port and DNS listening port are separate settings. Don't enter an HTTP or SOCKS proxy port in macOS's DNS server list.
3. Make geosite rules work for both DNS and routing
geosite contains domain categories, while geoip contains IP categories. Neither is a resolver or provides DNS service. In Xray, for example, the routing rule geosite:cn can match domains in mainland China. Entries in built-in DNS servers can also use domains to specify which domain sets they should handle first. These features are related, but they are not interchangeable.
- Check the rule data first. Make sure the active core can load the domain and IP data in use, and check the logs for missing files or unknown categories. Category contents can change, so don't treat them as permanently accurate geographic boundaries.
- Set the direct-resolution scope. Send domains matching
geosite:cnto direct DNS first. Handle internal domains with separate rules so they aren't sent to public resolvers. - Set the remote-resolution scope. Send domains that need a proxy to remote DNS. If you use
geosite:geolocation-!cn, first check that the category exists in your data. It's a category set, not a live check for every domain outside mainland China. - Check routing for connections. Send domains in mainland China directly and proxy domains that need it. Xray evaluates routing rules in order, so place specific domain rules before broad rules that could match first.
- Check fallback behavior. Queries may be sent to another server when a domain doesn't match, the response is empty, or the returned address is unexpected. If a class of domains must never use direct DNS, check which domains can fall back as well.
In Xray, routing.domainStrategy controls whether routing uses DNS results to match IP rules. AsIs doesn't actively resolve domains for IP rules; IPIfNonMatch tries resolving a domain if no domain rule matches, then checks the IP rules. This is separate from DNS's queryStrategy, which mainly controls behavior such as the address families queried.
In short: match domain rules first, then troubleshoot IP rules
If a website uses the wrong outbound route, first check whether it matches the expected domain category and whether the rules are in the right order. Change the routing-stage resolution strategy only when the connection actually needs IP-based matching. Don't use a DNS change to mask a routing problem.
4. Prevent DNS pollution with DoH and handle bootstrap resolution
DoH sends DNS queries over HTTPS, protecting the connection between your device and the resolver and reducing the risk of interception or tampering in transit. It doesn't guarantee that the resolver returns a correct answer or hide the destination IP of your connection. A browser's own Secure DNS setting may also bypass the resolver configured in the core.
- Bootstrap resolution: Before connecting to an endpoint such as
dns.google, the client needs to know its IP address. If resolving the endpoint itself depends on that same DoH service, which isn't connected yet, you get a circular dependency. - Node hostnames: If a proxy node uses a domain name, it must be resolved before the proxy connection can be established. Don't make the only resolution path for a node depend on a service that can only be reached through that node.
- Certificate verification: On macOS, open System Settings → General → Date & Time and check that time is set automatically. For certificate errors, check the clock, endpoint name, and network filtering. Don't bypass the problem by disabling verification.
- Outbound routing: If a remote resolver must be reached through the proxy, configure its DNS transport and route explicitly using options supported by the active core, then confirm the route in the logs. Don't infer behavior from a field name alone.
Don't change a DoH endpoint's hostname to an arbitrary IP just to avoid bootstrap resolution. HTTPS also depends on the certificate name and server virtual hosting. Use an IP endpoint only when the DNS provider explicitly supports it and publishes that format.
5. When to enable FakeDNS
FakeDNS isn't another public DNS service. It assigns a synthetic IP to a domain and maps that IP back to the original domain when the traffic re-enters the core. This lets the core apply domain-based routing even if an app later submits only an IP address. FakeDNS is often used with transparent traffic interception, but enabling TUN doesn't automatically mean you need it.
| Comparison | DoH | FakeDNS |
|---|---|---|
| Main purpose | Encrypt real DNS queries in transit | Preserve the association between a domain and its synthetic IP |
| What it returns | Real address records from the resolver | An address generated from a local mapping pool |
| Key requirements | Reachable endpoint, valid certificate, correct outbound route | DNS queries and subsequent connections are both handled by the supporting mechanisms |
| Common issues | Bootstrap resolution failure, connection timeout | Synthetic IP bypasses the proxy; cached mapping is out of sync |
If you use only the system proxy and the browser already passes domains to the proxy, leave FakeDNS off to start. In a TUN setup, if an app resolves domains before the core sees them and domain rules stop working, check whether the active core and client fully support DNS interception and mapping. Re-test after switching cores; don't assume they work the same way.
In short: verify traffic interception before enabling FakeDNS
First confirm that DNS queries follow the intended handling path. Then make sure connections to synthetic addresses can't bypass the client. If only some apps lose connectivity after enabling FakeDNS, check the cache, bypass rules, and mappings before switching nodes.
6. Verify DNS and proxy behavior on macOS
Change one group of settings at a time. After saving, restart the core and check the startup logs for errors before running the tests below. The domains in the commands are examples; replace them with the hostname of the site you're troubleshooting. Never post subscription URLs, node credentials, or a full connection configuration in public logs.
- Check system DNS. Run
scutil --dnsto see which resolvers are configured for the current network, VPN, or other network services. This shows system resolver settings, not the full status of Xray's built-in DNS. - Test a specific resolver. Run the
digcommand below to check whether the resolver responds on your current network. This does not verify v2rayN's DNS split rules. - Test the proxy connection. First check the local listening port and protocol under Settings → Parameter Settings, then send a proxied request. The example assumes
10808provides an HTTP or mixed proxy. If it only provides SOCKS, don't use the HTTP syntax. - Check the core logs. For the same test window, look for the target domain, matched route, selected outbound, and DNS timeouts. Raise the log level temporarily if needed, then restore it when testing is done.
# Check the macOS system resolver
scutil --dns
# Query a specific resolver directly; 2-second timeout, 1 attempt only
dig @223.5.5.5 www.baidu.com A +time=2 +tries=1
# Use only if port 10808 provides an HTTP or mixed proxy
curl -I --proxy http://127.0.0.1:10808 \
--connect-timeout 10 --max-time 20 https://www.example.com/
If the listening port supports SOCKS5, you can compare the following commands. The first usually resolves the destination domain locally; the second passes the domain to the SOCKS proxy. If the second works and the first doesn't, check the local resolution path first. Also check the logs to rule out address-family differences or site-specific connection restrictions.
# Resolve the destination domain locally
curl -I --proxy socks5://127.0.0.1:10808 \
--connect-timeout 10 --max-time 20 https://www.example.com/
# Pass the destination domain to the SOCKS proxy
curl -I --proxy socks5h://127.0.0.1:10808 \
--connect-timeout 10 --max-time 20 https://www.example.com/
If you still get the old result after changing settings, quit and reopen the test app first. To clear the macOS system DNS cache if necessary, run the following commands in Terminal. The second requires administrator privileges. These commands don't clear browser-specific caches, core caches, or upstream resolver caches.
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
7. Common DNS split-routing questions
Why did every website get slower after I switched to DoH?
Restore the previous resolver first and check whether things return to normal. Then check DoH endpoint bootstrap resolution, the proxy route, and timeout logs. If domains in mainland China also use the remote resolver, they may resolve to addresses that don't work well with your direct connection. Split both DNS resolution and connection routing for those domains instead of simply changing the DNS address.
dig works, but my browser still can't open sites. What does that mean?
dig @223.5.5.5 only confirms that this query to the specified resolver got a response. The browser may use its own Secure DNS, or there may be a conflict with the system proxy or an extension. First test again with the explicit proxy command above, then check the browser's proxy and Secure DNS settings.
Does a website in mainland China resolving to an overseas IP always mean DNS pollution?
Not necessarily. CDN routing, resolver location, and service deployment can all affect the result. Query the same domain through both a direct and a remote resolver, then compare connection success and routing. Different answers alone don't prove DNS pollution, and you shouldn't permanently add a one-off result to your hosts file.
If a domain has an A record but times out, should I disable IPv6?
Query A and AAAA records separately, then compare the results of curl -4 and curl -6. When testing through a proxy, the proxy may choose the address family, so the result doesn't directly tell you whether local IPv6 is working. Identify the failing IPv6 path before changing the relevant query or outbound route. Avoid disabling an entire system feature unnecessarily.
Can I use the same DNS configuration on Android?
The split-routing principles apply, but don't copy the configuration as is. v2rayNG uses the Xray core, while v2flyNG uses the v2fly core. Check each client's VPN traffic interception, DNS entry points, and supported fields separately. When migrating, test one domain and one resolver first, then add category rules and fallback behavior.
Check three things before calling the setup done: domains in mainland China use the intended direct DNS path, domains that need a proxy don't unexpectedly fall back to direct DNS, and connections use the correct outbound route. Keep a working copy of the configuration, then add DoH, IPv6, or FakeDNS one at a time so you always have a clear rollback point.