Android VpnService. Почему весь трафик проходит через устройство TUN?

Я создал устройство TUN с помощью VpnService. Почему интерфейс 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:/ $

1 ответ

Если VpnService включен на Android, это не значит, что весь трафик проходит через 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-устройство.

В этом случае, если вы не хотите, чтобы трафик сокета проходил через tun, вам нужно вызвать функцию VpnService::p rotect для socket-fd, чтобы защитить fd.

Но этого недостаточно, вам также нужно найти действующую сеть (не VPN), вызвать ее функцию Network::bindSocket и заставить Socket пройти через эту сеть и выйти.

Если вы не хотите защищать сокет функцией Network::bindSocket! Затем вы можете установить сеть по умолчанию, но она действительна только для андроид-процесса открытия службы VPN.

              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) {
        }
Другие вопросы по тегам