引言

WSL 与宿主机之间有其内建的网络,对应的网关和虚拟网卡等。因此在 WSL 里面并不能直接通过 localhost 来访问宿主机的网络代理等网络服务。查阅官网文档也未能找到自动优雅的解决方案,只能通过一个简单脚本来手动实现(同时也可以将该脚本设定为自动任务以达到自动化效果)。

原理

网络服务

查阅官网文档我们可以看到,官方提供的方案为

如果要从 Linux 分发版(即 Ubuntu)访问 Windows 上运行的网络应用(例如,在 NodeJS 或 SQL 服务器上运行的应用),则需要使用主机的 IP 地址。 虽然这不是一种常见方案,但你可以执行以下步骤来使其可行。

  1. 通过在 Linux 分发版中运行以下命令来获取主机的 IP 地址:cat /etc/resolv.conf
  2. 复制以下词语后面的 IP 地址:nameserver
  3. 使用复制的 IP 地址连接到任何 Windows 服务器。

代理服务

在宿主机可以选择常见的Clash等软件为内部网络提供代理服务,需要记得勾选Allow LAN。在 WSL 内可以选择 proxychainsproxychains4 这两个软件来为 WSL 实现访问宿主机代理服务的功能。

实现

~ 路径下创建 set_proxy_conf.py,在文件中写入如下内容。如果选择 proxychains4 而不是 proxychains ,则需要将代码中 /etc/proxychains.conf 改为 /etc/proxychains4.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import os

cmd = 'cat /etc/resolv.conf'

statu = os.popen(cmd, 'r').read().strip()
lines = statu.split('\n')

key_line = ''
for line in lines:
if 'nameserver' in line:
key_line = line

host_ip = key_line.split(' ')[1]

set_proxy_cnf_cmd = '''
printf "
[ProxyList]
# example
socks5 {} 7890
" > /etc/proxychains.conf
'''.format(host_ip)

os.popen(set_proxy_cnf_cmd, 'r')

res = os.popen('cat /etc/proxychains.conf').read().strip()
print(res)

使用

当第一次使用或 WSL 内部网络发生变化时运行如下命令为 proxychains 配置即可。

1
sudo python3 ~/set_proxy_conf.py

在使用时只需要在需要代理的命令前加上 proxychains 就可以实现代理了。

1
proxychains curl www.google.com

参考文献

[1] 使用 WSL 访问网络应用程序 | Microsoft Learn