WSL2想要连上宿主机Windows里设置的网络代理端口很是蛋疼。

前置条件

PS C:\Users\overlord> wsl -l -v  NAME            STATE           VERSION* Ubuntu-20.04    Running         2

获取Host和WSL的ip

首先咱们须要获取WSL2的动静IP,再每次Windows零碎重启之后,它会动静给WSL2调配一个新IP。

所以能够写个脚本displayip.sh,来动静获取。

#!/bin/bashecho "Host ip: $(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')"echo "WSL client ip: $(hostname -I | awk '{print $1}')"

运行可查看以后Windows host主机ip、WSL的ip。

  chmod +x displayip.sh  ./displayip.shHost ip: 172.20.96.1WSL client ip: 172.20.99.149

Windows应用的代理程序

我用的Clash for Windows反对http和socks5代理。

代理端口为1081。

谬误尝试

Windows Defender 里新增入站规定

管理员权限ps运行:

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound  -InterfaceAlias "vEthernet (WSL)"  -Action Allow

会在Windows Defender 防火墙里减少开启一条入站规定“WSL”。这条规定容许全副接口名为 vEthernet (WSL) ——也就是WSL2的入站连贯。

在WSL的bash里ping宿主主机,测试连通:

  ping 172.20.96.1 -c 4PING 172.20.96.1 (172.20.96.1) 56(84) bytes of data.64 bytes from 172.20.96.1: icmp_seq=1 ttl=128 time=0.373 ms64 bytes from 172.20.96.1: icmp_seq=2 ttl=128 time=0.350 ms64 bytes from 172.20.96.1: icmp_seq=3 ttl=128 time=0.398 ms64 bytes from 172.20.96.1: icmp_seq=4 ttl=128 time=0.380 ms--- 172.20.96.1 ping statistics ---4 packets transmitted, 4 received, 0% packet loss, time 3114msrtt min/avg/max/mdev = 0.350/0.375/0.398/0.017 ms

然而此时通过宿主机的ip并不能拜访到代理软件应用的1081接口。用telnet测试接口可得如下后果。

  telnet 172.20.96.1 1081Trying 172.20.96.1...

对1081的连贯申请会始终停留在尝试连贯的步骤上。

入站规定的用途

减少入站规定其实能够用来让WSL2子系统拜访Windows宿主机起的http服务。

例如我用node在Windows宿主机的5000端口起了一个node的server。

PS D:\Codes\nodejs16\tsrctutorial> pnpm preview> tsrctutorial@0.0.0 preview D:\Codes\nodejs16\tsrctutorial> vite preview  > Network:  http://172.24.0.1:5000/  > Network:  http://192.168.56.1:5000/  > Network:  http://192.168.3.130:5000/  > Local:    http://localhost:5000/  > Network:  http://172.20.96.1:5000/

WSL2内用telnet测试的后果就会变成:

  telnet 172.20.96.1 5000Trying 172.20.96.1...Connected to 172.20.96.1.Escape character is '^]'.

还能够用curl测试。

  curl http://172.20.96.1:5000<!DOCTYPE html><html lang="en">  ...</html>

从Windows宿主机拜访WSL2起的服务

新版WSL2里零碎曾经映射,间接用localhost即可拜访。

比方在WLS2里起个简略的node服务器,在Windows的浏览器中用 localhost:port 即可拜访。

猜测

可能是Windows Defender的入站规定只对它意识的连贯协定放行,而clash的混合http和socks5的协定不在它意识的范畴内。

正确计划

配置 Windows Defender

在“高级平安 Windows Defender 防火墙” -- 属性,选项卡“专用配置文件”,状态组里“受爱护的网络连接:”左边的“自定义”按钮,关上爱护的网络连接窗口勾销勾选“vEthernet (WSL)”复选框。

不过配置的毛病是每次重启必须重新配置。起因是vEthernet这个服务必须每次登录WSL2才会呈现,Windows Defender 会默认将其纳入爱护,我还没有找到Windows Defender默认不爱护它的办法。

欢送留言交换重启后也能失效的WSL和宿主拜访的配置办法。

测试连贯

telnet

  telnet 172.20.96.1 1081Trying 172.20.96.1...Connected to 172.20.96.1.Escape character is '^]'.

curl

  curl -x "socks5://172.20.96.1:1081" https://www.google.com<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8"><TITLE>302 Moved</TITLE></HEAD><BODY><H1>302 Moved</H1>The document has moved<A HREF="https://www.google.com.hk/url?sa=p&amp;hl=zh-CN&amp;pref=hkredirect&amp;pval=yes&amp;q=https://www.google.com.hk/&amp;ust=1645782940260650&amp;usg=AOvVaw0PyWu1rzhLahRjGxgRdqPH">here</A>.</BODY></HTML>

应用场景

先配置好Windows Defender的高级平安,再把宿主机的代理端口设置为WSL2零碎代理,或者git的代理。

clash或者其余的代理程序须要凋谢局域网拜访(Allow LAN)。

WSL2里设置零碎代理局部,我应用一个bash脚本来做这样的配置。

socks5协定的proxy.sh脚本

#!/bin/bashhostip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')wslip=$(hostname -I | awk '{print $1}')port=1081PROXY_SOCKS="socks5://${hostip}:${port}"function display() {    echo "Host ip: ${hostip}"    echo "WSL client ip: ${wslip}"    echo "current PROXY: ${PROXY_SOCKS}"}function set_proxy() {    export http_proxy="${PROXY_SOCKS}"    export https_proxy="${PROXY_SOCKS}"    echo "env http/https proxy set."}function unset_proxy() {    unset http_proxy    unset https_proxy    echo "env proxy unset."}function set_git_proxy() {    git config --global http.proxy "${PROXY_SOCKS}"    git config --global https.proxy "${PROXY_SOCKS}"    echo "git config proxy set."}function unset_git_proxy() {    git config --global --unset http.proxy    git config --global --unset https.proxy    echo "git conffig proxy unset."}if [ "$1" = "display" ]; then    displayelif [ "$1" = "set" ]; then    set_proxyelif [ "$1" = "unset" ]; then    unset_proxyelif [ "$1" = "setgit" ]; then    set_git_proxyelif [ "$1" = "ungit" ]; then    unset_git_proxyelse    echo "incorrect arguments."fi

第4行port=你Windows代理程序设置的代理端口。

保留后记得chmod +x proxy.sh赋予执行权限。

用法

  ./proxy.sh displayHost ip: 172.20.96.1WSL client ip: 172.20.99.149current PROXY: socks5://172.20.96.1:1081  ./proxy.sh setenv http/https proxy set.  ./proxy.sh unsetenv proxy unset.  ./proxy.sh setgitgit config proxy set.  ./proxy.sh ungitgit conffig proxy unset.

set之后能够curl或wget拜访须要代理连上的地址;setgit之后拉github上连贯不上的包。

参考资料

Windows Defender Firewall blocks access from WSL2 · Issue #4139 · microsoft/WSL

Add "allow" rule to Windows firewall for WSL2 network · Issue #4585 · microsoft/WSL

Protecting X410 Public Access for WSL2 via Windows Defender Firewall

[WSL 2] NIC Bridge mode (Has TCP Workaround) · Issue #4150 · microsoft/WSL

WSL2 中拜访宿主机 Windows 的代理 - ZingLix Blog