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) {
}