MetaCubeX / mihomo

A simple Python Pydantic model for Honkai: Star Rail parsed data from the Mihomo API.
https://wiki.metacubex.one
MIT License
13.82k stars 2.4k forks source link

最新构建版alpha, vision+reality连接错误 #444

Open Zxis233 opened 1 year ago

Zxis233 commented 1 year ago

#440修复后,重新用正确配置进行测试,但日志中大量出现

23-03-14 08:12:23[ error ]XTLS Vision server responded unknown UUID: 12040000-0000-0000-0300-000080000400

查看服务端日志,并且与正常连接的日志进行对比,发现服务端似乎未收到xray-core版本信息,不知clashmeta里是否需要加上。除此以外,用clashMeta连接时,服务端并未输出任何关于short-id的信息,直接返回hs.c.conn == conn: false。

iKira commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

qist commented 1 year ago
 - name: vless-reality-h2
    type: vless
    server:  server
    port: 443
    uuid: uuid
    network: h2
    tls: true
    udp: true
    flow:
    servername: www.lovelive-anime.jp
    h2-opts:
      host:
        - www.lovelive-anime.jp
      path: /
    reality-opts:
      public-key: 
      short-id: 

这个可以连接但是测速没返回。

Zxis233 commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

设置最小版本为1.7.5仍旧无法连接。可以看看你的服务端配置吗?

hooUmAi commented 1 year ago

我也遇到了类似的情况 我对比了服务端打开show: true后 v2rayNG 和 ClashMetaForAndroid 访问生成的日志,服务端在 v2rayNG 访问时输出了AuthKey, Client, ClientTime, ClientShortId,但 ClashMetaForAndroid 访问时服务端只输出了AuthKey,之后立即就是hs.c.conn == conn: false

yoohooyoo commented 1 year ago

+1

我也遇到了类似的情况 我对比了服务端打开show: true后 v2rayNG 和 ClashMetaForAndroid 访问生成的日志,服务端在 v2rayNG 访问时输出了AuthKey, Client, ClientTime, ClientShortId,但 ClashMetaForAndroid 访问时服务端只输出了AuthKey,之后立即就是hs.c.conn == conn: false

iKira commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

设置最小版本为1.7.5仍旧无法连接。可以看看你的服务端配置吗?

跟这里一样的:https://github.com/XTLS/REALITY

hooUmAi commented 1 year ago

是能连接上了因此close了吗?请问修改了什么配置?

chika0801 commented 1 year ago

是能连接上了因此close了吗?请问修改了什么配置?

Esing🥰: 我是不同协议分不同json的

reality那个换行符是LF,其余的都是CRLF

w他说的

yoohooyoo commented 1 year ago

测试了下,还是连不上。 我还是等下一个修复版本吧。T-T

qist commented 1 year ago

我这边没现在版本 一致都没啥问题。

qist commented 1 year ago

@chika0801 你的模板库可以增加一个TROJAN-gRPC-uTLS-REALITY 这个比vless 质量好点。

RPRX commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

这个设计使服务端可以拒绝过时的 uTLS 或客户端实现,比如 uTLS v1.3.0 前有 bug,升级该库时应一并更新 REALITY 的版本号。 比如说多人共享时,你可以修改 minClientVer,其他人必须将 REALITY 客户端更新至较新版本,防止旧版本祸害服务端

参考 https://github.com/XTLS/Xray-core/issues/1544#issuecomment-1399194727

我也遇到了类似的情况 我对比了服务端打开show: true后 v2rayNG 和 ClashMetaForAndroid 访问生成的日志,服务端在 v2rayNG 访问时输出了AuthKey, Client, ClientTime, ClientShortId,但 ClashMetaForAndroid 访问时服务端只输出了AuthKey,之后立即就是hs.c.conn == conn: false

这种情况是服务端解密失败,有可能是你没有给客户端填指纹(REALITY 客户端必须填指纹)。此外我看到 Clash.Meta 的 REALITY 可以自定义 ALPN,这是不合适的:若用浏览器指纹,不应当任意修改,否则很明显就不是浏览器,干脆等下给服务端加个检查

参考 https://github.com/XTLS/Xray-core/discussions/1773#discussioncomment-5276077

@chika0801 你的模板库可以增加一个TROJAN-gRPC-uTLS-REALITY 这个比vless 质量好点。

这个哪里比 VLESS 质量好点

chika0801 commented 1 year ago

@chika0801 你的模板库可以增加一个TROJAN-gRPC-uTLS-REALITY 这个比vless 质量好点。

主要是那种感觉,你自己家做出来的东西,还白给别人做事

点击查看
服务端入站的部分 ``` { "listen": "0.0.0.0", "port": 8006, "protocol": "trojan", "settings": { "clients": [ { "password": "chika" } ] }, "streamSettings": { "network": "grpc", "security": "reality", "realitySettings": { "show": false, "dest": "www.lovelive-anime.jp:443", "xver": 0, "serverNames": [ "www.lovelive-anime.jp" ], "privateKey": "2222222222222222222222222222222", "shortIds": [ "1111111111" ] }, "grpcSettings": { "serviceName": "grpc" } }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } } ``` 我在v2rayN看了下选添加Trojan,TLS那没做reality,你要用自定义配置,肯定不方便,能用是能用。 v2rayN客户端配置 ``` { "log": { "loglevel": "warning" }, "dns": { "servers": [ "1.1.1.1" ], "queryStrategy": "UseIPv4" }, "routing": { "domainStrategy": "AsIs", "rules": [ { "type": "field", "domain": [ "geosite:category-ads-all" ], "outboundTag": "block" }, { "type": "field", "domain": [ "geosite:category-games@cn" ], "outboundTag": "direct" }, { "type": "field", "domain": [ "geosite:geolocation-!cn" ], "outboundTag": "proxy" }, { "type": "field", "domain": [ "geosite:cn", "geosite:private" ], "outboundTag": "direct" }, { "type": "field", "ip": [ "geoip:cn", "geoip:private" ], "outboundTag": "direct" } ] }, "inbounds": [ { "listen": "127.0.0.1", "port": 10808, "protocol": "socks", "settings": { "udp": true }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } }, { "listen": "127.0.0.1", "port": 10809, "protocol": "http", "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } } ], "outbounds": [ { "protocol": "vless", "settings": { "vnext": [ "servers": [ { "address": "1.2.3.4", "port": 8006, "password": "chika" } ] }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "show": false, "fingerprint": "chrome", "serverName": "www.lovelive-anime.jp", "publicKey": "1111111111111111111111111111111111111", "shortId": "1111111111", "spiderX": "/" } }, "tag": "proxy" }, { "protocol": "freedom", "settings": { "domainStrategy": "AsIs" }, "tag": "direct" }, { "protocol": "blackhole", "settings": { "response": { "type": "http" } }, "tag": "block" } ] } ```
qist commented 1 year ago

@chika0801
Clash.Meta 配置

- name: trojan-reality-grpc
    server: server
    port: 443
    type: trojan
    password: "password"
    network: grpc
    alpn:
      - h2
    sni: www.lovelive-anime.jp
    flow:
    skip-cert-verify: false
    udp: true
    grpc-opts:
      grpc-service-name: "path"
    reality-opts:
      public-key: 4sOfcRRDfIauzddPL79g3WGKXoVlVXB6ZziitVZoBUE
      short-id: aa244f6889399408
RPRX commented 1 year ago

@chika0801 小细节,你出站写的是 VLESS + password

Larvan2 commented 1 year ago

@RPRX

Clash.Meta 的 REALITY 可以自定义 ALPN

这个属于是意外,之前群里讨论 utls 会不会自动加 ALPN,H1手快先加了自定义,后来才发现会自动加

qist commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

这个设计使服务端可以拒绝过时的 uTLS 或客户端实现,比如 uTLS v1.3.0 前有 bug,升级该库时应一并更新 REALITY 的版本号。 比如说多人共享时,你可以修改 minClientVer,其他人必须将 REALITY 客户端更新至较新版本,~防止旧版本祸害服务端~。

参考 XTLS/Xray-core#1544 (comment)

我也遇到了类似的情况 我对比了服务端打开show: true后 v2rayNG 和 ClashMetaForAndroid 访问生成的日志,服务端在 v2rayNG 访问时输出了AuthKey, Client, ClientTime, ClientShortId,但 ClashMetaForAndroid 访问时服务端只输出了AuthKey,之后立即就是hs.c.conn == conn: false

这种情况是服务端解密失败,有可能是你没有给客户端填指纹(REALITY 客户端必须填指纹)。此外我看到 Clash.Meta 的 REALITY 可以自定义 ALPN,这是不合适的:若用浏览器指纹,不应当任意修改,否则很明显就不是浏览器,~干脆等下给服务端加个检查~。

参考 XTLS/Xray-core#1773 (comment)

@chika0801 你的模板库可以增加一个TROJAN-gRPC-uTLS-REALITY 这个比vless 质量好点。

~这个哪里比 VLESS 质量好点~

表达有误,抱歉。

iKira commented 1 year ago

确实,服务端配置文件去掉minClientVer限制就可以正常连(或者minClientVer设为1.7.5,设为1.8.0不行)

这个设计使服务端可以拒绝过时的 uTLS 或客户端实现,比如 uTLS v1.3.0 前有 bug,升级该库时应一并更新 REALITY 的版本号。 比如说多人共享时,你可以修改 minClientVer,其他人必须将 REALITY 客户端更新至较新版本,~防止旧版本祸害服务端~。

参考 XTLS/Xray-core#1544 (comment)

我也遇到了类似的情况 我对比了服务端打开show: true后 v2rayNG 和 ClashMetaForAndroid 访问生成的日志,服务端在 v2rayNG 访问时输出了AuthKey, Client, ClientTime, ClientShortId,但 ClashMetaForAndroid 访问时服务端只输出了AuthKey,之后立即就是hs.c.conn == conn: false

这种情况是服务端解密失败,有可能是你没有给客户端填指纹(REALITY 客户端必须填指纹)。此外我看到 Clash.Meta 的 REALITY 可以自定义 ALPN,这是不合适的:若用浏览器指纹,不应当任意修改,否则很明显就不是浏览器,~干脆等下给服务端加个检查~。

参考 XTLS/Xray-core#1773 (comment)

@chika0801 你的模板库可以增加一个TROJAN-gRPC-uTLS-REALITY 这个比vless 质量好点。

~这个哪里比 VLESS 质量好点~

设计minClientVer的背景和逻辑我是能理解和支持的。我比较好奇为什么设为1.8.0就不能连,而1.7.5就可以,是因为minClientVer判断是“大于”,并不是“大于等于”吗?

RPRX commented 1 year ago

设计minClientVer的背景和逻辑我是能理解和支持的。我比较好奇为什么设为1.8.0就不能连,而1.7.5就可以,是因为minClientVer判断是“大于”,并不是“大于等于”吗?

有没有一种可能,Clash.Meta 的 REALITY 写的还是 1.7.5,所以你服务端写 "minClientVer" = "1.8.0",Clash.Meta 是连不上的

这个版本号在 Xray-core 中是自动的,为了方便其它实现,要不我们把第四个字节拿出来用吧,反正剩下的够用到 2106 年 比如在 Clash.Meta 的 REALITY 实现中,前三个字节填充 Clash.Meta 的版本号,第四个字节填 1,以和 Xray-core 区分 这样大家都比较方便,服务端还能区分不同的客户端实现,这个想法怎么样 @H1JK @Larvan2

RPRX commented 1 year ago

就是说到 2106 年,TLSv1.3 和 REALITY 应该早就成历史了,所以第四个字节实际用不上,干脆拿出来方便一下大家

iKira commented 1 year ago

设计minClientVer的背景和逻辑我是能理解和支持的。我比较好奇为什么设为1.8.0就不能连,而1.7.5就可以,是因为minClientVer判断是“大于”,并不是“大于等于”吗?

有没有一种可能,Clash.Meta 的 REALITY 写的还是 1.7.5,所以你服务端写 "minClientVer" = "1.8.0",Clash.Meta 是连不上的

这个版本号在 Xray-core 中是自动的,为了方便其它实现,要不我们把第四个字节拿出来用吧,~反正剩下的够用到 2106 年~ 比如在 Clash.Meta 的 REALITY 实现中,前三个字节填充 Clash.Meta 的版本号,第四个字节填 1,以和 Xray-core 区分 这样大家都比较方便,~服务端还能区分不同的客户端实现~,这个想法怎么样 @H1JK @Larvan2

赞同!

RPRX commented 1 year ago

你们选一个自己喜欢的数字吧,还有 @nekohasekai 的 sing-box,大家选不同的数字就行

RPRX commented 1 year ago

既然原有对时间戳的解析要改,顺便我们把它改成从 2023.1.1 开始计时吧,时间戳减掉 1672531200 秒,给它续到 2159 年

RPRX commented 1 year ago

看了下群,@H1JK 说得有道理,有生之年 X25519 就会下线,那时间戳还是直接 UNIX 吧,不给它续了,少点计算量

你们选好数字直接改 REALITY 客户端代码就行,先到先得

H1JK commented 1 year ago

@RPRX My idea is to design a REALITY protocol version where changes are explicitly specified for each version, and all clients MUST implement these new requirements before updating the version number in the request.

This is due to the fact that new clients may support the protocol at any time, but new implementations are expected to use the version numbers of existing clients for convenience. sing-box and Clash.Meta are the examples, they use Xray 1.7.5 as version code. To avoid confusion, do not do IANA works.

H1JK commented 1 year ago

可以自定义 ALPN

It seems that the direct modification to utls.Config struct NextProto field takes no effect because ALPN is a part of uTLS mimicry. So WebSocket with uTLS needs a additional process for ALPN. I forgot this at that time so nothing actually happened. 😂

RPRX commented 1 year ago

@RPRX My idea is to design a REALITY protocol version where changes are explicitly specified for each version, and all clients MUST implement these new requirements before updating the version number in the request.

This is due to the fact that new clients may support the protocol at any time, but new implementations are expected to use the version numbers of existing clients for convenience. sing-box and Clash.Meta are the examples, they use Xray 1.7.5 as version code. To avoid confusion, do not do IANA works.

其实 REALITY 协议本身不会大改,这个版本号不是“协议版本号”,而是“实现版本号”。

比如升级了 uTLS 库,“实现版本号”应往上跳(否则我们难以做到区分过时的 uTLS 实现),Xray-core 现在是自动的,但我们也看到了,如果都按 Xray 的填,对其它实现来说要经常改代码,很不方便。而如果把这个“实现版本号”独立出来,那么对所有实现来说都不方便了。所以对开发者来说,自动填上版本号是最方便的方式。不过 Clash.Meta 代码里是不是没有版本号,这倒很少见。

这里没有严格的注册机制,因为服务端一般是拒绝已知有问题的客户端版本,除此之外放行,新的客户端不与已有流行客户端冲突即可。至于协议的具体实现,我觉得不必强求,比如没有完整实现 SpiderX 其实也增加了多样性,而且当我们能区分客户端后,若有需要,服务端可以指定必须用哪一个(让服务端放心的)客户端,增强了服务端对队友的筛选能力,我觉得这是很有意义的。

nekohasekai commented 1 year ago

你有什么 uTLS 过时以外的需要排除某个版本的场景么?即使有,当你更新服务器的时候,你就应该知道哪些客户端及其版本需要被排除了;而不是在 examples 里写一堆排除有问题的客户端,不断增长

RPRX commented 1 year ago

其实上面的想法主要是方便其它实现,那么,若仅针对“筛掉过时的 uTLS”这一需求,你们觉得用什么方式来实现比较好呢?

还有一个想法是自动填 uTLS 的版本号(若能实现),但并不是所有实现都使用或直接引用原始 uTLS 库。

nekohasekai commented 1 year ago

我觉得这个需求有问题(参考 v2ray 弃用 alterId 一年后一批批用环境变量绕过的人)。不过非要检测 uTLS 的话,可以用自身的 uTLS 生成一个指纹列表(例如使用 ja3 的官方 go library),如果不在其中就拒绝。

RPRX commented 1 year ago

REALITY 有实现“客户端指纹白名单”的计划,但它的缺点也很明显:假如 uTLS 加了一个新版本的 Chrome 指纹,客户端一更新就不能用了,因为服务端还没有更新,数据库中没有该指纹。

此外,服务端的“客户端指纹白名单”并不能解决这样的问题:https://github.com/refraction-networking/utls/pull/171 如果服务端允许任意版本的 uTLS 连接,那么中间人就可以据此检测出旧版 uTLS,从而导致增加对服务端的怀疑,甚至直接封禁,所以类似“筛掉过时的 uTLS”的需求是切实存在的。

nekohasekai commented 1 year ago
  1. 即使 uTLS 更新,旧的指纹并没有立即过时而可用于审查,所以不需要检测(就像 naive 一样)。

  2. go TLS 行为特征修复,并不属于 uTLS 的版本一部分,而属于 reality 协议规定(它数量有限,并不需要像指纹一样更新)。

我认为正确的办法是在请求中附加一组 flag 表示实现了某个协定,而拒绝某 个特定的问题(似乎和协议版本号是一个意思。

nekohasekai commented 1 year ago

另:没有证据表明 GFW 会用破坏性的 方式(比如在连接中插入数据) 以识别代理。

RPRX commented 1 year ago

即使 uTLS 更新,旧的指纹并没有立即过时而可用于审查,所以不需要检测(就像 naive 一样)。 go TLS 行为特征修复,并不属于 uTLS 的版本一部分,而属于 reality 协议规定(它数量有限,并不需要像指纹一样更新)。 另:没有证据表明 GFW 会用破坏性的方式(比如在连接中插入数据)以识别代理。

比如,刚刚的 issue 不是“指纹过时”的问题,而是 uTLS 实现上的问题,它影响所有使用旧版 uTLS 的程序,已在 v1.3.0+ 修复。 它的危险性在于中间人插 17 个 CSS 包并不会破坏真浏览器的连接,只会破坏 uTLS:https://github.com/refraction-networking/utls/pull/171#issuecomment-1458718635

我认为正确的办法是在请求中附加一组 flag 表示实现了某个协定,而拒绝某个特定的问题(似乎和协议版本号是一个意思。

和版本号是一个意思

nekohasekai commented 1 year ago

这说的这些和我所述没有冲突,此外,版本号指 H1 描述的协议版本号。

RPRX commented 1 year ago

版本号指 H1 描述的协议版本号。

协议版本号解决不了“某个客户端以为它正确实现了,但其实有 bug”的问题。

nekohasekai commented 1 year ago

对于你觉得没有能力实现规范的客户端作者,你可以提供测试工具以协助其在发布前发现问题;会故意偷懒不实现某个协定的人,当然也可以伪装客户端特征以绕过这样的检查。但是首先,你要写协议规范。

hooUmAi commented 1 year ago

我尽可能排除了其他影响因素进行了测试,确实连不上。

客户端使用的是最新的ClashMetaForAndroid,配置如下:

mixed-port: 7891
allow-lan: false
bind-address: "*"
mode: rule
log-level: debug

ipv6: true

proxies:
  - name: "proxy"
    type: vless
    server: some.server.domain.name
    port: 8443
    uuid: some-random-uuid
    network: tcp
    udp: true
    tls: true
    flow: xtls-rprx-vision
    servername: some.server.domain.name
    reality-opts:
      public-key: SoMePUbliCkEY
      short-id: ffffffffffffffff
    client-fingerprint: firefox

rules:
  - DOMAIN-SUFFIX,some.server.domain.name,DIRECT
  - MATCH,proxy

测试方法是只用客户端代理termux,在termux上curl https://bing.com

服务端reality入口配置尽可能参照了chika0801的模板,内容如下:

        {
                "listen": "0.0.0.0",
                "port": "8443",
                "protocol": "vless",
                "settings": {
                        "clients": [{
                                "id": "some-random-uuid",
                                "flow": "xtls-rprx-vision",
                                "level": 0,
                                "email": "hooUmAi"
                        }],
                        "decryption": "none"
                },
                "streamSettings": {
                        "network": "tcp",
                        "security": "reality",
                        "realitySettings": {
                                "show": true,
                                "dest": ":9443",
                                "xver": 0,
                                "serverNames": [
                                        "some.server.domain.name"
                                ],
                                "privateKey": "SoMePRivaTEkEY",
                                "shortIds": [
                                        "ffffffffffffffff"
                                ]
                        }
                },
                "tag": "vless"
        }

服务端日志为:

REALITY remoteAddr: some.client.ip:2655   hs.clientHello.sessionId: [23 137 107 127 104 247 226 215 72 245 94 111 153 203 215 166 216 184 97 234 220 244 154 213 92 238 169 131 59 144 46 61]
REALITY remoteAddr: some.client.ip:2655   hs.c.AuthKey: [245 183 196 183 223 251 242 247 163 21 93 222 176 64 159 22 236 223 11 205 104 207 156 244 1 243 112 160 141 104 219 41]
REALITY remoteAddr: some.client.ip:2655   hs.c.conn == conn: false
REALITY remoteAddr: some.client.ip:2655   handled: false

之前类似的配置用v2rayNG是能够连上的

chika0801 commented 1 year ago

@hooUmAi

看了下你发的配置,客户端配置的

servername: some.server.domain.name

这个地方是填你要(偷)的网站的sni。

server: some.server.domain.name

这个网址是你自己设置的一个子域名指向你vps的方便,方便你不想输入vps ip的,它和目标网站网址不是一个。

我看了下你配置就觉得这点我没理解你示例的意思。

当然 REALTIY配置示例 说明用的服务端的域名 或 IP,我遇到过搞不懂这点域名指什么来问的群友几个了

我在用最新版本的app,加服务端是xray1.80,我这一直没遇到什么兼容问题都挺正常的。

hooUmAi commented 1 year ago

@hooUmAi

看了下你发的配置,客户端配置的

servername: some.server.domain.name

这个地方是填你要(偷)的网站的sni。

server: some.server.domain.name

这个网址是你自己设置的一个子域名指向你vps的方便,方便你不想输入vps ip的,它和目标网站网址不是一个。

我看了下你配置就觉得这点我没理解你示例的意思。

当然 REALTIY配置示例 说明用的服务端的域名 或 IP,我遇到过搞不懂这点域名指什么来问的群友几个了

我在用最新版本的app,加服务端是xray1.80,我这一直没遇到什么兼容问题都挺正常的。

你可以看一下服务端的配置,能看到服务端的dest指向本地9443。我在本地9443运行有其他tls server,所以实际上是偷自己,因此servername和server确实是同一个

chika0801 commented 1 year ago

Screenshot_2023-03-19-02-41-54-438-edit_com foxdebug acode 你意思是你用的是自己偷自己配置,clashmeta当客户端遇到连不通吗?

我也有这样的配置在meta 安卓app用是正常的。

主要是这种问题不好打字分析要不你帖完整些配置,要不自己再研究下 如果你是自己偷自己不行,我这用成的

我看了你clash配置,唯一不一样我填的是vps ip,没填vps的域名

我的配置是 https://github.com/chika0801/Xray-examples/blob/main/Clash_Meta_For_Android.yaml

hooUmAi commented 1 year ago

我好像发现问题在哪儿了。问题好像在于Meta在热切换配置的时候会有一些不可预测的行为,至少我观察到MetaForAndorid在切换了配置并重新开关之后仍然在health check之前配置里的proxy group的情况。切换配置之后杀掉重启就好了。

Skyxim commented 1 year ago

@hooUmAi 因为没有主动关闭,最终的关闭会在对象被 gc 时

feidaodu commented 1 year ago

我也是,能连上,但是没有测速返回。。 很无奈。。总感觉心里没底。