为 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 地址的情况,确保网络通信的正常进行。
启用镜像模式
- 在宿主机的用户目录下创建或编辑
.wslconfig文件:
[wsl2]
networkingMode=mirrored
autoProxy=true

-
重新启动 WSL2 实例以使配置生效:
wsl --shutdown然后重新启动 WSL2 实例。
🧪 验证网络配置
再次进入时,不再提示就是配置.wslconfig生效

-
查看 IP 地址:
ip addr show eth0 -
查看路由表:
ip route -
查看 DNS 配置:
cat /etc/resolv.conf
这些命令应显示与宿主机相同的网络配置,验证镜像模式已成功启用。

浙公网安备 33010602011771号