DNS Behavior Under Proxy: Routing and Leaks
This article is for technical discussion only. This site does not provide proxy services, nor does it offer complete tutorials on setting up proxies.
Glossary
To avoid ambiguity, here are the specific meanings of terms used throughout this article.
- Application (Client): Software that initiates network requests, such as a web browser.
- Proxy (Proxy Client): A proxy application running on the local machine or local network, such as Clash.
- Proxy Node: A server that forwards user traffic to the destination website.
- Local DNS: The DNS server queried by the proxy client.
- Remote DNS: The DNS server queried by the proxy node.
- System DNS: The default DNS server used by applications without proxy.
DNS
DNS is one of the cornerstones of the modern internet. Nearly all requests are initiated with domain names, yet internet communication requires IP addresses. The service responsible for resolving domain names to IPs is DNS. In October 2025, AWS DynamoDB experienced a major outage in the us-east-1 region, triggering cascading failures across over a hundred AWS services and severely impacting well-known platforms including Steam and Slack. The root cause was a DNS error — a testament to its critical importance.
As a foundational service, DNS requests are straightforward from the client’s perspective — no handshake, no connection. Applications just fire off a single packet and wait for a reply. In a typical environment without a proxy, a simplified web request looks like this:
sequenceDiagram Client->>DNS: Query "example.com" DNS->>Client: 113.108.81.189 Client->>QQ: Send request to 113.108.81.189
- The client wants to visit a website but doesn’t know its IP address (assuming no local cache).
- The client (or the OS) sends a query to the local DNS server.
- Only after receiving the DNS response can the client actually assemble and send the request.
DNS Under a Proxy
Proxy Modes
Before diving into DNS behavior under a proxy, we need to understand which traffic the proxy client can capture. This depends on the proxy mode. The two most common modes are system proxy and TUN.
For now, we only consider plaintext DNS over UDP. DoH and DoT are encrypted, and from the proxy’s perspective, they are typically treated as application traffic similar rather than DNS queries.
System Proxy
sequenceDiagram
Client->>+Clash: "https://google.com"
Clash->>...:
...->>Clash: Google
Clash->>Client:
A system proxy is more like a gentleman’s agreement. The proxy modifies system settings to announce, “Please route all your traffic through me instead of sending it out directly.” Unfortunately, not all applications honor this — just as you wouldn’t necessarily walk into a store just because there’s a promotional sign in front of the door. Browsers are generally the most compliant, while applications like Steam and games tend to ignore it. The key point is that most systems and applications only recognize HTTP proxy that doesn’t support UDP traffic, so applications naturally use domain name as the destination insead of resolving it by themselves. In this mode, the proxy client receives mostly domain-based HTTP requests and rarely encounters DNS traffic. The reason it’s “rarely” rather than “never” is that some systems and applications also support SOCKS5 proxies. While applications typically still send domain names directly, it is technically possible to perform DNS queries through a UDP-capable SOCKS5 proxy (not shown in the diagram above).
TUN
sequenceDiagram
Client->>+Clash: Query "google.com"
Clash->>-Client: "209.85.2.2"
Client->>+Clash: HTTP "209.85.2.2"
Clash->>+...:
...->>-Clash: Google
Clash->>-Client:
In contrast, TUN is a heavy-handed approach. It works by creating a virtual network interface that takes over all outbound traffic — TCP, UDP, and even ICMP — making it effective for all applications, including games. The applications are unaware of the existence of proxy and perform DNS lookups as usual, which are then captured by the proxy client. In this mode, the proxy receives a large volume of DNS traffic and typically does not encounter domain-based HTTP requests.
Due to the SNI extension in TLS and the requirements of the HTTP protocol, requests will most likely contain a domain name. However, from the TCP package perspective, the destination is an IP address, not a domain name.
Traffic Routing and DNS Modes
Now let’s get to the heart of the matter. DNS under a proxy environment is inherently tricky. You might think, “What’s the big deal? Just forward DNS requests through the proxy.” The problem is that the “proxy” is typically used to solve connectivity issues between the client and the destination website. In the context of a DNS query, the destination is the DNS server itself, which is usually a domestic service that’s directly reachable. The real issue is that domestic DNS services may be poisoned, returning fake IPs for certain overseas domains. A proxy doesn’t change the ultimate destination of a request, so “forwarding DNS queries through the proxy” doesn’t change the fact that it’s still querying a domestic server, nor does it prevent receiving a poisoned response. The key isn’t whether to forward DNS traffic — it’s that the proxy must intercept applications’ DNS requests and, when necessary, force to use a more trustworthy DNS server.
To make this more concrete: suppose a device’s system DNS is set to 223.6.6.6 (Alibaba DNS) and it wants to visit google.com. The first step is sending a DNS query to 223.6.6.6 to resolve “google.com.” For this particular request, the destination server is Alibaba, not Google. Even if the query is forwarded through the proxy node, it still goes to Alibaba. Since Alibaba’s DNS is poisoned, the result will still be a bogus IP.
Furthermore, most of the time people configures traffic routing rules based on domain names and CIDRs. For these rules to work, the proxy must know both the target domain and IP of a request. But in TUN mode, the client only sends IP-based HTTP requests, and the proxy can only see the IP.
One approach solves both issues at once: the proxy client turns itself into a DNS server. This gives it control over which upstream DNS to query (avoiding poisoned results) and allows it to build a domain-to-IP mapping for reverse lookups.
redir-host
Due to numerous issues including first-packet latency caused by applications waiting for DNS responses, legacy redir-host mode has been deprecated.
The original idea behind redir-host was straightforward: do what a DNS server does, and track the results. This way, the IPs can be solved from the domain-based requests, and IP-based requests can be reverse-mapped to domains recorded during earlier DNS processing. In practice, however, it got burned by DNS poisoning. Firewalls commonly use a technique called DNS poisoning to block undesirable websites. Specifically, they race to respond to DNS queries with fake IPs before the authoritative server can reply, and they also poison cache servers. Applications cannot obtain the correct results without encrypted querying of overseas DNS servers.
But querying overseas servers every time is too slow, so redir-host introduced a patch: fallback. The core idea is to prefer local DNS results, but wait for a more trustworthy result from an overseas DNS queried through the proxy node, if the returned IP looks suspicious. Depending on the proxy client, the criteria for “suspicious” are somewhat configurable, but the default rule is typically “any overseas IP.” This is because DNS poisoning usually returns fake IPs geolocated overseas to avoid routing traffic to legitimate domestic nodes, which could cause unintended side effects.
It’s worth noting that for IP-based requests from the application, Proxy client (Clash) first consults its domain-IP mapping table to recover the domain, then forwards a domain-based request to the proxy server. The proxy node then performs a fresh DNS lookup there and uses the result to reach the destination. In other words, the DNS resolution happens on the proxy client is only used for routing decisions — the actual IP used to access the destination is determined by the DNS on the proxy node’s side. This is primarily because many services use global CDNs and rely on DNS to direct users to the nearest server. Letting the node that ultimately visits the website perform its own DNS lookup typically yields faster responses.
The diagram below shows the complete flow of a request in TUN mode. For system proxy mode, the first DNS query round is skipped, and the client sends an HTTP request for “google.com” directly to the proxy.
sequenceDiagram
Client->>+Clash: Query "google.com"
Clash->>+Local DNS:
Local DNS->>-Clash: 5.5.5.5
opt Local DNS returned a suspicious IP
Clash->>+Fallback DNS: Query "google.com"
Fallback DNS->>-Clash: 209.85.2.2
end
Clash->>-Client:
Client->>+Clash: HTTP "209.85.2.2"
Clash->>+Proxy: HTTP "google.com"
Proxy->>+Remote DNS: Query "google.com"
Remote DNS->>-Proxy: 209.85.3.3
Proxy->>+Google: HTTP "209.85.3.3"
Google->>-Proxy: HTTP Response
Proxy->>-Clash:
Clash->>-Client:
A set of mechanisms have been built in redid-host in order to reverse-map IPs to domains for rule matching, but comes with two notable drawbacks:
- Even assuming the proxy always obtains unpoisoned DNS results, CDNs often cause multiple domains to resolve to the same IP. This makes it impossible for the proxy to reverse-map an IP back to a specific domain, significantly reducing routing accuracy — especially in TUN mode.
- If the destination matches a domain-based rule (i.e., no IP-based rule matching is needed), the entire round-trip to obtain an unpoisoned DNS result is pointless. The client has to wait for the useless DNS response before it can construct and send the TCP (HTTP) packet, adding hundreds of milliseconds of latency for overseas domains.
fakeip
fakeip is currently the most popular DNS mode, also known as fakedns.
fakeip addresses both major drawbacks of redir-host. We’ve established that the IP resolved by the proxy client isn’t used for the actual connection, since the proxy attempts to recover the domain name from the IP before forwarding traffic to the proxy node. If that’s the case, why not just respond with a fake IP? And so fakeip was born.
Whenever a DNS query is received, the proxy client assigns an address from a configured private IP range and records its association with the domain name. Since the IP is generated by the proxy, each domain is guaranteed to map to a unique IP. This ensures that subsequent IP-based requests can always be reverse-mapped to a domain.
A typical request flow under fakeip looks like this:
sequenceDiagram
Client->>+Clash: Query "google.com"
Clash->>-Client: 198.18.0.16
Client->>+Clash: HTTP "198.18.0.16"
Clash->>+Proxy: HTTP "google.com"
Proxy->>+Remote DNS: Query "google.com"
Remote DNS->>-Proxy: 209.85.3.3
Proxy->>+Google: HTTP "209.85.3.3"
Google->>-Proxy: HTTP Response
Proxy->>-Clash:
Clash->>-Client:
However, fakeip has its own glitches:
- Some applications validate the resolved IP and treat obviously invalid results as a network failure.
- If the application caches the resolved IP and the proxy is not running, all requests will fail until the cached DNS record expires.
- Local DNS query is still required for matching IP-based routing rules — though latency can be slightly optimized by returning the fake IP first and querying in the background.
For the first point, most proxy clients support a filter list. Domains on this list fall back to redir-host behavior, returning real IPs to the application. With a well-maintained list, fakeip has no significant drawbacks.
realip
Although fakeip solves the latency issue and uses a filter list to avoid breaking certain applications, maintaining a domain list is not easy. Some games even perform targeted detection for anti-cheat purposes. Additionally, DNS leaks are difficult to fully eliminate under fakeip (see below). This led to the proposal of realip.
As the name suggests, realip responds to applications with real IPs obtained from DNS servers. Sounds similar to redir-host, right? The key differences are twofold:
- The proxy client must support rule-based routing for DNS, so overseas domains are never queried against domestic DNS servers. This prevents leaks and completely eliminates the possibility of receiving poisoned IPs.
- The proxy client must support sniffing.
Borrowing Elon Musk’s favored first-principles thinking, realip doesn’t try to patch the shortcomings of previous approaches. Instead, it builds a new solution from the original problems. Let’s revisit the issues that motivated redir-host:
- The default system DNS may return poisoned results.
- The proxy client cannot reverse-map IPs to domains, preventing it from matching domain-based routing rules (especially in TUN mode).
Realip’s answers to these problems are: domain-based DNS routing and sniffing. Realip isn’t a standalone feature but rather a specific configuration built on these two capabilities. Any proxy client that supports both can implement realip.
Domain-Based DNS Routing
In traditional implementations, the proxy client always sends DNS queries to domestic DNS servers. realip selects the target DNS server based on the domain being queried. While this doesn’t significantly reduce latency, it prevents DNS leaks. Note the distinction from “routing DNS traffic” — the latter determines which network path is used to reach the DNS server (supported by most proxies), while the former determines which DNS server to query. The two are often used together, since overseas DNS servers are generally hijacked or blocked.
Sniffing
As mentioned earlier, in TUN mode the proxy receives IP-based requests — mostly TCP/UDP packets whose payloads are TLS or HTTP traffic. This makes it highly likely that the domain can be extracted from the SNI or the Host HTTP header.
SNI (Server Name Indication) is a TLS extension designed to solve the problem of a single IP hosting multiple domains, where the server doesn’t know which certificate to use for the handshake. The solution is straightforward: the client sends the target domain in plaintext during the handshake.
Previously, proxy clients wouldn’t inspect the contents of L3 packets. Domain sniffing attempts to parse the payload, and if it’s a known protocol, extracts the domain name for rule matching. This eliminates the dependency on the IP-domain mapping table built during DNS processing.
A typical request flow under realip looks like this (the HTTP traffic from proxy node is omitted):
sequenceDiagram
Client->>+SingBox: Query "xxx.com"
alt Domestic domain
SingBox->>+Local DNS: Query "xxx.com"
Local DNS->>-SingBox: 209.85.3.3
else Overseas domain
SingBox->>+Proxy: Query "xxx.com"
Proxy->>+Remote DNS: Query "xxx.com"
Remote DNS->>-Proxy: 209.85.3.3
Proxy->>-SingBox: 209.85.3.3
end
SingBox->>-Client: 209.85.3.3
Client->>+SingBox: HTTP "209.85.3.3"
Note over SingBox: infer domain via sniff to match rules
SingBox->>Proxy: HTTP "xxx.com"
As you can see, realip shares the same first-packet latency issue as redir-host when querying overseas DNS. This is unavoidable as long as the proxy client wants to return real IPs — a trade-off for better application compatibility.
DNS Leaks
When we talk about “leaks,” at least two elements are involved: the payload (what is leaked) and the recipient (who it’s leaked to). In the context of DNS leaks, the payload is the content of the DNS query — essentially the domain the application is trying to access. The recipient is more nuanced: under the strictest definition, it’s anyone other than the intended DNS server. Since DoH and DoT encrypted DNS are not yet universally adopted and most DNS queries are still sent as plaintext UDP, DNS leaks are actually commonplace. So why dedicate an entire section to this?
Potential Consequences
DNS leaks can only expose the domain the client is trying to access — the specific URL and content remain encrypted. Under normal circumstances, this isn’t a major concern. Even from a privacy standpoint, it’s not much worse than SNI, which already exposes the target domain during the TLS (HTTPS) handshake. However, under a proxy environment — especially a cross-border proxy — the potential impact is significantly greater:
- Leaking the websites the client is attempting to visit to domestic ISPs, authorities, etc.
- Increasing the risk of the proxy node being identified and blocked.
- Enabling websites to detect that the user is using a proxy.
We know that proxy solves connectivity issues with blocked sites primarily because the proxy node itself isn’t on the firewall’s blocklist, and specialized protocols disguise traffic as requests to unrestricted sites, effectively smuggling data past the firewall. DNS leaks partially expose statistical patterns. Imagine a client that just queried a sensitive domain name and immediately begins transmitting data to a specific IP (the proxy node). Over time, as sample data accumulates, it’s not hard to infer that this IP is actually a proxy server used to circumvent network restrictions. With today’s machine learning capabilities, automated detection of such traffic patterns is likely mature and already deployed in production. Therefore, one consequence of DNS leaks is an increased risk of the proxy node being identified and blocked.
Additionally, websites can technically use DNS to detect whether a user is using a proxy. To explain this, let’s review the simplified DNS resolution process using “netflix.com” as an example:
- The client queries a recursive resolver (e.g., Google Public DNS
8.8.8.8) for “netflix.com.” - The recursive resolver queries the root server for “netflix.com,” but it only knows that the TLD server responsible for “.com” is 1.1.1.1.
- The recursive resolver then queries 1.1.1.1, which only knows that the authoritative server for “netflix.com” is 2.2.2.2 (the domain’s NS record), not the actual IP.
- The recursive resolver finally queries 2.2.2.2 and obtains the result.
Among all the servers queried in this chain, only the final authoritative server can be configured by the domain owner. While most websites use authoritative servers hosted by registrars or major cloud providers for reliability and reduced operational overhead, they could theoretically point their NS records to a self-hosted instance for special purposes — and thereby easily obtain the requester’s IP address. Note that the “requester” here is the recursive resolver, not the end user. But this is sufficient to determine the user’s approximate region. The website then simply compares the geographic region of the DNS query’s source IP with the IP making the actual HTTP request to identify potential proxy usage. So DNS leaks can enable websites to detect that a user is using a proxy, potentially leading to measures such as blocking copyrighted content or redirecting users to the intended market. Note that DNS-based geolocation is just one method websites may use to detect proxy — others include EDNS and WebRTC.
How to Detect DNS Leaks
For ease of discussion, in the following sections “DNS leak” is defined as: querying a domestic DNS server for an overseas domain, whether the request is encrypted or plaintext.
- Start the proxy with your usual settings (but do not use global mode).
- Open https://browserleaks.com/dns in a browser and observe the DNS server IPs and their geolocations captured in the “Your DNS Servers” field.
- Important: for reliable results, the above domain must not be matched by a domain-based routing rule to use the proxy — otherwise you’re just fooling yourself.
If the test site captures IPs located domestically, a DNS leak has occurred.
Note that depending on your network configuration, web tests may produce false negatives (i.e., a leak exists but isn’t detected). A more accurate method is to capture packets with tools like Wireshark. Every DNS request must fall into one of the following categories; otherwise, a leak has occurred:
- Queries for domestic domains.
- Queries sent to overseas DNS servers in encrypted form (or through the proxy node).
Common Causes and Solutions
Bad Routing Rules
As mentioned above, aside from requests matching the “Direct” rule, the only reason the proxy client initiates a local DNS query for a domain-based HTTP request is to match IP-based routing rules. For example:
IP-CIDR,64.233.177.188/32,PROXY
DOMAIN,google.com,PROXYAlthough “google.com” is in the rule list, the proxy checks the IP-based rule first. If the request target is a domain, the proxy will attempt to resolve it. While some proxies support DNS routing, if the regular rules are misconfigured, the DNS rules are likely incomplete too, ultimately sending the query to a domestic DNS server.
Here’s a more subtle example:
...
DOMAIN,google.com,PROXY
GEOIP,CN,DIRECTIf the client tries to access a niche overseas website not in the rule list, a DNS query will still be triggered to match the trailing GEOIP rule.
Mitigations are:
- Prioritize comprehensive domain-based rules and always place them before IP-based rules.
- Add the
no-resolvekeyword (or equivalent) to IP-based rules (including built-inGEOIPrules). This causes domain-based requests to skip IP rule matching entirely rather than attempting resolution. To maintain routing accuracy, this requires well-configured domain rules as a prerequisite.
Bad DNS Configuration
The measures above can prevent DNS queries initiated by the proxy client for rule matching, but they cannot stop queries made in response to applications DNS requests (primarily in TUN mode). There are two approaches:
- Don’t query at all — just respond with a fake IP: use fakeip mode.
- Allow queries, but strictly use overseas DNS for overseas domains (preferably via DoH in case proxy nodes don’t support UDP).
- Requires proxy client support for DNS routing.
- Requires comprehensive domain rules.
- To handle niche sites not in the rule list, it’s recommended to only match domestic domains and default to overseas DNS for everything else.
Approach 2 is essentially the realip DNS mode described above.
Software and System Behavior
In theory, under fakeip mode, no local DNS queries should occur if IP-based rule matching isn’t needed. However, some proxy clients may force domain resolution for UDP traffic. The latest HTTP/3 protocol is based on QUIC, which runs on top of UDP. Besides switching proxy clients, you can temporarily disable QUIC support in your browser. For Chrome, navigate to chrome://flags, search for “Experimental QUIC protocol,” and set it to “Disabled.”
Additionally, in TUN mode, all traffic — including DNS queries — should theoretically only be sent through the proxy client’s virtual network interface. In practice, however, Windows has a feature called “Smart Multi-Homed Name Resolution” that sends DNS requests to all network interfaces. You can disable this in the Group Policy Editor under “Computer Configuration → Administrative Templates → Network → DNS Client → Turn off smart multi-homed name resolution” by setting it to “Enabled.”
Summary
This article discussed the complex DNS behavior under proxy environments, which depends on the proxy mode, DNS mode, and routing rules. There is no one-size-fits-all solution — you need to configure your proxy based on your specific requirements. Here’s a comparison of existing approaches:
| Behavior | Pros | Cons | |
|---|---|---|---|
| redir-host | Queries both domestic and overseas DNS locally | Returns real IPs; good compatibility | High latency; DNS leaks; may fail to reverse-map domains, reducing routing accuracy |
| fakeip | Always returns fake IPs | Low latency | Lower compatibility; small probability of DNS leaks |
| realip | Rule-based DNS queries + domain sniffing | Good compatibility; no DNS leaks | High latency |
Regardless of which approach you choose, it is strongly recommended to always prioritize domain-based routing rules.
If you don’t mind leaking DNS queries for niche overseas websites to domestic services, IP-based fallback rules are acceptable. Otherwise, use a whitelist approach: match known domains for direct connection and proxy everything else. Do not include any IP-based rules, or add no-resolve or equivalent configuration to them.
Across the Great Wall we can reach every corner in the world.
— The first email sent from China on September 14, 1987