Windows Guide Tags: WSL2 Clash localhost DNS

Fix WSL2 Traffic Through Clash on Windows:Localhost Forwarding and DNS Steps

You already run Clash on Windows, but inside WSL2 nothing respects it: apt update times out, git clone hangs, and curl says “Could not resolve host.” The failure is rarely “Clash is broken”; it is almost always a mismatch between where WSL2 thinks your proxy lives, which address the core is actually listening on, and how Linux resolves DNS while your profile uses Fake-IP or split rules. This guide walks the stack in order—host IP versus 127.0.0.1, port forwarding semantics, mixed-port and firewall alignment, proxy environment variables for common tools, and systemd-resolved interactions—so you can stop cargo-culting export https_proxy without understanding the hop.

Approx. 22 min read
Clash Editorial

1. What You Are Actually Debugging

WSL2 is a lightweight VM with its own virtual NIC, its own routing table, and its own Linux resolver stack. Windows applications that set “system proxy” to 127.0.0.1:7890 are talking to a listener on the Windows TCP stack. A process inside WSL2 is not on that stack unless you deliberately bridge the two with a known IP path or a supported localhost forwarding mode. Meanwhile, Clash may be listening only on loopback, only on a mixed port you forgot to expose, or on a port blocked by Windows Firewall for cross-interface traffic—even when the tray icon looks healthy.

Split the problem before you touch YAML. First confirm TCP reachability from WSL2 to the proxy port on the Windows side (for example with a one-line connectivity probe). Then confirm DNS: whether getent hosts example.com returns something consistent with your DNS mode in Clash, and whether systemd-resolved is rewriting upstreams behind your back. Only after both paths make sense should you tune rules and node groups.

For how mixed port and LAN-style exposure interact on the host, see our Windows 11 mixed port and firewall guide. For host-only TUN weirdness, the TUN troubleshooting article complements this one.

2. Why 127.0.0.1 Fails (Usually)

Documentation and blog posts love http_proxy=http://127.0.0.1:7890 because it is short. On a native Linux laptop that is often correct. Inside classic WSL2 NAT networking, 127.0.0.1 refers to the Linux guest, not the Windows host. Pointing apt at that address asks Ubuntu inside WSL to open a port on itself; unless you run a proxy there, the connection fails immediately or times out while you misread the error as “Clash down.”

Some users try localhost next. Whether that maps to the host depends on WSL version, Windows 11 feature level, and optional mirrored networking—details in section 4. Treat “localhost works on my machine” as anecdote until you verify with your build. The portable fix for NAT-style WSL2 remains: use the Windows host IP as seen from the guest, plus the same mixed port (or HTTP/SOCKS port) you exposed on Windows.

Tip: When a command fails, record three facts: the exact proxy URL you exported, the output of your host-IP discovery command, and whether ss -lntp inside WSL shows any local listener. That triplet eliminates half of Reddit threads.

3. Find the Windows Host IP From WSL2

On the default NAT topology, the Windows host is typically reachable at the default gateway IP from the guest’s point of view. A common quick check is reading the nameserver line Microsoft injects—often the same address WSL uses to reach the host resolver path:

grep nameserver /etc/resolv.conf | awk '{print $2}'

Another reliable pattern is to parse the default route:

ip route show | grep -m1 default | awk '{ print $3 }'

Both should yield an IPv4 address such as 172.x.x.x. Use that value as the host part of http_proxy and https_proxy. If you run multiple WSL distributions or VPN software on Windows, re-check after each change; the gateway can move when virtual adapters reorder.

Sanity checks

From WSL2, test raw TCP to your Clash port (replace host and port):

curl -v --connect-timeout 3 http://YOUR_HOST_IP:7890

You might get an HTTP error from the proxy—that is fine. You are proving the SYN completes. If the connection hangs or refuses, the issue is still on the Windows side: listener bind scope, “allow LAN,” or firewall—before DNS matters at all.

For a refresher on ports, modes, and documentation entry points, the configuration overview on this site stays mode-agnostic while you align the host.

4. WSL Networking Modes and Localhost

Microsoft continues to evolve WSL networking. In addition to classic NAT, newer releases expose options such as mirrored networking mode (conceptually sharing more of the host view with the guest). When mirrored mode is active, some workflows can treat 127.0.0.1 on the Linux side as reaching services bound on Windows—but the exact behavior depends on build and setting combinations you should not assume in documentation you ship to teammates.

Practical policy: pick one supported approach per machine, document it in your internal runbook, and verify with the TCP check from section 3. If mirrored mode is off, teach everyone the gateway IP method so interns do not inherit a brittle “localhost hack” from one forum post. If you standardize on mirrored mode, still confirm Clash’s listener and firewall rules because Windows updates can reset secondary toggles you relied on informally.

Note: .wslconfig changes require a full wsl --shutdown cycle to apply reliably. If you toggled networking experiments mid-session, stop and restart WSL before declaring victory.

5. Clash on Windows: Listen Address and Firewall

Once WSL2 knows where Windows lives, Windows must actually accept inbound TCP on your proxy port from that virtual subnet. In Clash-family GUIs this is usually labeled Allow LAN or equivalent; in YAML you align concepts like allow-lan and bind addresses so the core listens on 0.0.0.0 (all interfaces) rather than only 127.0.0.1. If the listener stays on loopback, WSL2’s packets never arrive—exactly like the “works on the PC, fails from the phone” story, except the “remote” client is your own penguin.

Pair that with Windows Firewall. An application rule for your Clash executable is the friendly path; a dedicated inbound rule for the TCP mixed port is the precise one. Scope rules to Private networks when you can. Corporate Group Policy may still block listening sockets; no amount of YAML fixes that class of restriction.

Keep the external controller port separate in your head. Opening the REST API broadly is not a substitute for exposing the HTTP/SOCKS proxy port. Forward the port that actually carries user traffic.

6. Proxy Environment Variables

Most CLI tools honor http_proxy and https_proxy (lower case is widely accepted; some also read uppercase variants). Many also respect all_proxy for schemes such as SOCKS5, depending on the library. A typical HTTP mixed-port setup looks like:

export HOST_IP=$(ip route show | grep -m1 default | awk '{ print $3 }')
export http_proxy="http://${HOST_IP}:7890"
export https_proxy="http://${HOST_IP}:7890"
export HTTP_PROXY="$http_proxy"
export HTTPS_PROXY="$https_proxy"

Adjust the port to match your profile. If you terminate TLS inside a SOCKS hop instead, switch the scheme and port accordingly.

no_proxy

Corporate registries, private Git remotes on RFC1918 space, and local Kubernetes endpoints often need bypass rules. Maintain a deliberate no_proxy list for hostnames and CIDRs that must not leave the tunnel. Forgetting no_proxy is a common reason internal Git servers “break” the moment you export proxies globally in ~/.bashrc.

7. apt, curl, and git

apt reads proxy settings from configuration files such as /etc/apt/apt.conf.d/ snippets or the environment, depending on your image. Environment exports often work for quick tests; durable machines benefit from explicit Acquire::http::Proxy and Acquire::https::Proxy directives pointing at your http://HOST:PORT URL. Remember that apt sometimes fetches over HTTP to mirrors even when your upstream goal is HTTPS-heavy browsing—both lines matter.

curl is your truth engine. Run curl -I https://example.com with and without proxies to see whether failures move from “could not resolve” (DNS) to “connection timed out” (TCP or rule path) to HTTP status codes (upstream). That single habit shortens triage more than editing fifty YAML lines blindly.

git can use http.proxy / https.proxy or the environment. SSH remotes ignore those unless you switch to HTTPS or use an SSH ProxyCommand. Teams frequently mix SSH GitHub URLs with a newly exported HTTP proxy and then wonder why nothing changed—match transport to the mechanism you configured.

8. DNS, Fake-IP, and systemd-resolved

Even with perfect TCP to the proxy, Linux may still resolve names incorrectly relative to your Clash policy. If the core uses Fake-IP, the resolver inside WSL might cache synthetic addresses that only make sense when queries flow through Clash’s DNS pipeline. When they do not, you see bizarre partial failures: one tool works, another resolves to an unexpected range, or short-lived caches desync after you toggle modes.

Modern Ubuntu images often run systemd-resolved. It can stub listeners on 127.0.0.53 while /etc/resolv.conf points there, which is fine until you manually replace resolv.conf or mix static corporate DNS with WSL-generated files. Understand who owns the file: if Windows or WSL regenerates it on boot, your hand-edited nameservers vanish silently.

Alignment strategies

  1. Single resolver path: Ensure application DNS queries ultimately reach the same logical resolver your Clash profile assumes—either by routing DNS through the tunnel or by using a consistent upstream list that matches your rule mode.
  2. Red-flag pattern: You can curl an IP through the proxy but hostname-based curl fails. That split screams DNS mismatch, not dead nodes.
  3. Diagnostics: Compare dig @SERVER results against what Clash logs show for the same query when DNS hijack or fake-ip is enabled.

If you expose a dedicated DNS inbound on Windows (some advanced setups do), you can point WSL2 at that host IP and port—again, only after firewall rules permit it. Otherwise, prefer simplifying: reduce the number of resolvers in play until behavior stabilizes, then reintroduce complexity one knob at a time.

9. TUN on Windows vs WSL2

Enabling TUN mode on Windows steers many host applications through the virtual adapter, but it does not magically retrofit every WSL2 packet unless your overall architecture routes that traffic. People sometimes enable TUN, see the browser on Windows improve, and assume WSL2 inherited the same path—it often has not. You still need an explicit story: host IP proxying, mirrored networking, or a separate Linux-side client if you require full guest transparency.

Choose deliberately. Running two full tunnels (Windows + Linux) doubles maintenance and can create asymmetric DNS unless you document both. Many developers keep one Clash instance on Windows as the choke point and drive WSL2 through it with the HTTP/SOCKS hop described above—simple, loggable, and easy to explain to new hires.

10. Symptom Checklist

Symptom Likely layer First action
Immediate connection refused to proxy port Wrong IP (127.0.0.1) or service down Recompute host IP; confirm Windows listener
Timeout to host IP:port Bind scope or firewall Allow LAN; add inbound TCP rule
IP curl works; name curl fails DNS vs Fake-IP / resolved Trace resolver; simplify DNS path
Works until reboot Changing gateway or regenerated resolv.conf Script host IP; avoid static resolv hacks

11. Summary

Routing WSL2 through Clash on Windows is a two-host problem dressed as one. The guest must target the Windows TCP stack with a real routable address, the Windows core must listen broadly enough and pass firewall policy, and DNS on the Linux side must stay consistent with how your profile resolves names—especially under Fake-IP and systemd-resolved. When you verify in that order, most “mysterious” breakages collapse into one missing toggle or one stale resolver file.

Compared with opaque all-in-one VPN clients, a rule-based proxy stack rewards operators who can read a routing table and a listener list. That transparency is exactly what makes cross-environment setups like WSL2 + Windows manageable: you can test each hop with ordinary tools instead of guessing from a single tray icon.

When you install or refresh the Windows client, prefer the official site’s download page so binaries stay traceable—then apply the host and DNS alignment above on top of a build you trust.

Download Clash for free and experience the difference