Android отдаёт реальный IP мимо VPN, и Google чинить это не будет

10.09.2026 8 мин 8

В Android есть переключатель «Блокировать соединения без VPN». Включаешь его вместе с постоянным VPN - и система обещает, что мимо туннеля с устройства не уйдёт ничего. Две независимые находки этого года показывают, что любое обычное приложение проходит мимо этого переключателя и отдаёт ваш реальный IP-адрес серверу, который выберет само. Google закрыл оба обращения, ничего не починив.

Кратко

  • Два независимых обхода, найденные двумя разными исследователями, ломают постоянный VPN с включённой блокировкой.
  • Ни одному не нужно разрешение, которое пользователь подтверждает вручную. Хватает доступа в интернет, а он выдаётся автоматически.
  • Приём в обоих случаях один: заставить системный процесс отправить пакет за тебя. На системные процессы правила блокировки не распространяются.
  • Один отчёт Google пометил «Won't Fix (Infeasible)», второй закрыл без действий. GrapheneOS первую дыру закрыла, вторую обещает закрыть.

Что вообще гарантирует этот переключатель

Когда на Android поднимается VPN, система переписывает правила маршрутизации так, что приложения под туннелем достают до сети только через него. У каждого сокета есть метка, по которой ядро понимает, какой сети он принадлежит, и если приложение пробует привязать сокет напрямую к физическому интерфейсу Wi-Fi, проверка не проходит и вызов возвращает отказ. Это и есть механика настройки, и она работает.

Работает она для приложений. Сокеты системных компонентов лежат ниже порога FIRST_APPLICATION_UID и помечаются как системные, а значит достают до любой сети независимо от того, что делает VPN в пространстве пользователя. Системе нужно уметь говорить с сетью при любых обстоятельствах, так что само по себе исключение разумно. Проблемой оно становится в тот момент, когда обычное приложение может уговорить системный процесс отправить пакет вместо себя.

Дыра первая: вежливое прощание

В Android 16 появилась функция аккуратного закрытия соединений QUIC. Если сокет приложения умер внезапно, сервер на другом конце остаётся с полуоткрытым соединением до истечения таймаута, поэтому система теперь позволяет заранее зарегистрировать прощальный пакет, который она доставит за приложение. Исследователь, нашедший брешь и публикующийся как lowlevel, назвал результат «маленькой UDP-пушкой».

  1. Приложение вызывает метод сетевой службы и передаёт ей UDP-сокет и произвольный кусок байтов. Проверки разрешений на этом вызове нет ни в самом методе, ни в описании интерфейса, ни в политике безопасности.
  2. Система запоминает, кто вызвал, какая сеть, а также адреса и порты отправителя и получателя.
  3. Приложение завершается. Ядро сообщает, что сокет уничтожен.
  4. Системный процесс открывает новый сокет на физической сети Wi-Fi, подключает его к запомненному адресу и отправляет запомненные байты. VPN этого пакета не видит, а получатель видит настоящий адрес устройства.

Исследователь сообщил о находке через программу вознаграждений Android. Обращение закрыли с формулировкой Won't Fix (Infeasible) на том основании, что это не входит в модель угроз. Mullvad, который обычно не пишет о чужих багах, выпустил предупреждение в мае и подал заявку повторно через публичный трекер, после чего её пометили недоступной без объяснений. GrapheneOS выкатила исправление, отключающее оптимизацию.

Для этой дыры есть обходной приём, и он неудобный: при включённой отладке по USB команда adb shell device_config put tethering close_quic_connection -1 выключает аккуратное закрытие QUIC и закрывает утечку. Она переживает перезагрузку, но может слететь после обновления системы, и тогда её нужно повторить. Плата в том, что сокеты QUIC на дальней стороне остаются полуоткрытыми до таймаута.

Дыра вторая: пакет за вас шлёт сам Wi-Fi-чип

Вторая находка, опубликованная 29 июля Армином Шупуком и разобранная Mullvad 10 сентября, заходит в ту же комнату через другую дверь. Android даёт приложениям публичный интерфейс для поддержания NAT-трансляции: приложение просит систему периодически слать маленький UDP-пакет, чтобы соединение через домашний роутер не отвалилось. Ради экономии батареи работу спускают на Wi-Fi- или сотовый чип, и пакеты шлёт уже он.

Фреймворк принимает запрос, не проверив, что вызывающий действительно владеет ресурсом, на который указывает, и не спросив, распространяется ли на него блокировка VPN. Дальше пакеты рождаются в сетевом железе - ниже того уровня, где живут правила туннеля. Пакеты фиксированного вида на UDP-порт 4500 приходят по адресу, который выбрало приложение, и несут настоящий IP.

10 синтервал между утекающими пакетами, минимум платформы
24 ч 32 мсамая долгая непрерывная утечка на тестовом устройстве
3производителя подтверждены: Google, Samsung, Nothing
91%поставок Android приходится на затронутые семейства Wi-Fi-прошивок, по данным работы

В работе прослежено, как расползлась модель доверия. Вызов начинался как привилегированный интерфейс, принимавший сырой файловый дескриптор, оброс публичной точкой входа, получил проверку ресурса, а затем потерял её обратно при откате. То, что осталось, пропускает запрос, не требуя доказательств, что вызывающий чем-то владеет.

Собственная приписка автора в трекере GrapheneOS скромнее заголовка работы: на устройствах Pixel это работает по Wi-Fi и в основном не работает по IPv6. Зато держится крепко. Утечка продолжается при уходе приложения в фон, на заблокированном экране, в режиме Doze, в энергосбережении и под заморозкой процессов, и переживает принудительную остановку приложения.

Что именно утекает

Не переписка. Оба канала узкие: приложение управляет тем, куда уйдёт пакет, а в случае с QUIC - ещё и содержимым нескольких байтов. Дальняя сторона узнаёт, что конкретное устройство с конкретным публичным адресом существует и прямо сейчас в сети. Для приложения, которое и так знает, кто вы, это недостающее звено между аккаунтом и местоположением - ровно то, ради чего ставился VPN.

Почему это повторяется

Обе дыры выросли из одного решения: удобные функции, позволяющие системному процессу действовать от имени приложения, написаны без вопроса, а можно ли этому приложению в эту секунду вообще выходить в сеть напрямую. Проверка блокировки фильтрует идентификаторы приложений, поэтому всё, что делается под системным идентификатором, до неё не доходит.

И список не заканчивается на двух. В обсуждении у GrapheneOS сопровождающий проекта отметил, что нашёл и починил своими силами ещё как минимум десяток утечек, а утечки, которые случаются без злого умысла приложения, там считают более приоритетными, чем эти две. Он же прямо сказал про мотивацию: Google за утечки VPN не платит, и сообщать о них стоит ради документирования, а не в расчёте на исправление.

Что можно сделать

Стоит сделать

  • Считать установку приложений реальной точкой контроля. Обе атаки требуют, чтобы враждебное приложение уже стояло на устройстве, и ни одна ни о чём не спрашивает.
  • Если туннель нужен ради безопасности, а не ради удобства, взять сборку Android, где это чинят напрямую, например GrapheneOS.
  • Применить команду adb выше, если вы понимаете, что делаете, и повторять её после обновлений системы.
  • Помнить, что вторая утечка на проверенном железе тянется к Wi-Fi. По мобильной сети картина пока пестрее.

Не помогает

  • Сменить VPN-сервис. На Android задеты одинаково все приложения, потому что побег происходит ниже них.
  • Включить «Блокировать соединения без VPN». Это ровно та настройка, которую обходят.
  • Ждать патча от Google. Оба обращения закрыты.
  • Аварийный выключатель внутри VPN-приложения. Оно не видит и не остановит пакеты, которые шлёт система или Wi-Fi-чип.

Что это меняет при выборе VPN

Тут стоит быть точным в том, где вина, потому что реклама вокруг этого точной не будет. Ни один VPN-сервис обе утечки починить не может и ни один их не создал: пакеты не доходят до уровня приложений, где вообще работает VPN-клиент. Судить провайдера здесь разумно по одному - сказал ли он своим пользователям о проблеме. Если вы выбираете приложение для телефона, наш разбор VPN для Android о том, чем управляет само приложение, то есть обо всём, что выше этого уровня.

Это касается iPhone?
Нет. Обе находки относятся к сетевому стеку Android и к интерфейсам, которые Android отдаёт приложениям. Про iOS они не говорят ничего.
Какие версии Android затронуты?
Утечка через QUIC приехала вместе с функцией в Android 16 QPR1. Утечка через keepalive идёт по общему пути фреймворка начиная с Android 12, и в работе утверждается, что задето большинство устройств на Android 12 и новее.
Можно ли заметить, что приложение так делает?
С телефона - нет. Пакеты порождает система или сетевое железо, поэтому в счётчиках трафика по приложениям они не появляются. В своей сети их видно в перехвате на роутере: периодический UDP на порт 4500 с реального адреса телефона.
Виноват ли мой VPN-провайдер?
Нет. Трафик уходит ниже уровня, которым VPN-приложение управляет. Mullvad рассматривал обходной приём, занимающий все аппаратные слоты keepalive, и отказался: это означало бы слать пакеты мимо туннеля самому и всё равно не гарантировало бы победу в гонке с враждебным приложением.
Стоит ли перестать пользоваться VPN на Android?
Нет. Туннель по-прежнему несёт ваш настоящий трафик и по-прежнему прячет его от сети, в которой вы сидите. Он перестал гарантировать другое: что специально написанное враждебное приложение не выдаст ваш адрес отдельным каналом.

androidgooglevpnprivacysecuritymullvadgrapheneosip leakcybersecuritytracking

Читайте также