WSL2 代理连不通排查实录:从 WFP 规则条件到防火墙默认策略的深坑
明明防火墙规则显示"允许",WSL2 里 curl 走代理却一直超时?改完规则后外部公网又能连进你的代理端口?这篇文章记录一次完整的 Windows 防火墙排查过程,从 WFP 规则条件不匹配,到规则优先级打架,最后揪出真正的元凶——一个被改动过的默认入站策略。踩过的坑和最终解法都在这里。
背景
环境是 WSL2 + v2rayN,代理监听在 10808 端口。WSL2 里通过局域网地址 192.168.10.100:10808 访问代理,一直超时连不上。用 netsh 查看防火墙规则,负责放行的规则显示是 Allow,看起来一切正常,但流量还是被拦。
第一步:排查 WSL2 curl 超时——规则条件不匹配的坑
一开始怀疑过好几个方向,包括标准防火墙规则的优先级、WFP 底层 callout driver(hrwfpdrv)、vEthernet (WSL) 接口没有 NLA 网络位置分类、以及系统里一条叫 Query User 的无条件 Block filter 的权重问题。这些线索确实都是环境里客观存在的现象——vEthernet (WSL) 确实没有 NLA 记录,Query User 那条 filter 确实存在且描述吻合——但排查下来都不是这次连不通的直接原因。
真正的根因:之前建的 WSL2-v2rayN-10808-TCP/UDP 规则里,FWPM_CONDITION_IP_REMOTE_ADDRESS 条件被写死限定在 172.31.160.0 ~ 172.31.175.255(WSL 虚拟网段),但实际代理连接的目标地址是 192.168.10.100(物理局域网地址),完全不在这个范围内。规则权重再高、层级再对,只要匹配条件本身不命中这次连接的五元组,这条 Allow 规则根本不会被评估,流量直接落到了那条无条件 Block(Query User filter)上。
教训:权重和层级排查方向是对的,但顺序上应该先核对规则条件是否匹配实际流量的五元组,再去纠结权重和层级——条件不匹配的规则等于不存在,根本轮不到跟别的规则比权重。
去掉 RemoteAddress 限制,只按端口/协议放行后,WSL2 能正常连上代理了。
第二步:意外发现——公网可能也能连进来
解决 WSL 连接问题后新建的两条规则是这样的:
Direction: Inbound, LocalPort 10808, Profile Any, RemoteAddress 不限制
这意味着不只是 WSL 和局域网能连,理论上公网任何机器只要能路由到这台机器的 10808 端口,都能连上。这一点必须认真对待,原因有两个:
① 如果这台机器有公网可达的 IPv6 地址,那么这条不限 RemoteAddress 的规则,加上 v2rayN 监听的是 [::]:10808(netstat 输出里能看到),外部通过 IPv6 直接访问代理端口在网络层面是可行的,不会经过传统 IPv4 NAT 的天然屏障。
② 10808 通常是 SOCKS5 代理端口,如果没有账号密码认证,等于把一个开放代理暴露在公网上——任何扫到这个端口的人都能借用你的网络出口,风险包括流量被滥用、带宽被占,甚至你的 IP 被关联进对方做的坏事里。
怎么测试外部网络到底能不能连进来
测试思路:先拿到这台机器的公网 IPv6 地址,再从**真正的外部网络**(不能是同一个局域网/同一个路由器下)尝试连接 10808 端口。
第一步,查这台机器当前的公网 IPv6 地址:
ipconfig | findstr /C:"IPv6"
找到那个不是 fe80:: 开头(link-local,本地链路地址,不可路由)、也不是 ::1(回环)的地址,通常公网 IPv6 是以 2xxx: 或 2400:/2600: 之类开头的。
第二步,确认域名解析是否指向这台机器:
# 先确认域名解析结果对不对
nslookup sz.zsanjin.top
# 用 Test-NetConnection 测端口连通性
Test-NetConnection -ComputerName sz.zsanjin.top -Port 10808
重要前提:测试机必须是真正的"外部"。具体做法是用手机流量(4G/5G,关掉 WiFi)开热点,让另一台设备连手机热点上网,保证走的是完全不同的运营商网络路径。不要用同一个宽带下的另一台设备测,哪怕接的是同一个路由器的不同网口,这样测出来的路径可能还是走内网直连,测不出真实的公网可达性。
测试结果是 TcpTestSucceeded: True——外部确实能连进来,端口暴露在公网上,需要立刻处理。
第三步:改成精确网段规则,问题依然没解决
按照收紧思路,删掉不限地址的规则,重新建了两条只放行 WSL 网段和局域网网段的精确规则:
Remove-NetFirewallRule -DisplayName "Allow v2rayN 10808 TCP All"
Remove-NetFirewallRule -DisplayName "Allow v2rayN 10808 UDP All"
New-NetFirewallRule -DisplayName "Allow v2rayN 10808 TCP Local" `
-Direction Inbound -Action Allow -Protocol TCP -LocalPort 10808 `
-RemoteAddress 172.31.160.0/20,192.168.10.0/24,127.0.0.1 `
-Profile Any
New-NetFirewallRule -DisplayName "Allow v2rayN 10808 UDP Local" `
-Direction Inbound -Action Allow -Protocol UDP -LocalPort 10808 `
-RemoteAddress 172.31.160.0/20,192.168.10.0/24,127.0.0.1 `
-Profile Any
规则创建成功,返回 Status: 已从存储区成功分析规则。按理说这样外部就应该连不进来了。
结果用手机热点再测一次,外部依然能访问这个端口。规则明明改精确了,为什么还是挡不住?
第四步:发现另一组"捣乱"的规则——xray 自带的阻止规则
在防火墙管理界面里翻查入站规则列表,发现有几条名字叫 xray 的规则(应该是安装 xray/v2rayN 时软件自己生成的),配置是这样的:
名称: xray
配置文件: 公用 / 专用
已启用: 否
操作: 阻止
协议: TCP / UDP
本地地址: 任何 远程地址: 任何
程序: I:\se...(xray.exe 的路径)
测试发现一个很诡异的现象:
① 启用这几条 xray 阻止规则后,外部无法访问了,但本地 WSL 也连不上了。
② 关闭这几条规则后,外部又能连进来,等于没有任何限制。
原因分析:Windows 防火墙里,同一层级下"阻止"规则的优先级高于"允许"规则,不管谁先建的。这四条 xray 规则不区分来源地址,只要是这个程序(按程序路径 I:\se... 匹配)产生的流量,不管是 WSL 内网地址还是外部公网地址,只要启用就会被这条阻止规则拦下来,优先级压过按端口网段放行的 Allow 规则。所以打开时连 WSL 也被误伤,关闭时又变成完全没有防护。
问题不是精确网段规则写错了,而是这一组按程序路径全网段阻止的规则,和按端口网段放行的规则在打架,而且阻止规则赢了。
第五步:真正的元凶——被改动过的默认入站策略
既然规则互相打架,先查一下 Windows 防火墙的默认入站策略是什么:
Get-NetFirewallProfile | Select-Object Name, DefaultInboundAction
返回结果:
Name DefaultInboundAction
---- --------------------
Domain NotConfigured
Private NotConfigured
Public Allow
这才是这次所有诡异现象的总开关。Public 配置文件的 DefaultInboundAction 是 Allow,不是 Windows 出厂正常的默认值 Block。这意味着在公用网络配置文件下,没有匹配任何规则的入站连接会被默认放行,而不是默认拒绝。
这一条设置解释了前面所有现象:
① xray 阻止规则关闭时:没有规则拦截,公网默认策略又是 Allow,所以公网、WSL、局域网全部能连——之前看到的"没有限制",其实是默认策略本身就是开放的,跟精确网段的 Allow 规则完全没关系,那两条规则从头到尾都是摆设。
② xray 阻止规则打开时:这四条按程序全网段阻止的规则生效,挡住了所有来源,包括 WSL。
也就是说,删掉不限地址的规则、换成精确网段规则这个操作,在 Public 配置文件默认 Allow 的前提下,从一开始就没起到收紧的作用。新建的 Allow 规则只是锦上添花,从来不是真正的防线。
第六步:最终修复
把三个配置文件的默认入站策略都改回 Block:
Set-NetFirewallProfile -Profile Public -DefaultInboundAction Block
Set-NetFirewallProfile -Profile Private -DefaultInboundAction Block
Set-NetFirewallProfile -Profile Domain -DefaultInboundAction Block
改完再确认一遍,三个 Profile 都应该显示 Block:
Get-NetFirewallProfile | Select-Object Name, DefaultInboundAction
禁用掉那几条粗暴的 xray 全网段阻止规则(默认策略已经是 Block,不再需要它们,留着还会误伤 WSL):
Get-NetFirewallRule -DisplayName "xray" | Disable-NetFirewallRule
保留之前建的两条精确网段 Allow 规则(TCP Local / UDP Local,限定 WSL 网段 + 局域网网段),这时候它们才真正开始起作用——默认策略挡住一切未匹配的连接,只有匹配这两条规则的 WSL/局域网来源能通过。
验证结果:本地 WSL 正常访问 10808,用手机热点从外部测试:
Test-NetConnection -ComputerName sz.zsanjin.top -Port 10808
这次返回 TcpTestSucceeded: False,外部彻底连不进来了,问题解决。
⚠️ 注意:修改默认入站策略是全局改动,不只影响 10808 端口,会让 Public 配置文件下所有没有明确 Allow 规则的入站连接都被拒绝。如果这台机器上还有远程桌面、文件共享等依赖了"默认放行"这个漏洞在公用网络下工作的服务,改完可能会连不上,需要单独为它们建 Allow 规则。
完整问题链路总结
根本原因:这台机器的 Windows 防火墙 Public 配置文件被改成了 DefaultInboundAction = Allow,而不是系统正常的默认值 Block。这一条设置错误是所有诡异现象的总开关:
① WSL curl 超时:独立问题,规则里的 RemoteAddress 条件写死限定在 WSL 网段,实际连接目标是局域网地址,条件不匹配导致规则形同虚设,流量落到了系统级 Block 规则上。
② 新规则不限地址,怀疑公网暴露:排查方向正确,但还没摸到真正病根。
③ 改成精确网段规则,外部依然能连:因为 Public 默认策略本来就是 Allow,Allow/Block 规则从头到尾都没有决定权,只要没有别的规则明确拦截,任何流量默认直接放行。
④ xray 自带的阻止规则:不区分来源,是唯一真正在起作用的拦截逻辑,导致开关这组规则时行为要么全通、要么全断,跟精确配置的网段规则完全脱节。
一句话总结:之前所有的规则调整都是在正确方向上做无用功,因为防火墙的默认门本身就是开着的,直到发现并关上这扇默认的门,之前建的所有精确规则才第一次真正生效。
故障排查速查表
规则显示 Allow 但还是连不通:先核对规则的 RemoteAddress/端口条件是否匹配实际流量的五元组,条件不匹配的规则等于不存在。
改完规则外部依然能连:检查 Get-NetFirewallProfile 的 DefaultInboundAction,确认默认策略不是被改成了 Allow。
开关某条规则后行为要么全通要么全断:可能存在按程序路径、不区分来源的粗暴阻止规则,跟按地址网段放行的规则在打架,阻止规则优先级更高。
怀疑代理端口暴露公网:用手机流量(关闭 WiFi)在真正的外部网络环境下用 Test-NetConnection 测试,不要用同一路由器下的设备测,会有假阴性。
如果你也在用 v2rayN/xray 给 WSL2 或 NAS 之类的设备做代理转发,建议现在就去检查一下自己机器的 DefaultInboundAction,这个坑很隐蔽,规则本身看起来完全正常,很容易被忽略。
Comments NOTHING