Краткий ответ
VPN-приложение на Android не является средством контроля исходящего трафика устройства. Это сетевая политика, которую операционная система применяет к идентификаторам приложений, и эта политика по замыслу не распространяется на системные процессы, на раздачу интернета и на ряд служебных соединений.
Параметр «Блокировать соединения без VPN» — то, что обычно называют kill switch или килл-свитч, — блокирует именно приложения. В исходном коде сетевой подсистемы Android сокеты, принадлежащие идентификаторам ниже FIRST_APPLICATION_UID — то есть системным компонентам, в частности system_server, radio и network_stack, — помечаются как PERMISSION_SYSTEM и вообще не проходят проверку доступа к сети. Им разрешена любая сеть, включая физический интерфейс Wi-Fi, независимо от состояния туннеля.
Это не ошибка и не недосмотр. Без такого исключения операционная система не смогла бы выполнять часть собственных функций. Но следствие для пользователя прямое: никакая настройка в телефоне не переведёт весь исходящий трафик в туннель, потому что механизм принуждения применяется не к устройству, а к приложениям.
Единственная конфигурация, в которой весь трафик телефона гарантированно инкапсулирован, выглядит так: сотовый модуль выключен, подключение только по Wi-Fi, а туннель поднят на маршрутизаторе. Тогда решение о маршрутизации принимает не телефон.
Как устроено принудительное направление трафика в Android
У каждого сокета в Android есть метка SO_MARK (fwmark), указывающая ядру, к какой сети он относится. Когда VPN поднимается, таблицы маршрутизации и правила netd для отдельных приложений переписываются так, что для заблокированных идентификаторов единственной доступной сетью становится туннель. Если приложение пытается привязать сокет напрямую к физическому интерфейсу Wi-Fi, вызов проходит через fwmark-сервер, тот вызывает checkUserNetworkAccess(), видит заблокированный идентификатор и возвращает EPERM.
Для приложений этот механизм работает. Исключение описано в system/netd/server/NetworkController.cpp двумя строками, которые и определяют всё дальнейшее:
return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
return 0; // разрешает доступ к ЛЮБОЙ сети, включая физический Wi-Fi
}
Системный компонент, отправляющий пакет, не проверяется на предмет того, поднят ли сейчас туннель и заблокирован ли сетевой доступ вне его. Проверка просто не выполняется.
Отсюда следуют две вещи. Первая: любой трафик, физически отправляемый системным процессом, покидает устройство мимо туннеля. Вторая: если приложение способно побудить системный процесс отправить пакет от своего имени, туннель обходится тоже — и именно этим оказался публично продемонстрированный в апреле 2026 года обход, описанный ниже.
Что официально выведено из-под туннеля
Самая точная формулировка принадлежит инженеру Google в ответе на обращение в трекер ошибок Android. Проверки подключения к интернету, по его словам, далеко не единственное, что выведено из-под VPN: привилегированные приложения также могут обходить туннель, и для многих из них это необходимо для работы; в качестве примера названы IWLAN и трафик раздачи интернета.
Разберём эти категории.
Проверки подключения к интернету. Android выполняет их при каждом подключении к сети Wi-Fi, чтобы обнаружить captive-портал. Это было публично задокументировано в 2022 году: проверки выходят мимо туннеля даже при включённом «Блокировать соединения без VPN», и вместе с ними наружу идут DNS-запросы, HTTP- и HTTPS-трафик и, вероятно, NTP. Google закрыл обращение с формулировкой об ожидаемом поведении. В том же обращении отдельно отмечалось, что название самого переключателя и документация к нему вводят пользователя в заблуждение, поскольку создают впечатление, будто устройство не отправляет ничего вне туннеля.
Здесь GrapheneOS даёт реальное преимущество перед заводской Android: проверки подключения можно переключить на сервер GrapheneOS или отключить полностью в разделе «Network & internet». Это независимо проверено: с отключёнными проверками описанной утечки не наблюдается.
IWLAN, то есть звонки через Wi-Fi. Службы VoLTE, VoNR, VoWi-Fi, RCS, MMS, SMS поверх LTE и визуальная голосовая почта реализованы преимущественно самой операционной системой поверх TCP/IP, а не сотовым уровнем. Это означает собственные соединения операционной системы к серверам оператора через подсистему IMS и домены 3gppnetwork.org. Эти соединения принадлежат системным идентификаторам, и туннель приложения их не охватывает. GrapheneOS меняет конфигурацию оператора так, чтобы переключатели отключения VoLTE, VoNR и VoWi-Fi были доступны всегда — но это отключение службы, а не её перевод в туннель.
Раздача интернета. Вынесена в отдельный раздел ниже.
Привилегированные приложения в целом. Формулировка Google не ограничена перечнем. Это категория, а не список, и она может меняться между версиями.
Раздача интернета никогда не попадает в туннель
Это самая частая практическая неожиданность. Телефон с поднятым туннелем раздаёт Wi-Fi или USB, подключённый ноутбук проверяет свой внешний адрес — и видит адрес оператора, а не выходного узла VPN. Когда туннель на телефоне разрывают, браузер телефона перестаёт открывать страницы, а ноутбук продолжает работать как ни в чём не бывало.
Причина не в ограничении ядра Linux, как иногда предполагают, а в архитектуре сетевой подсистемы AOSP. VPN в Android действует в границах профиля пользователя: туннель принадлежит профилю и распространяется на приложения этого профиля. Подключённый ноутбук, планшет или телевизор не относятся ни к одному профилю на телефоне, поэтому ни один туннель телефона их не охватывает.
Пересылку трафика раздачи выполняют системные компоненты, а они, как показано выше, помечаются как PERMISSION_SYSTEM и проверку доступа к сети не проходят. Именно поэтому раздачу интернета и назвали в перечне исключений рядом с IWLAN: она выведена из-под туннеля на том же архитектурном уровне.
Механизма, который направил бы трафик раздачи в туннель профиля, в AOSP нет. Это не спрятанная где-то настройка и не свойство конкретной сборки: интерфейс VPN-приложений такой возможности не предусматривает вообще, поэтому и ни одна операционная система на базе AOSP не может предоставить её средствами этого интерфейса. Реализация потребовала бы собственного туннеля внутри операционной системы, способного выдавать каждому подключённому устройству отдельный маршрут.
Обходные средства существуют, но требуют root-доступа: они вставляют собственные правила маршрутизации в промежуток между приоритетами локальной сети и раздачи интернета. Root на Pixel требует разблокированного загрузчика, что отключает проверенную загрузку. Мы не применяем это на устройствах и не рекомендуем.
Отдельно стоит знать ещё одно: сам факт раздачи заметен оператору даже тогда, когда подключённое устройство поднимает собственный туннель, — в частности, из-за различий в значении TTL у пакетов, прошедших через дополнительный узел.
Утечки DNS
Разрешение доменных имён является отдельной подсистемой со своей историей проблем.
Независимые исследователи задокументировали в 2024 году несколько сценариев, в которых Android отправляет DNS-запросы мимо туннеля: когда VPN активен, но сервер DNS в нём не настроен, и в течение короткого промежутка, пока приложение перенастраивает туннель, аварийно завершается или принудительно останавливается. Утечки касаются прямых вызовов функции getaddrinfo и воспроизводились именно на приложении WireGuard, которое считают эталонной реализацией VPN для Android. Ключевая деталь: это происходит независимо от состояния «Постоянная VPN» и «Блокировать соединения без VPN».
GrapheneOS устраняет часть этих сценариев. Проект прямо описывает, что Android допускает утечку запросов системного разрешителя к серверам DNS сети через состояние гонки, когда VPN-приложение прекращает работу, и точно так же допускает соединения к серверам DNS самого туннеля вне туннеля; оба случая в GrapheneOS устранены расширением блокировки на эту часть системного разрешителя.
Есть и конфигурационная ловушка. Private DNS имеет приоритет над серверами DNS, которые предоставляет туннель, поскольку с точки зрения системы это серверы сети. Поэтому GrapheneOS рекомендует не держать Private DNS настроенным одновременно с VPN, а для вторичных профилей настаивает на полном отключении Private DNS до переработки этой подсистемы. Комбинация, которую пользователь включает из соображений приватности, в этом случае работает против него.
Ошибки реализации появляются регулярно
Кроме категорий, выведенных из-под туннеля намеренно, существуют ошибки. Свежий и показательный пример опубликован 30 апреля 2026 года.
В Android 16 появился механизм корректного завершения соединений QUIC: приложение может заранее зарегистрировать кадр CONNECTION_CLOSE, который операционная система отправит от его имени, когда сокет будет закрыт. Метод registerQuicConnectionClosePayload в ConnectivityManager принимает произвольный массив байтов и не проверяет ни разрешений вызывающего, ни содержимого переданных данных, ни того, заблокирован ли вызывающему сетевой доступ вне туннеля. Отправляет данные system_server, который, как показано выше, от проверок освобождён.
Результат: обычное приложение, имеющее лишь два разрешения, выдаваемые автоматически, отправляет произвольные байты на произвольный адрес мимо активного туннеля и раскрывает настоящий адрес устройства. Проверено на Pixel 8 с Android 16 и включёнными «Постоянная VPN» и «Блокировать соединения без VPN». Команда безопасности Android закрыла отчёт с пометкой «Won’t Fix (Infeasible)», а после апелляции решение не изменила. GrapheneOS, напротив, исправил это в собственной кодовой базе.
Это не единичный случай. GrapheneOS перечисляет на странице с описанием возможностей ещё несколько классов обхода, которые исправил самостоятельно: отправку многоадресных пакетов напрямую или через системные вызовы управления группами многоадресной рассылки, что позволяло приложениям обходить туннель независимо от того, поднят он или нет; возможность отправить многоадресные пакеты через туннель, принадлежащий другому профилю; дыру в фильтрации на базе eBPF, которая позволяла обойти туннель, указав конкретный интерфейс отдельным системным вызовом.
И самое важное в этом перечне — собственная оценка проекта. GrapheneOS отмечает, что поиск и устранение всех форм утечек VPN является одним из приоритетов на данный момент и что функция пока не считается завершённой из-за дополнительно обнаруженных проблем. Это честная позиция команды, которая сделала в этой области больше кого бы то ни было, и именно поэтому её стоит читать буквально.
Отдельно о приложении WireGuard на Pixel
Теперь о конкретном сценарии из вопроса.
Официальное приложение WireGuard для Android использует реализацию в ядре, если она доступна, и использует реализацию в пространстве пользователя, если нет. Доступ к модулю ядра требует root. На Pixel с GrapheneOS root отсутствует, поэтому приложение всегда работает в пространстве пользователя — то есть через реализацию на языке Go поверх того же механизма VpnService, со всеми описанными выше ограничениями.
Дальше идёт специфичная для GrapheneOS деталь. Проект рекомендует очень короткий перечень VPN-приложений и отмечает, что аппаратная маркировка памяти обнаруживает некорректные обращения к памяти именно в официальном приложении WireGuard — в отличие от другого приложения из этого перечня, которое проверено на GrapheneOS с включённой маркировкой памяти. Отдельно GrapheneOS сообщал, что пользователи неоднократно находили ошибки работы с памятью в приложениях на базе WireGuard под Android, и предполагал, что большинство из них происходит от среды выполнения Go.
Маркировка памяти включается для установленных пользователем приложений на Pixel восьмого поколения и новее. То есть включение одной из ключевых функций защиты GrapheneOS повышает вероятность аварийного завершения именно того приложения, которое держит туннель. А аварийное завершение VPN-приложения — это ровно то условие, при котором и зафиксированы описанные выше утечки DNS.
Это не аргумент против WireGuard как протокола. Это аргумент против конструкции, в которой целостность всей сетевой защиты устройства зависит от непрерывной работы одного приложения в пространстве пользователя.
Чего VPN на телефоне не делает в принципе
Даже если бы все перечисленные утечки были устранены, остаётся граница, которую VPN не пересекает по определению. Туннель работает на сетевом уровне. Всё, что происходит на радиоуровне, лежит вне его.
С установленной SIM-картой и включённым сотовым модулем телефон регистрируется в сети оператора независимо от состояния туннеля. Оператор видит IMSI, IMEI, время регистрации и местонахождение с точностью до соты. Никакой VPN на это не влияет. Мы разбирали смежную тему в материале об IMEI на Google Pixel.
Службы IMS добавляют к этому собственные соединения к серверам оператора, и, как отмечено выше, они идут мимо туннеля.
Итак, VPN на телефоне отвечает на вопрос «кто видит содержимое и назначение моего IP-трафика». Он не отвечает на вопрос «кто знает, что этот аппарат сейчас включён и где он находится».
Конфигурация без утечек: Wi-Fi и маршрутизатор с туннелем
Конфигурация, которую мы рекомендуем, когда задача состоит именно в том, чтобы ни один пакет не покинул устройство вне туннеля, складывается из двух условий.
Первое: сотовая связь выключена. Режим полёта отключает приём и передачу сотовой радиочасти, после чего Wi-Fi включается отдельно. Это устраняет и регистрацию в сети оператора, и трафик IMS, и сам канал, по которому утечки выходили бы наружу. Если SIM-карта остаётся в аппарате и включены звонки через Wi-Fi, телефон продолжит регистрироваться у оператора через Wi-Fi — поэтому звонки через Wi-Fi следует отключить или вынуть SIM-карту.
Второе: туннель поднят на маршрутизаторе. Маршрутизатор инкапсулирует всё, что выходит через его внешний интерфейс. Здесь нет ни политики на уровне идентификаторов приложений, ни исключений для системных процессов, ни профилей пользователя — потому что решение о маршрутизации принимает устройство, не имеющее ни одного из этих понятий. Kill switch реализуется правилом межсетевого экрана, а не политикой операционной системы: если туннель не поднят, у пакетов просто нет маршрута наружу.
Что эта конфигурация не делает, и об этом следует сказать прямо:
- Она не скрывает телефон от того, кто управляет маршрутизатором и точкой доступа. Точка доступа видит MAC-адрес устройства, запросы DHCP и объём трафика.
- Она не останавливает телеметрию приложений. Туннель меняет маршрут, а не содержимое.
- Проверки подключения к интернету никуда не исчезают — они просто идут внутри туннеля, как и остальной трафик.
То есть это решение задачи «ноль утечек мимо туннеля», а не задачи «анонимность».
Заключение
VPN-приложение на Pixel с GrapheneOS не является средством контроля исходящего трафика устройства, потому что механизм принуждения в Android применяется к идентификаторам приложений, а системные идентификаторы исключены из него на уровне сетевой подсистемы. Это не ошибка конкретной сборки и не свойство конкретного приложения.
Категории, выведенные из-под туннеля по замыслу, подтверждены самим Google: проверки подключения к интернету, привилегированные приложения, IWLAN и раздача интернета. Раздача интернета не попадает в туннель никогда, и механизма, который это изменил бы, в AOSP нет. Утечки DNS в сценариях перенастройки и аварийного завершения задокументированы на официальном приложении WireGuard. Ошибки реализации, позволяющие обойти туннель, появляются регулярно, и сам GrapheneOS не считает эту часть работы завершённой.
Конфигурация без утечек одна: сотовая связь выключена, подключение только по Wi-Fi, туннель поднят на маршрутизаторе. В ней телефон вообще не принимает решений о маршрутизации, значит, и обходить их нечему.
Приложение VPN в телефоне при этом не бесполезно. Оно уместно как второй слой внутри маршрутизаторного туннеля и как средство для тех случаев, когда контролируемого маршрутизатора нет под рукой. Оно просто не является тем, чем его считают.
Pixel 8, Pixel 9 и Pixel 10 с GrapheneOS. Мы подбираем модель под вашу модель угроз, устанавливаем GrapheneOS, блокируем загрузчик и передаём устройство с полным руководством по эксплуатации. Подробнее о GrapheneOS →
Связанные материалы: IMEI на Google Pixel · Pixel с GrapheneOS.
Источники
Архитектура принуждения и системное исключение
- «The Tiny UDP Cannon: An Android VPN Bypass», 30.04.2026 — разбор registerQuicConnectionClosePayload, исходный код NetworkController.cpp и QuicConnectionCloser.java, хронология раскрытия. — lowlevel.fun
- Android Issue Tracker, обсуждение 234170605 — ответ инженера Google о том, что проверки подключения далеко не единственное, что выведено из-под VPN, с примерами IWLAN и раздачи интернета. Просмотр трекера может потребовать входа в аккаунт Google. — issuetracker.google.com
- Android Developers, «VPN» — описание VpnService, режима постоянного подключения и поведения при включённой блокировке соединений вне туннеля. — developer.android.com
Проверки подключения к интернету
- Android Issue Tracker, обращения 250529027 (утечка) и 249990229 (документация).
Раздача интернета
- Отчёт 2145 «Hotspot traffic is not routed through (Wireguard) VPN» — воспроизведение поведения и объяснение того, что VPN в Android действует в границах профиля пользователя. — github.com
DNS
- Публичное раскрытие сценариев утечки DNS в Android, 2024 — утечки воспроизведены на официальном приложении WireGuard.
- GrapheneOS, FAQ, разделы о DNS, Private DNS и поддержке VPN. — grapheneos.org
Меры GrapheneOS и собственная оценка состояния
- GrapheneOS, Features, раздел «Improved VPN leak blocking» — перечень закрытых классов обхода и замечание, что функция не считается завершённой. — grapheneos.org
- GrapheneOS, FAQ, «What kind of VPN and Tor support is available?» — рекомендуемые приложения и замечание о маркировке памяти. — grapheneos.org
- GrapheneOS, публикация от 28.09.2024 об ошибках работы с памятью в приложениях на базе WireGuard. — grapheneos.social
Реализация WireGuard для Android
- wireguard-android, описание проекта: использует реализацию в ядре при наличии, иначе — реализацию в пространстве пользователя без root. — git.zx2c4.com
Сотовый уровень и IMS
- GrapheneOS, FAQ, «What are the default connections?» — MMS, RCS, SMS поверх LTE, VVM, VoLTE, VoNR и VoWi-Fi реализованы операционной системой поверх TCP/IP через IMS. — grapheneos.org
- GrapheneOS, FAQ, «Is the baseband isolated?» — grapheneos.org