动机

Windows 下其实已经存在很多代理工具了,曾经用过的就有V2rayN, Clash, Netch, V2rayA等。对我来说,好的代理应该完全让人感觉不到代理的存在。 但是现实情况是:经常动不动就需要开关代理,对于不同的需求要反复切换节点,甚至有些地方直接用不了代理,比如对UWP应用和WSL环境的代理一直是很麻烦的事情。

那么,有没有好用点的呢,V2rayA说自己是一款透明代理工具,但是实际上也解决不了WSL的问题,而且有分流需求的话需要手动去写RoutingA规则,说实话体验也非常糟糕。 在 Linux 阵营里面情况就不一样了,我在 NixOS 用了很长一段时间的 大鹅,开启之后基本感受不到代理和墙的存在,体验非常丝滑。 于是我就开始想办法把这个好东西挪到 Windows 上来用,但是 WSL 并不支持 tproxy,所以只能考虑用虚拟机来做旁路由了。

旁路由

说到路由就不得不提到OpenWrt,现在用OpenWrt吃鹅的方式有两种:

由于ImmortalWrt提供了Hyper-V可以直接使用的.vhdx硬盘映像文件,选它没毛病。

创建虚拟机前需要先新建一个新的外部虚拟网络交换机,外部网络根据自身情况选择联网使用的网卡设备即可。创建虚拟机的时候使用该虚拟网络交换机作为网络适配器即可,可以考虑在网络适配器的高级功能选项中启用MAC地址欺骗。

旁路由不需要像主路由那样真正去做物理网口数据转发,消耗的硬件资源很少,内存和处理器的分配都尽量往小了去整就行,我设置了1GB内存绰绰有余。 检查点也可以考虑关掉,并没有什么东西需要保存。 最后,将虚拟机的自动启动操作设置为始终自动启动此虚拟机即可,这样旁路由就会随着主机启动。

接下来就可以进入旁路由系统内部了。首先需要修改的是/etc/config/network,找到虚拟网络适配器对应的网关,一般是option ipaddr 'xx.xx.xx.xx',这里需要把IP地址改成真实网关可分配的一个IP,比如网关是10.218.1.1,这里的IP就可以设置为10.218.1.100,诸如此类。改完之后重启即可。重启后就可以通过之前修改好的IP在浏览器中直接访问ImmortalWrt的管理页面了。

进入管理页面后首先需要改一下默认的root密码,这点不用多说。习惯通过密钥ssh登录也可以设置一个密钥登录。重点在于找到 网络-接口 下的 LAN 口,将网关和自定义DNS均设置为真实网关地址,并且让DHCP服务器忽略此接口。此外,确保 网络->DHCP/DNS 中的 DNS重定向 为关闭状态,方便后续让dae接管DNS请求。

到此,旁路由的设置就结束了。

吃鹅

ImmortalWrt上可以直接使用opkg安装dae或者daed,后者是带WebUI的版本,更加易用。我原本在 NixOS 下使用的是dae,但是这次为了方便就直接用daed进行配置了。安装过程非常简单,只需要安装luci-i18n-daed-zh-cn这一个包就行,其他的依赖会自动安装。

安装完成后刷新页面会发现导航栏多了一个服务选项卡,点进去就能看到daed服务了。点击启用就能让旁路由每次开机都自动启动该服务(具体配置可以去/etc/config/daed里面看)。

之后在该界面打开daed的配置页面(也可以直接通过端口2023访问)就可以进行配置。需要修改的大概只有DNS、路由、群组、节点这么几项,当然有订阅链接的话也可以直接订阅节点。节点可以拖拽到群组进行分组。下面的DNS和路由配置仅供参考:

  • DNS配置
ipversion_prefer: 4
upstream {
  alidns: 'tcp+udp://223.5.5.5:53'
  googledns: 'tcp+udp://8.8.8.8:53'
}
routing {
  request {
    qname(geosite:category-ads-all) -> reject
    fallback: alidns
  }
  response {
    upstream(googledns) -> accept
    ip(geoip:private) && !qname(geosite:cn) -> googledns
    fallback: accept
  }
}
  • 路由配置:
# client -> router.53(dnsmasq) # 禁止在这一步劫持DNS请求
# router.53(dnsmasq) - > remote_dns.53
dport(53) && !pname(dnsmasq) -> must_direct

pname(NetworkManager, systemd-resolved, frpc) -> must_direct
dip(8.8.8.8) -> proxy

# Custom
domain(suffix:hf-mirror.com) -> direct
domain(keyword:cc98) -> direct
domain(keyword:warmyou) -> direct
domain(suffix:tjupt.org) -> direct
domain(suffix:nexushd.org) -> direct
domain(suffix:moonshot.com) -> direct
domain(suffix:youpin898.com) -> direct
domain(suffix:cm.steampowered.com, suffix:steamserver.net) -> direct

# ChatGPT
domain(geosite:openai) -> proxy
domain(suffix:auth0.com) -> proxy
domain(suffix:sentry.io) -> proxy
domain(suffix:hcaptcha.com) -> proxy
domain(suffix:recaptcha.net) -> proxy
domain(suffix:gvt1.com) -> proxy
domain(suffix:gvt2.com) -> proxy
domain(suffix:gvt3.com) -> proxy
domain(suffix:msftconnecttest.com) -> proxy
domain(suffix:live.com) -> proxy
domain(suffix:sfx.ms) -> proxy
domain(suffix:microsoft.com) -> proxy

ipversion(6) -> direct
dip(224.0.0.0/3, 'ff00::/8') -> direct
dip(geoip:private) -> direct
dip(geoip:cn) -> direct
domain(geosite:cn) -> direct
domain(geosite:category-ads-all) -> block
# 目标非常用端口都走直连,避免BT流量走代理
!dport(21,22,23,53,80,123,143,194,443,465,587,853,993,995,998) -> direct

fallback: proxy

最后通过右上角的按钮启动代理即可放心吃鹅。

主机端

到此为止,旁路由的代理已经配置完毕。接下来就是让主机能够共享这个代理。

注:在daed的全局配置里面默认启用了lan_interface,因此不需要额外配置就可以让局域网设备共享代理,如果是dae的话则需要手动开启。

主机端的配置其实非常简单,就是让之前设置的虚拟网卡的网关和DNS指向旁路由即可。 Win11 中,桌面右键网络图标打开网络和Internet设置,进入高级网络设置,可以看到之前设置的虚拟网卡 vEthernet。编辑其 IPv4 配置,将默认网关和DNS填上旁路由的IP地址。网卡本身的IP地址可以写任意其他在同一网段下主机可被分配到的IP地址。保存配置代理即可生效。

这样设置的代理无论是对UWP应用也好还是对WSL内部也好都是通用的,可以说真正做到了透明代理。美滋滋!