Skip to content

TUN inbound: Add gateway, dns, autoSystemRoutingTable, autoOutboundsInterface for Windows#5887

Merged
RPRX merged 24 commits intoXTLS:mainfrom
LjhAUMEM:tun-winroute
Apr 13, 2026
Merged

TUN inbound: Add gateway, dns, autoSystemRoutingTable, autoOutboundsInterface for Windows#5887
RPRX merged 24 commits intoXTLS:mainfrom
LjhAUMEM:tun-winroute

Conversation

@LjhAUMEM
Copy link
Copy Markdown
Collaborator

@LjhAUMEM LjhAUMEM commented Apr 3, 2026

{
  "log": { "loglevel": "debug" },
  "inbounds": [
    {
      "protocol": "tun",
      "settings": {
        "name": "xray0",
        "mtu": [
          1500,
          1280
        ],
        "gateway": [
          "10.0.0.1/16",
          "fc00::1/64"
        ],
        "dns": [
          "1.1.1.1",
          "8.8.8.8"
          // "2606:4700:4700::1111",
          // "2001:4860:4860::8888"
        ],
        "userLevel": 0,
        "autoSystemRoutingTable": [
          "0.0.0.0/0",
          "::/0"
        ]
        // ,"autoOutboundsInterface": "auto"
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom"
    }
  ]
}

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 3, 2026

另外是不是可以给 sockopt.interface 增加 interface index 的支持

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

这个 auto-route 要加的话,mac 和 linux 肯定也会适配的,不用起名 winRoute

还要实现自动给出站没填 interface 的加上 interface,不过有同时插网线、连 wifi 的情况,先判断哪个是默认的?

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

还要实现自动给出站没填 interface 的加上 interface

这种东西肯定得加的,因为内核里 DoH 等自动请求也得绑个 interface 来绕过 tun 不然回环了,其它自动请求可没有 sockopt

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 3, 2026

那就先作为 draft 吧

auto-route 是作为 bool?我认为也要有一个类似 route 的可以指定 ip cidr

interface 当初想的是不手动指定就取第一个非 tun index 的传到 ctx 里

@Fangliding
Copy link
Copy Markdown
Member

直接用 RegisterDialerController 注入一个sockopt绑定接口就是了 doh什么的全走的这个接口 很久之前就考虑过这个问题了

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 3, 2026

也可以,反正 setsocketint 各大 os 都有,不用分 os

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

v2ray 的过度设计终于到了要发挥作用的时候了吗,但是 VLESS fallbacks 没走这个,REALITY 的话世界塞了个可以用外部 dial

但是 record_detect 没用那个,得改一下

Xray 启动时探测一下默认接口吧,auto-route 可以保留现在的配置格式,这样挺好的,毕竟未来的 auto-redirect 也是这格式

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

@Fangliding echForceQuery 配置项还有必要留着吗,开个 PR 删了吧

@Fangliding
Copy link
Copy Markdown
Member

之前有一个给伊朗无服务器用的莫名其妙的half 也毙了吗

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

那再想想,不过伊朗现在也用不上这个不是嘛

话说隔壁两家的 TUN 实现的 auto-redirect 是不是拿 /0 减掉 auto-redirect 来算路由表

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

不过感觉不如叫 auto-bypass,它和 auto-route。。。不对不能二选一,这块你们想下

@Fangliding
Copy link
Copy Markdown
Member

那东西我也觉得没用 用处太边缘而且他自己好像也不更了 好像他扔出来的模板都没那功能 纯ex人

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

既然没用到那就先删了吧,主要是感觉 v2rayN&G TLS 设置那里越来越眼花缭乱了

ECH any outer sni 这个前几天在群里讨论过,是不是现在的 uTLS 实现不了来着?

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

话说有了 ECH 这么大的位置,搞 QUIC 版 REALITY 倒是方便了很多,一开始就设计成国外运营商能配合的 REALITY 变种吧

@Fangliding
Copy link
Copy Markdown
Member

ECH any outer sni 这个前几天在群里讨论过,是不是现在的 uTLS 实现不了来着?

可以 主要是CF不支持 做了也没用 自建ECH的情况下outer完全可以自己填

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

可以 主要是CF不支持 做了也没用 自建ECH的情况下outer完全可以自己填

那就先加个自定义 outer sni 的功能吧,感觉 echConfigList 塞不下了,按之前说的把 sni 改成 outer.com+inner.com 吧

主要是正好也能把旧的客户端给 break 掉,这在以后全面普及 any outer sni 后会有帮助

@Fangliding
Copy link
Copy Markdown
Member

Fangliding commented Apr 3, 2026

random outer 哪怕是IETF最后做出来也是另一套逻辑 我稍微看了一下那个ppt 和现在做一个土制的的盖过去肯定是不一样的 还是那句话这东西八字没一撇

@Fangliding
Copy link
Copy Markdown
Member

Fangliding commented Apr 3, 2026

还有我说的自建ECH可以自己填意思是生成 ECH Config 的时候 outer 可以自己写 然后就原生apply进去了 不需要任何新功能

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

有点难以想象“另一套逻辑”是啥逻辑,服务端定义可选 SNI 范围?都 2026 年了都 IPv6 了还在搞虚拟主机 SNI 分流那一套吗

@Fangliding
Copy link
Copy Markdown
Member

可能就是因为这些乱七八糟的原因才如此缓慢吧 我第一次看到这东西好像得是两年前24年那会了

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

想了一下有可能比如加了个额外的签名验证尝试以实现同 IP 区分多服务端?虽然 outer sni 一样,那的确是不能直接覆盖过去

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

那先不管了,@Fangliding 他这个 auto-route 的话得把 REALITY 仓库 record_detect.go 和 VLESS fallbacks 改一下,你看看

@Fangliding
Copy link
Copy Markdown
Member

这都要算吗 反正tun也就客户端用用应该无所谓吧 singbox clash那些带tun的都没见管

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 3, 2026

那有人提的话再说吧

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 4, 2026

multi dns instance 有在计划内吗

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 4, 2026

multi dns instance 有在计划内吗

先不管这个,先实现个 Xray 启动时自动探测出默认 interface 并应用到核心发出的连接吧,这个会不会影响 sendThrough

还有你看下隔壁两家的 auto-redirect 是不是拿 /0 减掉、自动计算路由表,如果是的话那它和 auto-route 的优先级?

它们的 auto 是不是还包括了把 routing 的 IP 规则自动弄过来,不过感觉这样干不好吧,direct/freedom 不一定是单纯发出

对了还需要实现个指定 TUN 的 IPv4 & IPv6,TUN 这块就差不多了

@patterniha
Copy link
Copy Markdown
Collaborator

I also think that thing is useless and too peripheral, and it seems like he doesn't update it anymore. It seems like the templates he releases don't even have that function; it's just ridiculous.

Although the internet is still down and only DNS or IP-Spoofing based methods work in Iran, they opened some Cloudflare IPs for some White SNIs for a few hours (They've done this a few times in the last month and closed it again.), and it is clear that they are implementing a new system.

"cloudflare-ech.com" was not in their whitelist, also fragments method didn't work, they simply close the connection when they can't read the sni.

but i tested some ip/tcp-header-manipulation methods and it can bypass this restriction:

method 1 (simplest one): send a white-sni-client-hello-packet with low ip-ttl before main-clienthello-packet: because GFW sees this packet and interprets it as a white-sni-clienthello-packet , so allow other packets without checking, but this packet does not reach to the cloudflare servers, so you can send your main-blocked-sni-clienthello-packet later !!!

Apart from method 1, I successfully tested 2 other methods (related to tcp-header) and with all of them I was able to successfully connect to cloudflare cdn.

///

@RPRX

It's time to prioritize raw-sockets-outbounds.

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 4, 2026

auto-redirect 是什么需求,我还在看 linux go 里怎么实现路由,不会只能 exec 吧

晚点我去视奸下其他两家吧,虽然我也不是很想当 skid

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 5, 2026

update,更新几点信息

  1. go 可以通过 vishvananda/netlink 在 linux 上操作路由
  2. 没有所谓的两家,全都是一家 - singtun,hysteria 也和 mihomo 一样没有造轮子
  3. autoRedirect 不是简单的操作静态路由,在 windows 上,通过在 WFP 侧拦截流量然后进行的路由,这种方式还可以根据 pid 进行分流
  4. excludeRoute 在非 autoRedirect 下是通过静态路由实现,比如要在 0.0.0.0/0 排除 192.168.1.1/32 就会看到
0.0.0.0/1
128.0.0.0/2
192.0.0.0/9
192.128.0.0/11
192.160.0.0/13
192.168.0.0/24
192.168.1.0/32
192.168.1.2/31
192.168.1.4/30
192.168.1.8/29
192.168.1.16/28
192.168.1.32/27
192.168.1.64/26
192.168.1.128/25
192.168.2.0/23
192.168.4.0/22
192.168.8.0/21
192.168.16.0/20
192.168.32.0/19
192.168.64.0/18
192.168.128.0/17
192.169.0.0/16
192.170.0.0/15
192.172.0.0/14
192.176.0.0/12
192.192.0.0/10
193.0.0.0/8
194.0.0.0/7
196.0.0.0/6
200.0.0.0/5
208.0.0.0/4
224.0.0.0/3
func main8() {
	var builder netipx.IPSetBuilder
	builder.AddPrefix(netip.MustParsePrefix("0.0.0.0/0"))
	builder.RemovePrefix(netip.MustParsePrefix("192.168.1.1/32"))
	result, _ := builder.IPSet()
	for _, p := range result.Prefixes() {
		fmt.Println(p)
	}
}

关于这个 pr,将会侧重在 windows 上的 autoRedirect 以及 tun 的 defaultInterface,其他 os 的路由先不说我没有某些 os,linux 上我也不会用到 tun,所以谁用谁加吧

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 13, 2026

这就要提到 win 上著名的智能多宿主解析了,组策略 -> 管理模板 -> 网络 -> DNS 客户端 -> 禁用智能多宿主名称解析,如果显示不禁用就是每个网卡都发一遍

DNS...leak?略复杂,以后再整

autoRoutingTable 改名 autoSystemRoutingTable,这下对齐了

mtu、autoOutboundsInterface 应该是任何系统都生效吧?gateway、dns、autoSystemRoutingTable 目前只支持 Windows?

配置示例里的 mtu json 最好换个行吧

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

DNS...leak?略复杂,以后再整

默认就是禁用的,应该问题不大,要杜绝的话就是之前说的 wfp 驱动层拦截,狠狠的入侵系统

mtu、autoOutboundsInterface 应该是任何系统都生效吧?gateway、dns、autoSystemRoutingTable 目前只支持 Windows?

mtu 其他 os 和之前一样,autoOutboundsInterface 理论所有 os 都生效,但我只测了 windows

gateway、dns、autoSystemRoutingTable 这个 pr 只有 windows

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 13, 2026

“mtu 其他 os 和之前一样” 是啥意思,其它 OS 不支持分 IPv4/v6 吗

不过 autoOutboundsInterface 的 "auto" 目前应该是只支持 Windows

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 13, 2026

“mtu 其他 os 和之前一样” 是啥意思,其它 OS 不支持分 IPv4/v6 吗

就是没动过,不过应该支持吧,我记得是有分 unix.AF_INET 和 unix.AF_INET6

不过 autoOutboundsInterface 的 "auto" 目前应该是只支持 Windows

多了个在后台监测网卡变动的 callback(不过应该也没什么用),初始化都一样

@RPRX RPRX changed the title tun: winroute TUN inbound: Add gateway, dns, autoSystemRoutingTable, autoOutboundsInterface for Windows Apr 13, 2026
@RPRX RPRX merged commit 806b8dc into XTLS:main Apr 13, 2026
39 checks passed
2dust added a commit to 2dust/v2rayNG that referenced this pull request Apr 14, 2026
@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 14, 2026

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

#5887 (comment) 这里说了一个可能回环的情况

他们那 UI 的配置还要搞分流有点复杂,但如果说换成 sockopt.interface 就不回环了那是不应该的,autoOutboundsInterface 应该完美覆盖了 sockopt.interface 的情况,还多了个 localdns

描述里的 freedom 启动后唯一占 cpu 的只有浏览器,需要最简可复现配置

@mclovin-2k
Copy link
Copy Markdown

能不能麻烦开发者看一下这个问题:
#5900

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

还真有个双栈问题,在 #5891 一起改了,默认 ipv6 就是按 dual stack 设置,应该没什么问题,darwin 和 windows 默认也是双栈的

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

@LjhAUMEM 应该解决了 2dust/v2rayN#9063 (comment) 吧?

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

@LjhAUMEM #5887 (comment) 这个也解决了吗

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

@LjhAUMEM 应该解决了 2dust/v2rayN#9063 (comment) 吧?

只能说 autoOutboundsInterface 现在和 sockopt.interface 没区别了,而且覆盖情况更多

@LjhAUMEM #5887 (comment) 这个也解决了吗

这个可以通过 sockopt.domainStrategy 解决,要改就是改成用 localdns 解析,但是应该不止这一处,单改这一处没什么意义感觉

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

这个可以通过 sockopt.domainStrategy 解决,要改就是改成用 localdns 解析,但是应该不止这一处,单改这一处没什么意义感觉

描述详细些是啥问题,这个 net.ResolveUDPAddr 不是指向了 Golang DNS 吗,你的意思是直接走系统 DNS 解析会回环?

RPRX pushed a commit that referenced this pull request Apr 15, 2026
And reverts "refactor `mtu` to support setting IPv4/v6 separately" #5891 (comment)

And fixes `autoOutboundsInterface` on Windows #5887 (comment)

---------

Co-authored-by: LjhAUMEM <llnu14702@gmail.com>
@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

描述详细些是啥问题,这个 net.ResolveUDPAddr 不是指向了 Golang DNS 吗,你的意思是直接走系统 DNS 解析会回环?

理论上是会,比如这个 outbound,这里的 www.example.com 就是走的 net.ResolveUDPAddr 也就是系统解析,理论上系统解析是会进入系统路由,然后又回到这个 outbound

{
  "protocol": "hysteria",
  "settings": {
	"address": "www.example.com",
	"port": 1081
  },
  "streamSettings": {
	"network": "hysteria"
  }
}

不过也只是 udp 类的 addr,net.dialer 绑定了网卡所以没问题

感觉改下也可以,下次重构 xicmp 带上这个吧

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

@LjhAUMEM 这种情况的话,Golang 能不能提前注入 net.ResolveUDPAddr() 使它回调自定义 setsockopt()?不过这函数没 ctx

或者手写 listen UDP 就可以 control fd

临时的解决方案是路由中加上匹配自身 "/self" 或覆盖范围更广的 "/xray",让潜在的回环流量走 direct 出站 @2dust @DHR60

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

LjhAUMEM commented Apr 15, 2026

@LjhAUMEM 这种情况的话,Golang 能不能提前注入 net.ResolveUDPAddr() 使它回调自定义 setsockopt()?不过这函数没 ctx

ResolveUDPAddr 就是 net.ParseIP + net.Resolver,搞个自定义 net.Resolver 就可以绑定到网卡了

临时的解决方案是路由中加上匹配自身 "/self" 或覆盖范围更广的 "/xray",让潜在的回环流量走 direct 出站

把回环的都路由到 direct 也是一个方法

理论上一切回环都可以通过内部路由解决,只要有任一出站是有效的

@Fangliding
Copy link
Copy Markdown
Member

感觉越来越dirty了

@LjhAUMEM
Copy link
Copy Markdown
Collaborator Author

感觉越来越dirty了

所以我才没动 dns 部分,autoOutboundsInterface 一开始也不打算动的来着

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

我觉得用 TUN 时建议加这个路由挺好的,万一以后加其它东西又整回环了,这算是个万能兜底,文档中确实得提醒下

Xray-core 的文档的话建议加 "/self" 吧,有的人可能就爱开俩进程然后整些进程 2 进一步处理进程 1 的流量的花活

@mclovin-2k
Copy link
Copy Markdown

我觉得用 TUN 时建议加这个路由挺好的,万一以后加其它东西又整回环了,这算是个万能兜底,文档中确实得提醒下

Xray-core 的文档的话建议加 "/self" 吧,有的人可能就爱开俩进程然后整些进程 2 进一步处理进程 1 的流量的花活

我的需求是先按进程名称分流一次,一部分进程走Direct,一部分进程的流量按域名和IP再分流一次。
一直以来,我都是用ProxyCap+XRay来实现这个需求的。
现在XRay既然支持了Tun,自然我是想去掉ProxyCap的。
但是目前RouteObject的匹配功能比较简单,想实现上面的逻辑就需要写非常多重复的规则,所以只能开两个XRay。

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Apr 15, 2026

@mclovin-2k 试试 loopback 出站?

@mclovin-2k
Copy link
Copy Markdown

@mclovin-2k 试试 loopback 出站?

明天试试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants