2dust / v2rayNG

A V2Ray client for Android, support Xray core and v2fly core
https://1.2345345.xyz
GNU General Public License v3.0
33.11k stars 5.18k forks source link

FCM 与系统 VPN 服务的交互更改导致部分情况下 FCM 绕过 v2rayNG 发起连接 #2641

Open KobeArthurScofield opened 8 months ago

KobeArthurScofield commented 8 months ago

在提出问题前请先自行排除服务器端问题,同时也请通过搜索确认是否有人提出过相同问题。

预期行为

Google FCM 推送长连接可以通过系统 VPN 服务由 v2rayNG 发起连接,其发起的连接可以通过路由规则指定为直连或者由代理连接。

实际行为

特定情形下 FCM 推送连接不会经由 v2rayNG 发起,但是 VPN 模式下 v2rayNG 接管了系统 DNS,如果启用 FakeDNS 时会导致部分网络下 FCM 获得需要被翻译的 FakeIP 导致连接失败。(如果未启用 FakeDNS,在 FCM 推送裸连能正常连接时该问题很难被察觉。如果是默认自动配置也很难察觉问题,因为默认配置下启用了 FakeDNS 之后依然有机会回落到指定的远端 DNS 服务器查询到有效的 IP,直到遇到连接被 ISP 掐断。)

SNIP

如图所示,如果连接具有 isVpnConnected=1 的标记,那么该 FCM 推送连接会经由 v2rayNG 发起,否则该连接绕过了 v2rayNG。目前的临时解决方案是在自定义配置中加入优先于 FakeDNS 的查询服务器来保证 FCM 推送可用,但是考虑到潜在的风险可能需要进行修正。

目前本机发现的情形是在 Wi-Fi 下会经由 v2rayNG 连接,而数据网络下不会(v2rayNG 被绕过了)。

经过咨询 FCM 支持,目前获得的回复是为了保证连接可达和电池使用量下特定情况会绕开 VPN 服务进行连接。似乎需要对应的客户端设置指示是否强制使用 VPN 服务连接。

复现方法

  1. 使用一台 Google APEX (Google 系统更新)/ Google Service 能更新到近期版本(两三个月内)的手机
  2. 使用 v2rayNG 开启 VPN 模式下的代理
  3. 在系统拨号盘拨入 *#*#426#*#*,点击 FCM diagnostic 上方的按钮切换到 Event 视图
  4. 在 Wi-Fi / 数据网络下来回切换,Event 视图内的 log 会指示连接是否使用 VPN

以下是体验上最好复现的复现方法

  1. 使用一台 Google APEX (Google 系统更新)/ Google Service 能更新到近期版本(两三个月内)的手机
  2. 使用自定义配置,启用本地 DNS 处理,然后使用以下的 DNS 配置置于自定义配置中(FakeDNS 优先,代理 DNS 有指定用于查询的域名且跳过回落):
    "dns": {
       "servers": [
            {
                "address": "fakedns",
                "domains": [
                    "geosite:googlefcm"    /* 任何能够包含 Google FCM 推送连接的规则分类都可以,包括 geosite:google 或者手写域名 */
                ]
            },
            "1.2.3.4",    /* 任意的本地 DNS */
            {
                "address": "5.6.7.8",    /* 任意的代理 DNS */
                "domains": [
                    "geosite:googlefcm"    /* 任何能够包含 Google FCM 推送连接的规则分类都可以,包括 geosite:google 或者手写域名 */
                ],
                "skipFallback": true
            }
        ],
        "disableFallbackIfMatch": true
    }
  3. 运行 VPN 模式下的代理
  4. 在系统拨号盘拨入 *#*#426#*#*,点击 FCM diagnostic 上方的按钮切换到 Event 视图
  5. 在 Wi-Fi / 数据网络下来回切换,Event 视图内的 log 会指示连接是否使用 VPN。这种情况下不使用 VPN 进行连接的 FCM 推送连接会失败或者断线,因为其获得的 IP 无法在实际连接中使用。

日志信息

在自定义配置中将 ```loglevel``` 设置为 ```debug```,```access``` 和 ```error``` 保持默认配置,打开 ```dnsLog```。同时需要却道本地 DNS 处理开启,否则可能连 DNS 查询的日志记录都没有。 复现时, 如果指示 isVpnConnected=1,则日志中会有对 FCM 域名的 DNS 查询记录以及 inbound sniffing 记录,后面还会有对应的路由记录。 如果没有 isVpnConnected=1 的指示,则只能看到对 FCM 域名的 DNS 查询记录,而不会找到 inbound sniffing 记录,也不会有后面的路由记录。 这日志很难粘贴,因为不走 VPN 的连接根本不会通过 v2rayNG。

环境信息

Android 9/11 均可复现,应该所有可以更新 Google APEX 组件 / Google Service 的系统都可以复现

额外信息(可选)

系统 VPN 设置下的“阻止不使用 VPN 的连接”似乎并不会有作用。

dyhkwong commented 2 months ago

https://developer.android.com/reference/android/net/VpnService.Builder#allowBypass() VpnService 需要指定 allowBypass 应用才能绕过 VPN,v2rayNG 并没有这样做,所以恐怕不是这个原因。

KobeArthurScofield commented 2 months ago

VpnService 需要指定 allowBypass 应用才能绕过 VPN,v2rayNG 并没有这样做,所以恐怕不是这个原因。

按照现在 FCM 的文档来说该当如此,但是目前观察到的现象还是在数据网络下面 FCM 推送直接绕开 VpnService 连接,不知道是 Google 的问题还是什么情况。

douziovo commented 1 week ago

淦 我开了local DNS下ZZZ WiFi一开关 话费-70

KobeArthurScofield commented 1 week ago

后续: 因为手机变砖换了手机,系统是 Android 14 (OxygenOS 14),现在所有网络下面的 FCM 都没有绕开系统 VPN 服务,全部经过 v2rayNG 进行连接了。

但是 Android 9 下面还是有这样的问题(Android 11 预计亦然),所以现在怀疑是不是 google 那边改动了什么导致的问题。 有种莫名其妙就被整出毛病的感觉