6

我使用VpnService创建了一个 TUN 设备。为什么 TUN 接口在我设备的其他网络接口中具有最高优先级?

更新#1

这就是我配置 TUN 设备的方式:

mInterface = new Builder().setSession(getString(R.string.app_name))
        .addAddress("10.0.1.1", 24)
        .addRoute("0.0.0.0", 1)
        .addRoute("128.0.0.0", 1)
        .establish();

更新#2

这是route -n 没有TUN 设备的输出:

shell@m0:/ $ busybox route -n
busybox route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.197.55.0     0.0.0.0         255.255.255.0   U     0      0        0 rmnet0

这是route -n 使用TUN 设备的输出:

shell@m0:/ $ busybox route -n
busybox route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.1.0        0.0.0.0         255.255.255.0   U     0      0        0 tun0
10.197.55.0     0.0.0.0         255.255.255.0   U     0      0        0 rmnet0
shell@m0:/ $
4

1 回答 1

2

如果在 Android 上启用了 VpnService,并不意味着所有流量都通过 VpnTunnel。这取决于 IP 路由和允许/禁用应用程序代理设置。

mInterface = new Builder().setSession(getString(R.string.app_name))
        .addAddress("10.0.1.1", 24)
        .addRoute("0.0.0.0", 1)
        .addRoute("128.0.0.0", 1)
        .establish();

上面的代码显然是全局路由,相当于 0.0.0.0/0,你可能从 OpenVPN 设置中知道。

如果默认网关是 tun,则所有 IP 流量都通过 tun 设备。

在这种情况下,如果你不想让一个socket流量通过tun,你需要为socket-fd调用VpnService::p rotect函数来保护fd。

但这还不够,您还需要找到一个有效的网络(不是 VPN),调用它的 Network::bindSocket 函数,并让一个 Socket 穿过该网络并退出。

如果您不想使用 Network::bindSocket 函数保护套接字!然后可以设置默认网络,但只对开启VPN服务的android-进程有效。

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            try {
                ConnectivityManager cm = PppVpnNetworkListener.getConnectivityManager(this._service);
                if (cm != null) {
                    cm.bindProcessToNetwork(network);
                }
            } catch (Throwable ignored) {
            }
        }
        try {
            ConnectivityManager.setProcessDefaultNetwork(network);
        } catch (Throwable ignored) {
        }
于 2022-01-24T03:51:53.927 回答