为 WSL2 设置代理

WSL1

在 WSL1 时代,由于 Linux 子系统和 Windows 共享了网络端口,所以访问 Windows 的代理非常简单。例如 Windows 的代理客户端监听了 8000 端口,那么只需要在 Linux 子系统中执行如下命令,就可以让当前 session 中的请求通过代理访问互联网。

export ALL_PROXY="http://127.0.0.1:8000"
但是 WSL2 基于 Hyper-V 运行,导致 Linux 子系统和 Windows 在网络上是两台各自独立的机器,从 Linux 子系统访问 Windows 首先需要找到 Windows 的 IP。

WSL2(NAT)

+------------------------+
|     Windows Host       |
|  (Physical + VPN Net)  |
|                        |
|  +------------------+  |
|  | vEthernet (WSL)  |<--------------------------+
|  |  172.20.208.1     |                          |
|  +------------------+                          |
|                        |                       |
+------------------------+                       |
           ▲                                      |
           |                                      |
        NAT / vSwitch                            |
           |                                      | 网关
+------------------------+                       |
|         WSL2           |                       |
| (Lightweight VM with   |                       |
|  full Linux Kernel)    |                       |
|                        |                       |
|  +------------------+  |                       |
|  | eth0             |--------------------------+
|  | 172.20.213.240   |  |
|  +------------------+  |
|                        |
+------------------------+

1、找到wsl中宿主机的IP(wsl 的默认网关)

在 WSL2 中运行:

ip route

你会看到一行类似:

qiuliw@X:/mnt/c/Users/18071$ ip route
default via 172.20.208.1 dev eth0 proto kernel
172.20.208.0/20 dev eth0 proto kernel scope link src 172.20.213.240
WSL2 的 IP(子系统 IP) 172.20.213.240
默认网关(宿主机的 IP 172.20.208.1

其中 172.20.208.1 是 宿主机在 WSL 中的 IP(也就是WSL的网关)将数据代理到这个IP。

export HTTP_PROXY=http://172.20.208.1:7897
export HTTPS_PROXY=http://172.20.208.1:7897
export ALL_PROXY=http://172.20.208.1:7897

为什么三者分开设置?
许多老的或某些程序只识别 HTTP_PROXY 和 HTTPS_PROXY,不会理会 ALL_PROXY。
有些工具或库(比如 curl、wget、git 等)会优先读取 HTTP_PROXY 和 HTTPS_PROXY,而忽略 ALL_PROXY。
反过来,有些软件只用 ALL_PROXY

上述过程变成脚本 set_proxy.sh 就是

#!/bin/bash
GW_IP=$(ip route | grep '^default via' | awk '{print $3}')
export HTTP_PROXY="http://$GW_IP:7897"
export HTTPS_PROXY="http://$GW_IP:7897"
export ALL_PROXY="http://$GW_IP:7897"
echo "Proxy environment variables set to $GW_IP:7897"

或者在clash中查看

2、代理软件允许局域网连接

3、关闭Hyper-V虚拟网卡的防火墙

Get-NetFirewallHyperVVMCreator #获取wsl GUID

通常都为{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}, 如果不一样后面的命令都需要替换

Get-NetFirewallHyperVVMSetting -PolicyStore ActiveStore -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' # 查看Hyper-V防火墙状态
Name                  : {40E0AC32-46A5-438A-A0B2-2B479E8F2E90}
Enabled               : True
DefaultInboundAction  : Block # 默认拦截 宿主机 发往 Hyper-V 虚拟机(包括 WSL2)的入站连接,拦住了包的返回过程
DefaultOutboundAction : Allow #  WSL2 向外包发送到宿主机默认是允许的
LoopbackEnabled       : True
AllowHostPolicyMerge  : True

关闭Hyper-V防火墙(要使用管理员权限下的Powershell)

Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -Enabled False

4、关闭win11对wsl的防火墙

要使用管理员权限下的Powershell

New-NetFirewallRule -DisplayName "WSL vEthernet inbound" `
  -Direction Inbound `
  -InterfaceAlias "vEthernet (WSL*)" `
  -Action Allow `
  -Profile Any

New-NetFirewallRule -DisplayName "WSL vEthernet outbound" `
  -Direction Outbound `
  -InterfaceAlias "vEthernet (WSL*)" `
  -Action Allow `
  -Profile Any

如果关掉Hyper-V防火墙还是无法访问,检查一下ubuntu的防火墙并进行关闭。

测试

 curl -I https://www.google.com

返回http报文内容就是成功了

WSL2(镜像)推荐

开着代理进入wsl时,总会提示

wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。

显然,官方在提示一种更简便的网络代理方法——镜像

WSL2 默认使用 NAT 网络,通过 Hyper-V 虚拟交换机连接宿主机,网络是隔离的,IP 不同。

在启用 WSL2 的镜像模式(Mirrored Mode)后,宿主机和 WSL2 子系统将共享相同的 IP 地址,这不会导致冲突。镜像模式的设计目的是让 WSL2 子系统直接继承宿主机的网络环境,包括 IP 地址、路由、DNS 和代理设置,从而实现更高的网络兼容性和透明度。

+-------------------+       +---------------------+       +-------------------+
|     WSL2 子系统    | <---> |   Hyper-V 虚拟交换机   | <---> |    Windows 宿主机   |
| (eth0: 192.168.x.x) |       | (vEthernet (WSL))     |       | (eth0: 192.168.x.x) |
+-------------------+       +---------------------+       +-------------------+
  • 共享 IP 地址:WSL2 子系统和宿主机将共享相同的 IP 地址(如 192.168.x.x),实现网络直通。
  • 共享网络配置:包括 DNS、路由和代理设置,WSL2 将直接继承宿主机的网络配置。
  • 代理继承:通过设置 autoProxy=true,WSL2 可以自动继承宿主机的代理设置,无需手动配置。([cnblogs.com][1])

为什么不会发生 IP 地址冲突?

启用镜像模式后,宿主机和 WSL2 子系统共享相同的 IP 地址,但这并不会导致冲突,原因如下:

  • 网络栈隔离:虽然共享相同的 IP 地址,但宿主机和 WSL2 子系统的网络栈是隔离的。
  • 端口复用:在同一台机器上,多个进程可以绑定到相同的 IP 地址和不同的端口,因此不会发生冲突。
  • 系统设计:操作系统设计了机制来处理共享 IP 地址的情况,确保网络通信的正常进行。

启用镜像模式

  1. 在宿主机的用户目录下创建或编辑 .wslconfig 文件:
[wsl2]
networkingMode=mirrored
autoProxy=true

  1. 重新启动 WSL2 实例以使配置生效:

    wsl --shutdown
    

    然后重新启动 WSL2 实例。

🧪 验证网络配置

再次进入时,不再提示就是配置.wslconfig生效

  • 查看 IP 地址

    ip addr show eth0
    
  • 查看路由表

    ip route
    
  • 查看 DNS 配置

    cat /etc/resolv.conf
    

这些命令应显示与宿主机相同的网络配置,验证镜像模式已成功启用。

posted @ 2025-06-13 16:47  丘狸尾  阅读(3619)  评论(1)    收藏  举报