折腾:再战渣易——UU检测升级

书接上文,搞定了 UU 加速 xbox 以后没多久就买了 4070ti,那之后是更没有机会玩 xbox 了,再之后我统一了 routeros 标注包 / 连接的方式,也没时间去测试加速功能有没有问题,结果周六打开 xbox 一看,嘿,UU 升级给我的方案烂掉了。

是我搞烂的?

对于我的环境来说,肯定首先要排除 routeros 上流量转发的问题,从上次折腾后,我的包转发进行了一些修改,现在 mangle 表的逻辑是:

/ip/firewall/mangle

add action=mark-packet chain=prerouting comment="connection: bypass" connection-mark=mark-bypass new-packet-mark=mark-bypass passthrough=no
add action=mark-packet chain=prerouting comment="connection: proxy" connection-mark=mark-proxy new-packet-mark=mark-proxy passthrough=yes
add action=mark-packet chain=prerouting comment="connection: xbox" connection-mark=xbox new-packet-mark=xbox passthrough=yes

add action=jump chain=prerouting comment="judge connection" connection-mark=no-mark jump-target=judge-packet packet-mark=no-mark

add action=accept chain=prerouting comment="action: bypass" connection-mark=mark-bypass

add action=mark-routing chain=prerouting comment="action: route to uu" in-interface=!bridge.163 new-routing-mark=xbox packet-mark=xbox passthrough=no

add action=mark-routing chain=prerouting comment="action: proxy http(s)" in-interface=!bridge.802 new-routing-mark="proxy-http(s)" packet-mark=mark-proxy passthrough=no

add action=accept chain=prerouting comment="action: accept rest"

首先将 connection-mark 复制到 packet-mark 上,之后对于没有标记的包做判断,最后再根据标记的情况选择出口,判断包的逻辑大致是:

add action=jump chain=judge-packet comment="judge: bypass" jump-target=judge-bypass packet-mark=no-mark
add action=mark-packet chain=judge-packet comment="judge: xbox" dst-address-list=!range-all-local new-packet-mark=xbox packet-mark=no-mark passthrough=yes src-address-list=xbox
add action=jump chain=judge-packet comment="judge: proxy" jump-target=judge-proxy packet-mark=no-mark
add action=mark-packet chain=judge-packet comment="judge: bypass other" dst-address-list=!range-local new-packet-mark=mark-bypass packet-mark=no-mark passthrough=yes src-address-list=range-local

add action=mark-connection chain=judge-packet comment="judge: packet to connection" new-connection-mark=mark-bypass packet-mark=mark-bypass passthrough=yes
add action=mark-connection chain=judge-packet comment="judge: packet to connection" new-connection-mark=mark-proxy packet-mark=mark-proxy passthrough=yes
add action=mark-connection chain=judge-packet comment="judge: packet to connection" new-connection-mark=xbox packet-mark=xbox passthrough=yes

add action=return chain=judge-packet comment="judge: finish"

大致的逻辑是,先判断 bypass(主要是内网和国内 IP)再判断 proxy,并且在 proxy 之前判断 UU,这样内网流量、国内流量(还可以指定一些特殊流量,比如你懂的)就不需要再经过 UU 了,这样既稳定又安全,这也是我搞这么复杂一堆的原因。经过了路由器上多次抓包,流量转发似乎没有问题,甚至刚启动加速还能连上几个连接。

那又咋回事儿啊?

还是回到 UU 的界面,我们发现现在 UU 的界面会卡在一个之前没有的阶段,而且超时以后就会退出。抓包以后发现 UU 的接口上多了很多以前没有的包,主要是一些 DNS 和另一些看不懂的 UDP 包,而且在这个等待阶段循环发送。

没有办法,为了获取现在连接时的完整过程,只能修改到官方指定的配置,然后重新抓包。根据不同情况下抓包测试,现在使用 UU Windows 客户端加速 xbox 游戏时,客户端一共有以下几个阶段:(不考虑 IP 配置错误的情况)

  1. 等待阶段:启动后这个阶段 UU 不会主动发送任何包,这时接收到任何包会进入识别阶段;曾经的行为是收到包以后直接进入加速阶段。
  2. 识别阶段:这个阶段 UU 会主动发送一系列 DNS包,和一些 UDP 包,其中 DNS 包是为了通过主机返回的 SRV 记录判断主机类型,而UDP则是一些主机私有的连接包,两项都正确以后才会进入加速阶段;
  3. 加速阶段:这个阶段不会再重复检查主机类型的阶段,和以前一样;

那咋整啊?

我们先要看这两个识别分别怎么坏了,首先为什么这些包都是红色的?因为他们被特意设置了 TTL=2,即使在我这样中间隔着一个路由器的场景,TTL=2 其实也够了,如果你的环境更复杂,那么可能要在路由器上 mangle 成更大的值。

这些包涉及到 xbox 的应该就两种,第一个 :5050UDP,xbox 似乎返回了一些基本信息,包里能看的只有一个UUIDXBL Smart Glass Issuing CA0和两个序列号。xbox 似乎不会回复非 LAN 上的这个请求,而我这方案 xbox 使用的是正常网段和 UU 的网段不一样,所以解决方案就是增加一条 masquerade,把 UU 的请求 snat 成路由器本身的,这样 xbox 就能正确返回,再 dnat 回去完成考察。

DNS 包的问题则在于,xbox 只会回复他的真 IP,而 UU 似乎需要假 IP一致,这里则是两个方案,一个是把录下来的 DNS 回包修改完后直接发给 UU,或者也可以自己拼一个伪客户端来返回。

啊?

上面这些全部弄完以后,终于正常识别了,但是当我想复现的时候,我发现即使上面的东西全部关闭也能正常连接识别,怎么弄都弄不坏。

我怀疑 UU 可能对于同一个 mac 有检测的时限,一段时间(不知道长短)内不需要再次识别。这下也没法做实验获知到底哪些是必要条件了。折腾了几个小时,也不是很想故意搞烂再修好了,具体哪些必要就当课后作业留给需要复刻的同学了。

总结

UU 增加这个识别的初衷,其实可能是为了支持多个设备,或者防止有人选错加速类型,误伤到了我。当然,另一种可能是为了防止有人用 UU 的线路当梯子使用,当然,这都不可考了。

既然用了别人的服务,还是非标准用法,需要经常折腾就太正常了,但是某些人可能就是喜欢折腾?

其他

在查问题的时候发现一些好玩的东西,UU 所有发的包都要发两遍,UU 所有发的包都要发两遍,可能是为了防止客户的内网发生丢包影响效果去骂 UU,干脆都发两遍😓,这导致我一开始看到大量重传,还以为是挨批桌子配错了。