Вы блокируете приложение в брандмауэре VPN на Android, приложение перестаёт работать, а его строка расхода продолжает расти. Соблазнительный вывод — блокировка протекла или счётчик сломан. Ни одно не следует. Запись расхода говорит, что байты были отнесены к этой личности в некоторой точке наблюдения; она ничего не говорит о том, приняла ли удалённая служба запрос. Как только вы знаете, какая граница измерялась и какой личности это было отнесено, два наблюдения перестают противоречить друг другу.

Счётчик измеряет байты, а не доставку

Android относит трафик к UID и считает его в обоих направлениях, и делает это на границе интерфейса, а не в момент, когда запрос приложения завершается успешно.

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

Вот почему строка заблокированного приложения может расти, пока каждый запрос терпит неудачу. Счётчик отвечает на вопрос «сколько байтов отнесено к этой личности», а не «достигла ли эта личность интернета». График не может отличить принятый поток от вежливо отклонённого рукопожатия, и сумма, складывающая оба направления, тоже не может.

Привязка идёт за UID, а не за значком

Строка ведётся по UID, и один UID может использоваться несколькими пакетами, тогда как видимое приложение может передать работу отдельному компоненту, который работает под собственной личностью. Вкладка браузера, отрисовываемая общим процессом WebView, служба фоновой синхронизации или сопутствующий пакет, установленный рядом с основным приложением, — все они создают трафик, который экран расхода может показать под неожиданным для вас именем или под приложением, которое вы заблокировали. Заблокированный пакет и помощник, переносящий его запросы, — два разных субъекта, и правило охватывало только одного из них.

Когда числа выглядят неверно, сравнивайте UID, а не метку. API расхода запрашивается по UID, и adb shell dumpsys package <package> | grep userId= печатает число, с которым нужно сравнивать, поэтому две записи с одинаковым UID с точки зрения счётчика — одна и та же личность.

Временное окно может предшествовать вашему правилу

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

Используйте более короткое окно и чистый старт. Запишите отметку времени, когда меняете правило, подождите один интервал сбора, а затем смотрите только на данные после него. Если сумма продолжает расти в окне, начинающемся после правила, вам есть что исследовать; если рост прекратился, прежний рост был отображаемой историей.

Служба VPN может быть не той, которую вы настроили

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

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

adb shell settings get secure always_on_vpn_app
adb shell dumpsys connectivity
adb shell dumpsys netstats detail

Проверьте один свежий запрос и запишите четыре факта

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

Защитимое заключение называет, что было отклонено и какое наблюдение это подтвердило. «Счётчик вырос» — не находка, и «все счётчики расхода поддельные» тоже. Лозунг об уровне OSI этого не решает: честный ответ в том, что счётчик и блокировка могут быть одновременно верны, описывая разные вещи. Справочник Android NetworkStatsManager документирует, как эти корзины запрашиваются и относятся.

Похожие статьи