Skip to main content

WSL Networking and Proxy

WSL2 networking issues are easy to confuse because it is neither "completely isolated from Windows" nor "the same machine as Windows." If you don't first clarify the network relationship, you will end up repeatedly trial-and-erroring between localhost, the Windows host IP, and the WSL IP.

First, Distinguish the Three Addresses

Under the default WSL2 NAT network, three types of addresses typically coexist:

  • 127.0.0.1: The loopback address of the current environment itself
  • Windows host IP: For WSL, this is usually the default gateway address
  • WSL IP: The virtual network interface address of the Linux distribution itself

The most common conclusions are:

  • When Windows accesses WSL services, many services can use localhost directly
  • When WSL accesses Windows proxies or services, you should typically use the Windows host IP
  • When other LAN machines access WSL, they usually cannot use the WSL IP directly, but must go through Windows forwarding

How to Get the Windows Host IP in WSL

The most reliable method is to get the next hop of the default route:

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

On many machines you will also see the same address in /etc/resolv.conf:

grep nameserver /etc/resolv.conf

If both match, it usually means you have the Windows host's address within the WSL virtual network.

Temporarily Setting the Proxy

The following example assumes a local proxy program is already running on Windows with HTTP port 7890.

First get the Windows host IP:

export HOST_IP=$(ip route show default | awk '{print $3}')

Then set the environment variables:

export http_proxy=http://$HOST_IP:7890
export https_proxy=http://$HOST_IP:7890
export all_proxy=socks5://$HOST_IP:7890

Verify it works:

curl -I https://www.google.com
git ls-remote https://github.com/git/git.git HEAD

If you mainly need the proxy for commands like apt, pip, and git, this temporary approach is sufficient.

Persisting as Toggleable Functions

Rather than hardcoding proxy variables directly into ~/.bashrc, I recommend writing them as explicit toggle functions. This way you won't need to manually edit files when switching network environments.

Add the following to ~/.bashrc:

set_wsl_proxy() {
local host_ip
host_ip=$(ip route show default | awk '{print $3}')

export http_proxy="http://$host_ip:7890"
export https_proxy="http://$host_ip:7890"
export all_proxy="socks5://$host_ip:7890"
}

unset_wsl_proxy() {
unset http_proxy
unset https_proxy
unset all_proxy
}

alias proxy-on='set_wsl_proxy'
alias proxy-off='unset_wsl_proxy'

Reload the shell:

source ~/.bashrc

When you need the proxy, run:

proxy-on

When you don't need it, run:

proxy-off

What to Do When sudo Commands Don't Use the Proxy

Sometimes curl works under a normal user, but sudo apt update still fails. The common reason is that sudo does not inherit the current environment variables.

You can try temporarily:

sudo -E apt update

If you want apt to always use the proxy, you can also write a dedicated configuration file:

sudo nano /etc/apt/apt.conf.d/95proxies

Write:

Acquire::http::Proxy "http://<WINDOWS_HOST_IP>:7890";
Acquire::https::Proxy "http://<WINDOWS_HOST_IP>:7890";

Replace <WINDOWS_HOST_IP> with your currently discovered host address. Since the WSL IP may change, this file is more suitable when your network environment is relatively stable.

When to Stop Tweaking Proxy Variables in WSL

If you have already set the variables but things still don't work at all, prioritize checking the Windows side rather than continuing to blindly modify things in WSL:

  1. Whether the proxy program is actually running on Windows
  2. Whether the proxy program allows LAN or other network interface connections
  3. Whether the port number is really the one you configured
  4. Whether the Windows firewall is blocking the corresponding port

Many times the problem is not in WSL, but rather the Windows proxy software is only listening on 127.0.0.1 and has not opened up to the virtual network interface used by WSL.

Minimal Troubleshooting Order

I typically troubleshoot in this order:

  1. ip route show default
  2. echo $http_proxy
  3. curl -I https://www.google.com
  4. sudo -E apt update
  5. Confirm proxy program listening address and port on Windows

If step 3 doesn't work, don't rush to modify individual configurations for git, pip, or conda, because the underlying link is probably not working yet.

Frequently Asked Questions

1. Why Did It Work Yesterday But Not Today

After a WSL2 restart, the virtual network may change, and the Windows host IP may change accordingly. As long as you don't hardcode the IP into files but dynamically obtain it via ip route each time, these issues will be much less frequent.

2. Why Can the Browser Access the Internet But the Command Line Cannot

The browser may be using Windows' own proxy configuration; the WSL command line does not automatically inherit this layer, so you still need to explicitly set environment variables in WSL.

3. Why Does localhost:7890 Not Work in WSL

This is because localhost refers to WSL itself, not the Windows host. Under the default NAT network, to access the proxy on Windows, you should use the host IP instead.

Further Reading