Представьте: вы подключились к рабочему VPN – нужно зайти на корпоративный сервер или проверить доступность сервиса из другой юрисдикции. Потом, не выключая его, открыли приложение популярного маркетплейса – проверить, прибыл ли в пункт выдачи корм для почтовых воробьев. В этот момент приложение тихо просканировало localhost, нашло SOCKS5-порт вашего VPN-клиента, отправило через него запрос и узнало выходной IP вашего сервера. Завтра этот IP окажется в блэклисте. Сервер, за который вы или ваша компания платите $5 в месяц, вдруг внезапно деградировал. А вы даже не узнаете, кто вас сдал.

коллеги пытаются понять, почему
коллеги пытаются понять, почему

Эта статья о том, как я решил эту проблему. Не теоретически, а в виде работающего open-source приложения.

Anubis на GitHub – код, APK и инструкция по настройке. А ниже – как это устроено под капотом.

Предыстория

В апреле 2026 года Минцифры разослало крупнейшим российским площадкам методичку по обнаружению VPN-трафика. Компании получили конкретные инструкции: как выявлять VPN, как ограничивать доступ пользователям, и как передавать обнаруженные IP-адреса VPN-серверов в РКН для последующей блокировки.

Фактически каждое крупное российское приложение теперь потенциально содержит модуль, который:

  • определяет наличие VPN через ConnectivityManager

  • проверяет доступность заблокированных ресурсов

  • передаёт IP-адреса VPN-серверов для блокировки

Это не теория - статья Российский мессенджер MAX замечен в обращении к иностранным сервисам определения IP и серверам конкурентов описывает то, как обнаружили подобное поведение, статья “Месседжер MAX следит за пользователями VPN? Реверс инжиниринг говорит - да” показала конкретные обращения к серверам Telegram и WhatsApp для определения обхода блокировок.

Параллельно была обнаружена критическая уязвимость во всех популярных VLESS-клиентах: они поднимают локальный SOCKS5 прокси без авторизации, через который любое приложение на устройстве может узнать выходной IP VPN-сервера. Другой автор на Хабре, @Wendor, предложил решение на стороне VPN-клиента – свой клиент TeapodStream с рандомным портом и авторизацией SOCKS5. Шпион больше не может воспользоваться прокси. Но сам факт наличия VPN (tun0, маршруты) от его взгляда это не скрывает – как выяснилось в комментариях к той статье, шпион может биндиться напрямую к tun0 через SO_BINDTODEVICE и всё равно узнать выходной IP. Так что это закрывает один конкретный вектор, но не все.

На фоне всего этого на Хабре появилась статья с предложением использовать Island/Insular для изоляции приложений. В комментариях развернулась дискуссия о том, насколько это реально защищает. Позже тот же автор опубликовал продолжение – красивое серверное решение в виде трёхкаскадного VPN. Ключевой трюк: точка входа внутри РФ скрыта (трафик к ней выглядит как обычный межсервисный), а выходной узел и вовсе находится вне юрисдикции блокировок. Если шпион и сдаст выходной IP – РКН его забанит, но это не сломает схему: между российским трафиком и выходом стоит ещё один заграничный узел, и бан никакой цепочки не разрывает. Схема работает дальше как ни в чём не бывало. Подход серверный и устойчивый.

В первой версии этой статьи я описал его схему как "ротационную" – мол, выходные узлы быстро заменяются после банов. @linux-over справедливо поправил в личке: ничего заменять не нужно, схема живёт дальше как была. Этот абзац переписан.

Я решил зайти с другой стороны – со стороны клиента: вообще не дать шпиону ничего узнать, отключив его до включения VPN.

Песочница: что она реально даёт, а что нет

Идея простая: помещаем приложения в рабочий профиль Android, и они не видят VPN. Insular (форк Island) - это приложение-песочница, создающее рабочий профиль.

Как работает рабочий профиль под капотом

Рабочий профиль - это отдельный пользователь Android (например, user 10), привязанный к основному (user 0). Приложения не клонируются: APK один, но у каждого профиля своя директория данных (/data/user/0/ vs /data/user/10/). Изолированы: файлы, контакты, аккаунты, буфер обмена, хранилище ключей. Не изолирована: сеть.

Что песочница действительно скрывает

Автор статьи про Island утверждает, что Т-Банк после помещения в песочницу “перестал жаловаться на VPN”. Проверка показала, что это правда - и вот почему:

ConnectivityManager в Android фильтрует сети по userId. VPN, созданный в user 0, не виден через ConnectivityManager.getAllNetworks() из user 10 (рабочего профиля). Это framework-level фильтр в ConnectivityService - не ядерная изоляция, а программная. Но для приложений, которые проверяют VPN простейшим способом (а таких большинство), этого достаточно:

// Этот код из рабочего профиля НЕ увидит VPN основного профиля
val cm = getSystemService<ConnectivityManager>()
val vpnActive = cm.allNetworks.any {
    cm.getNetworkCapabilities(it)
        ?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
}
// vpnActive == false, хотя VPN включён
Что такое ConnectivityManager

ConnectivityManager - системный сервис Android для информации о сетевых подключениях. Любое приложение с разрешением ACCESS_NETWORK_STATE (есть практически у всех, не требует подтверждения) может спросить систему: "есть ли VPN?". В рамках одного профиля система ответит честно. Но между профилями - фильтрует. Это задокументированное поведение Android, не баг.

Так что песочница - не бесполезна. Она закрывает самый простой и распространённый вектор детектирования.

Что песочница НЕ скрывает

Проблема в том, что сетевой стек Android - один на всё ядро. Рабочий профиль не использует Linux network namespaces (хотя ядро их поддерживает - на этом построены Docker и LXC). Это значит, что из рабочего профиля доступны три канала утечки:

Что видит приложение из рабочего профиля

Как проверяет

Нужны права?

Интерфейс tun0

NetworkInterface.getNetworkInterfaces()

Нет

Маршрут через tun0

/proc/net/route

Нет

SOCKS5 прокси на localhost

Подключение к 127.0.0.1:<port>

Нет

Все три проверки работают без каких-либо разрешений. SOCKS5 на localhost - самая опасная: приложение в рабочем профиле может не просто обнаружить VPN, но и воспользоваться им, узнав выходной IP-адрес сервера.

Утилиты YourVPNDead и RKNHardering проверяют все каналы, а не только ConnectivityManager - поэтому они успешно детектят VPN из любого рабочего профиля: Island, Insular, Knox, Shelter, второе пространство Xiaomi.

А методичка Минцифры явно описывает проверку характерных портов прокси: SOCKS (1080, 9000, 5555), HTTP (3128, 8080), Tor (9050). Именно те проверки, от которых рабочий профиль не защищает.

Возможна ли полноценная сетевая изоляция на Android?

Может, Google просто доделает изоляцию? На настольных ОС виртуализация (VirtualBox, QEMU, Hyper-V) создаёт гостевую систему с собственным сетевым стеком. Гостевая ОС не видит VPN хоста – это настоящая изоляция. Linux-ядро, на котором построен Android, тоже так умеет – через network namespaces.

Но Android не пользуется network namespaces для профилей. VpnService, ConnectivityManager и весь сетевой фреймворк не рассчитаны на per-profile сетевую изоляцию. Чтобы песочница реально изолировала сеть, Google пришлось бы переработать сетевую подсистему. Этого нет, и в обозримом будущем не предвидится.

А что на других платформах?

**На ПК** проблема решается тривиально: помещаем приложения, которым не доверяем, в виртуальную машину (VirtualBox, QEMU). Даже если VPN на хосте работает в TUN-режиме и перехватывает весь трафик -- гостевая ОС в режиме NAT этого не видит. Трафик гостя пойдёт через VPN хоста, но гость видит только свою виртуальную сетевую карту. У него нет доступа к интерфейсам хоста (tun0, wg0 и т.д.), к его таблице маршрутизации, к списку адаптеров. Факт наличия VPN для него невидим. Это полноценная изоляция. **На iOS** ситуация хуже, чем на Android: нет даже рабочих профилей, нет per-app VPN для произвольных приложений. Единственный вариант -- второй телефон. **На Android** полноценной виртуализации нет, но есть другой механизм -- полное отключение приложения на уровне системы. Об этом ниже.

Проблема глубже: фоновая активность

Но допустим, чудо произошло и Google добавил настоящую сетевую изоляцию для профилей. Спасло бы это нас? Нет.

Android архитектурно позволяет приложениям вести активность без явного действия пользователя. BroadcastReceiver, JobScheduler, WorkManager, push-уведомления через FCM – всё это запускает код приложения в фоне. Приложение, которое вы запустили два дня назад и давно свернули, продолжает жить: получает события, обрабатывает данные, отправляет запросы.

Это не баг, а “by design”. Android построен вокруг модели, где приложения реагируют на системные события. Но эта же модель означает, что приложение в любой момент может:

  • проверить состояние VPN

  • просканировать открытые порты на localhost

  • отправить HTTP-запрос к произвольному серверу

  • передать собранную информацию

Агрессивное энергосбережение (Doze mode, App Standby, OEM-оптимизации) может замедлить эту активность, но не гарантирует её полного отсутствия. Системные приложения и приложения, которым вы разрешили работу в фоне, вообще не подпадают под ограничения. А банковские приложения, маркетплейсы, мессенджеры – чаще других просят разрешить работу в фоне, потому что иначе пользователи жалуются на задержку уведомлений.

Песочница от фоновой активности не защищает – приложение в рабочем профиле работает точно так же, как в основном. Единственный способ гарантированно закрыть все векторы утечки – сделать так, чтобы приложение не существовало в системе в момент, когда VPN активен.

Итого по песочнице

Рабочий профиль – не бесполезен, но недостаточен:

  • Скрывает VPN от ConnectivityManager – работает против простых проверок (банковские приложения, Т-Банк)

  • Не скрывает tun0, маршруты и SOCKS5 – не работает против продвинутых проверок (методичка Минцифры, YourVPNDead)

  • Не блокирует фоновую активность – приложение продолжает сканировать сеть, даже если вы его не открывали

  • Имеет встроенную заморозку отдельных приложений и целого профиля (“Pause work apps”) – но это всё ещё ручное действие

  • Полноценная сетевая изоляция на Android невозможна архитектурно – и ждать её от Google не приходится

Единственный гарантированный способ запретить приложению любую активность – полностью его отключить. Отключённое приложение не может проверить VPN, просканировать порты или отправить запрос – его просто не существует в системе. В Island, кстати, тоже есть кнопка «заморозить» – и замороженное приложение точно так же мертво и, следовательно, безопасно. Но в Island вы делаете это вручную. Забыли заморозить перед включением VPN – всё, данные утекли.

Нам нужно не просто отключать приложения – нам нужно делать это автоматически, по состоянию VPN. Но сначала разберёмся, как вообще отключить произвольное приложение на Android.

Заморозка вместо изоляции

Кнопка «Отключить» – она уже существует

Android уже умеет полностью отключать приложения – но прячет эту возможность. Если вы зайдёте в Настройки → Приложения и откроете какое-нибудь предустановленное системное приложение (например, Google Фото или YouTube), вы увидите кнопку “Отключить”. Нажатие на неё полностью останавливает приложение: оно больше не запускается, не работает в фоне, не получает уведомления, его иконка пропадает из лаунчера.

Это именно то, что нам нужно. Отключённое приложение не может ничего детектить - оно мертво.

Но есть подвох: для приложений, установленных пользователем (а не предустановленных), этой кнопки нет. Для них Android предлагает только “Удалить”. Это ограничение интерфейса, не системы - под капотом механизм отключения работает для любых приложений. Просто Android не даёт к нему доступ через UI.

pm disable-user: та самая кнопка, но для всех

Системная команда pm disable-user делает то же самое, что кнопка “Отключить”, но для любого приложения:

pm disable-user --user 0 com.example.app

pm - это Package Manager, встроенный в каждый Android. disable-user отключает приложение для пользователя. --user 0 - основной профиль. com.example.app - имя пакета (например, ru.sberbankmobile для Сбера).

После этой команды приложение:

  • не имеет процесса в системе

  • не может запустить Service, BroadcastReceiver, ContentProvider

  • не получает Intent’ы и push-уведомления

  • не может обратиться ни к какому API, включая ConnectivityManager

  • не может просканировать localhost порты и отправить HTTP-запрос

  • иконка пропадает из лаунчера

Это не изоляция, а анабиоз. Приложение мертво на уровне PackageManager. Обратная операция – pm enable <package> – оживляет его мгновенно. Дальше в статье я буду называть это «заморозкой» – отключение, заморозка, «приложение мертво» означают одно и то же: pm disable-user.

Проблема доступа: ADB и его ограничения

Команда pm disable-user требует повышенных привилегий - уровня shell (UID 2000). На обычном Android приложения работают в своей “песочнице” и такие команды выполнять не могут.

Стандартный способ получить shell-доступ - ADB (Android Debug Bridge). Вы подключаете телефон к компьютеру по USB, устанавливаете Android SDK и выполняете:

adb shell pm disable-user --user 0 com.example.app

Это работает, но неудобно: нужен компьютер, USB-кабель, и каждый раз вводить команды вручную. Автоматизировать заморозку при включении VPN таким способом невозможно.

Если хочется попробовать заморозку без Anubis и Shizuku

Для тех, кто хочет просто поиграться с `pm disable-user` без командной строки, есть [ADB AppControl](https://adbappcontrol.com/) -- десктопный GUI для ADB (Windows, есть портативная версия). Подключаете телефон по USB, получаете список всех приложений и отключаете/включаете в один клик. Самый дружелюбный способ познакомиться с возможностями ADB. Но ограничения те же: всё привязано к ПК, USB-кабелю и ручному действию -- автоматически по состоянию VPN замораживать нельзя.

Shizuku: ADB без компьютера

Shizuku решает эту проблему. Это приложение, которое один раз запускается с правами shell (через ADB или Wireless Debugging на Android 11+), а потом предоставляет эти права другим приложениям - прямо на телефоне, без компьютера.

После настройки Shizuku любое приложение с его разрешением может выполнять shell-команды: pm disable-user, pm enable и другие - всё, что доступно в adb shell. Какие именно команды и зачем - станет понятно дальше.

Критически важно: Shizuku - не root. Он не ломает Knox, не теряет гарантию, не вызывает проблем с банковскими приложениями и проверками SafetyNet/Play Integrity. Shell-доступ - привилегии ADB, а не суперпользователя. Shizuku нужно перезапускать после перезагрузки телефона (или настроить автозапуск). Его используют десятки приложений - это зрелый инструмент с открытым исходным кодом.

⚠️ Нюанс с китайскими приложениями. В комментарии к этой статье читатель сообщил, что после установки Shizuku у него безвозвратно заблокировали аккаунт WeChat. Сам Shizuku ничего не инжектит в чужие процессы, но некоторые китайские приложения (WeChat, Alipay, UnionPay и родственные) агрессивно сканируют список установленных пакетов и могут расценить наличие ADB-инструмента как “модифицированное устройство”. Если такие приложения вам нужны – лучше держать их на отдельном устройстве без Shizuku.

Бонус: не только безопасность

Инструменты для заморозки давно существуют: Hail, IceBox. Замороженные приложения не расходуют заряд батареи, не занимают RAM, не создают фоновый трафик, не шлют уведомления – пользователь получает бонус к автономности и производительности. Но в этих инструментах триггером был “приложение мне редко нужно”. Теперь триггер другой: состояние VPN-подключения.

По степени защиты pm disable-user уступает только одному варианту - второму телефону, где потенциально опасные приложения физически находятся на другом устройстве. Но второй телефон - это неудобство, расходы и необходимость носить два устройства. Заморозка даёт 99% той же защиты на одном устройстве, без побочных эффектов.

Так появился Anubis - менеджер приложений, который автоматически связывает заморозку с состоянием VPN.

Архитектура Anubis

Три группы приложений

Вместо бинарного “заморозить / не заморозить” - три группы с разной сетевой политикой:

Группа

Состояние приложения по умолчанию

При запуске из Anubis

Без VPN

Заморожено

Выключает VPN → размораживает → запускает

Только VPN

Заморожено

Включает VPN → размораживает → запускает

Запуск с VPN

Активно

Включает VPN → запускает

“Без VPN” и “Только VPN” – всегда заморожены по умолчанию. Размораживаются только при явном запуске из Anubis или через ярлык. При смене состояния VPN – замораживаются обратно: включили VPN – заморозились приложения “Без VPN”, выключили – заморозились “Только VPN”.

“Запуск с VPN” – для приложений, которые морозить нет смысла (браузер, Telegram, YouTube), но которым для стабильной работы требуется VPN-подключение. Они живут как обычные приложения, получают пуши, но при запуске из Anubis автоматически поднимается VPN.

Таким образом, приложения “Без VPN” и “Только VPN” живут в постоянном анабиозе и оживают только по вашему явному запросу.

Главный экран: серые иконки -- замороженные приложения, цветные -- активные
Главный экран: серые иконки -- замороженные приложения, цветные -- активные

По сути, инверсия привычной модели Android: вместо “приложения работают всегда, если пользователь не вмешался” – “приложения мертвы всегда, если пользователь не запросил иное”.

Осознанный trade-off: замороженное приложение не получает push-уведомления. Если банк в группе “Без VPN” заморожен, пуш о переводе не придёт, пока вы не запустите его через Anubis. Такова цена за безопасность: либо приложение молчит и не шпионит, либо живёт и потенциально сливает данные. Anubis выбирает первое - а уведомления вы увидите, когда осознанно откроете приложение. Да и многие ли приложения шлют вам ВАЖНЫЕ пуши? Да и нейроресурс тоже стоит беречь.

Shizuku: shell-доступ без root

Чтобы вся эта оркестрация с заморозкой работала автоматически, нужен надёжный способ дёргать pm disable-user прямо из приложения. Anubis использует Shizuku (о котором мы говорили выше) – конкретно AIDL UserService паттерн из API 13.

// IUserService.aidl - выполняется в процессе Shizuku с правами shell
interface IUserService {
    void destroy() = 16777114;
    int execCommand(in String[] command) = 1;
    String execCommandWithOutput(in String[] command) = 2;
}
Почему AIDL, а не Shizuku.newProcess()

В Shizuku v13 метод `newProcess()` стал приватным. Вместо него используется паттерн UserService: мы определяем AIDL-интерфейс, реализуем его в классе `UserService`, который запускается в процессе Shizuku с правами shell. Связь через `Shizuku.bindUserService()`. UserService выполняет команды через `Runtime.getRuntime().exec()` - те же команды, что вы набираете в `adb shell`.

UserService инициализируется один раз в Application.onCreate() и живёт, пока работает приложение. Все компоненты (Activity, TileService, ShortcutActivity) используют один и тот же экземпляр. Это критично для отзывчивости - никаких задержек на подключение к Shizuku при каждом действии.

Управление VPN-клиентами

Anubis умеет запускать VPN-клиенты через shell-команды:

Клиент

Метод

Команда

v2rayNG

Toggle (widget broadcast)

am broadcast -a com.v2ray.ang.action.widget.click

NekoBox

Start/Stop (exported Activity)

am start -n moe.nb4a/...QuickEnableShortcut

Happ

Toggle (widget broadcast)

am broadcast -a com.happproxy.action.widget.click

v2rayTun

Toggle (widget broadcast)

am broadcast -a com.v2raytun.android.action.widget.click

V2Box

Toggle (widget broadcast)

am broadcast -a dev.hexasoftware.v2box.action.widget.click

Любой другой

Ручной

Открывает приложение

Toggle - та же команда, что отрабатывает при нажатии на виджет клиента на рабочем столе: если VPN выключен - включить, если включён - выключить. NekoBox - исключение: у него отдельные Activity для включения и выключения.

Что такое am broadcast и am start

`am` - Activity Manager, системная утилита Android. `am broadcast` отправляет broadcast Intent - сообщение, на которое может отреагировать любое зарегистрированное приложение. Так работают виджеты на рабочем столе: при нажатии на виджет VPN-клиента, система отправляет broadcast, а клиент его получает и включает/выключает VPN. Мы делаем то же самое, но из командной строки через Shizuku. `am start` запускает Activity - экран приложения. У NekoBox есть специальные Activity для включения и выключения VPN, которые не показывают UI, а просто выполняют действие и закрываются. Обе команды доступны через `adb shell` или через Shizuku с правами shell.

Пользователь также может выбрать любое установленное приложение в качестве VPN-клиента - оно будет работать в ручном режиме (Anubis открывает его для включения, а для выключения использует механизмы, описанные ниже).

Определение активного VPN-клиента

Пользователь может включить VPN не только через Anubis, но и напрямую из клиента – открыть v2rayNG и нажать кнопку. Чтобы интерфейс Anubis честно показывал, какой именно клиент сейчас держит VPN (а не только тот, что выбран в настройках), нужен способ спросить об этом у системы. Плюс эта же информация помогает в крайнем случае – когда dummy VPN не сработал и приходится делать am force-stop конкретного процесса.

Система знает, какое приложение владеет VPN-сетью. Мы извлекаем это через Shizuku:

dumpsys connectivity | grep -A 30 'type: VPN\[' | grep -oE 'OwnerUid: [0-9]+'
Что такое dumpsys и UID

`dumpsys` - диагностическая утилита Android, которая выводит внутреннее состояние системных сервисов. `dumpsys connectivity` показывает все сетевые подключения, включая VPN. Для каждого подключения система хранит UID (User ID) - числовой идентификатор приложения, которое его создало. Зная UID, через `pm list packages --uid` получаем имя пакета. Это та же информация, которую Android показывает в шторке уведомлений: "Подключено через Happ" - просто мы извлекаем её программно.

Получаем UID владельца VPN-сети, резолвим в package name. Это работает для любого клиента - известного, неизвестного, кастомного. Даже если пользователь установил VPN-клиент, которого нет в нашем списке, мы покажем его package name в интерфейсе и сможем корректно его остановить.

Путь к работающему решению: три неудачные попытки

**Попытка 1: reflection на NetworkCapabilities.mOwnerUid.** На Android 11 поле попало в hidden API blocklist - getDeclaredField() бросает NoSuchFieldException. На Android 10 поле вообще не существует в публичном API. Отброшено. **Попытка 2: dumpsys connectivity | grep -i vpn.** Ловило строку NOT_VPN из WiFi-сети! Каждая WiFi-запись содержит NOT_VPN в capabilities. В результате возвращался UID 1000 (system) и package com.android.dynsystem. Полностью мимо. **Попытка 3: pidof для каждого известного клиента.** Находило все запущенные VPN-клиенты, а не тот, который реально держит VPN. v2rayNG мог висеть в фоне, пока Happ реально обеспечивал VPN. В итоге мы пытались остановить не тот клиент. **Работающее решение:** grep -A 30 'type: VPN\[' - паттерн, уникальный для VPN-сети. Не совпадает с NOT_VPN. Тестировано на Pixel 5, Android 11.

Изящный хак: как отключить любой VPN-клиент без API и без root

Итак, мы умеем запускать VPN и определять, кто его держит. Осталась обратная задача: как выключить VPN-клиент?

Почему обычные способы не работают

Для NekoBox это тривиально – у него есть отдельная Activity для отключения. Но для toggle-клиентов (v2rayNG, Happ и др.) всё сложнее: toggle-команда ненадёжна для остановки. При тестировании Happ обнаружилось: мы отправляем toggle, VPN на мгновение выключается, Anubis начинает размораживать приложения – а Happ уже переподключился. Приложения оказываются разморожены при активном VPN.

am force-stop тоже не панацея – не всегда срабатывает мгновенно. А для произвольного клиента, о котором мы ничего не знаем, API остановки нет вообще.

Dummy VPN: перехват через архитектуру Android

Я перепробовал всё что мог – и решение пришло из самой архитектуры Android: система разрешает только один VPN одновременно. Когда приложение вызывает VpnService.establish(), система автоматически отзывает предыдущий VPN.

Как работает VPN на Android

На Android VPN реализован через системный API VpnService. Приложение создаёт виртуальный сетевой интерфейс (tun0), через который система направляет весь (или часть) трафика. Но система разрешает только один такой интерфейс одновременно. Если второе приложение создаёт свой VPN - первый автоматически отключается. Это как розетка, в которую можно воткнуть только одну вилку. Мы используем это: создаём "пустой" VPN на долю секунды - система отзывает чужой -- мы тут же закрываем свой. Результат: ни одного VPN. При первом использовании Android покажет системный диалог "Разрешить VPN?" - это одноразовое действие.

Мы создали StealthVpnService - минимальный VPN-сервис, который делает одну вещь:

class StealthVpnService : VpnService() {
    private fun doDisconnect() {
        // Устанавливаем свой VPN - система отзывает чужой
        val fd = Builder()
            .addAddress("10.255.255.1", 32)
            .setSession("stealth-disconnect")
            .establish()
        // Немедленно закрываем - VPN нет вообще
        fd?.close()
        stopSelf()
    }
}

Результат: любой VPN-клиент отключён, и нам даже не нужно знать его package name. Требуется VPN permission (одноразовый системный диалог при первом использовании).

Поэтому toggle используется только для включения (когда VPN точно выключен). Для выключения – эскалация:

  1. API stop - только для клиентов с явной командой (NekoBox: QuickDisableShortcut)

  2. Dummy VPN - перехватываем VPN, закрываем свой → ни одного VPN нет

  3. am force-stop – останавливаем процесс обнаруженного клиента

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

Нюанс: если в системных настройках Android включена “Постоянная VPN” (Always-on VPN) для клиента, система будет автоматически перезапускать его после нашего перехвата. В этом случае Always-on нужно выключить.

Обнаружение API закрытых VPN-клиентов через jadx

Изначально Anubis поддерживал автоматический запуск только для v2rayNG и NekoBox – у них open-source, и API легко находится прямо в коде. Остальные клиенты работали в ручном режиме: Anubis открывал приложение, а пользователь сам нажимал “Подключить”. Выключение делалось через dummy VPN – для него реверс не нужен.

Но переключение контекста (открыл шторку → нажал на ярлык → подождал → переключился в чужое приложение → нажал там кнопку → вернулся в исходное) убивало весь смысл оркестрации. Хотелось одного нажатия. Так появилась задача – реверсить closed-source клиенты, чтобы и для них работала автоматика.

Целевые клиенты – Happ, v2rayTun, V2Box. Все три closed source, исходный код недоступен, документации по внешним API нет. Как был найден broadcast action для управления ими?

Ключевое наблюдение

Ресурсы Android (строки, XML-разметка, манифест) не обфусцируются. Обфускатор R8/ProGuard работает только с Java/Kotlin кодом: переименовывает классы, методы, переменные. Но strings.xml, AndroidManifest.xml, XML-описания виджетов остаются нетронутыми.

Это даёт нам точку входа: если у приложения есть виджет на рабочий стол (а у всех VPN-клиентов с поддержкой toggle он есть), мы можем найти его через ресурсы.

Пошаговая методика

  1. Декомпилируем APK через jadx

  2. Ищем виджет в ресурсах: в res/values/strings.xml находим app_widget_name – имя виджета (“Switch”, “Toggle”). Ресурсы не обфусцированы.

  3. Находим receiver в манифесте: в AndroidManifest.xml ищем <receiver> с <meta-data android:name="android.appwidget.provider"> – это класс AppWidgetProvider.

Важно: не перепутать с shortcuts

В APK может быть несколько компонентов с похожими именами. Например, в V2Box есть и `ScSwitchActivity` (в `shortcuts.xml`), и `WidgetProvider` (receiver в манифесте). `shortcuts.xml` -- это ярлыки для лаунчера, а нам нужен именно **receiver виджета рабочего стола**. Отличить легко: у receiver'а есть ``, а в `shortcuts.xml` перечислены `` с `` на Activity. Почему receiver, а не activity? Потому что `am broadcast` можно отправить в фоне без UI, а `am start` на Activity может показать экран. Виджет по определению работает через broadcast -- нажатие на виджет отправляет PendingIntent с broadcast, receiver его ловит и дёргает toggle.

  1. Извлекаем broadcast action из кода: в Java-коде receiver’а ищем setAction("...") – эта строка тоже не обфусцирована, потому что broadcast action’ы являются runtime-константами.

  2. Проверяем логику: в onReceive() ищем паттерн toggle:

// Декомпилированный Happ (jadx output)
// Классы и методы обфусцированы (kd5, r25), но строка action и структура видны
intent.setAction("com.happproxy.action.widget.click");
// ...
if (kd5.a.getIsRunning()) {
    r25.L(context);   // stop
} else {
    r25.J(context);   // start
}
  1. Проверяем exported: в манифесте смотрим android:exported="true" у receiver’а – если да, broadcast можно отправить из любого приложения. У всех проверенных клиентов WidgetProvider имеет exported=true (системе нужно отправлять ему APPWIDGET_UPDATE). Но даже если бы exported=false – через Shizuku shell (UID 2000) broadcast доставляется в любой компонент, потому что shell обходит эту проверку.

Паттерн v2ray/xray форков

Все четыре проверенных форка (v2rayNG, Happ, v2rayTun, V2Box) используют одинаковую структуру:

Action:   <package>.action.widget.click
Receiver: <package>.receiver.WidgetProvider (или WidgetProvider1x1 у v2rayTun)

Зная package name нового форка, можно предсказать broadcast action без декомпиляции.

Shell-команда для toggle:

am broadcast -a <package>.action.widget.click -n <package>/.receiver.WidgetProvider

Это стандартный Android IPC - broadcast action’ы являются публичными интерфейсами по определению. Обнаружение API для целей совместимости защищено законодательством (EU Software Directive 2009/24/EC, ст. 1280 ГК РФ).

Важно: toggle используется только для включения VPN. Почему для выключения он ненадёжен и что используется вместо – описано выше в секции про dummy VPN.

Ярлыки на рабочий стол

Техническая часть позади. Под капотом Anubis умеет: замораживать/размораживать приложения, запускать и останавливать VPN, определять активного клиента. Осталось сделать это удобным – чтобы пользователь просто нажимал на иконку приложения, а вся оркестрация происходила за кадром.

Ярлыки Anubis на рабочем столе -- выглядят как обычные иконки приложений
Ярлыки Anubis на рабочем столе -- выглядят как обычные иконки приложений

Для каждого приложения из любой группы можно создать pinned shortcut через ShortcutManager. Ярлык выглядит как обычная иконка приложения и ведёт себя как обычный запуск. Но под капотом:

  1. Запускается ShortcutActivity - прозрачная Activity без UI

  2. Она определяет группу приложения (Без VPN / Только VPN / Запуск с VPN)

  3. Замораживает/размораживает нужные группы

  4. Включает/выключает VPN через соответствующий клиент

  5. Дожидается подтверждения состояния (VPN включился/выключился)

  6. Размораживает целевое приложение

  7. Запускает его

  8. Закрывается

Пользователь видит: нажал ярлык → приложение открылось. 200мс задержки, если Shizuku уже подключён. Вся оркестрация за кадром.

Дополнительные детали

Grayscale для замороженных приложений

На домашнем экране иконки замороженных приложений отображаются в grayscale:

private val grayscaleFilter = ColorFilter.colorMatrix(
    ColorMatrix().apply { setToSaturation(0f) }
)

Визуально видно, что приложение отключено. При размораживании иконка мгновенно становится цветной – для этого используется реактивный счётчик frozenVersion, который инкрементируется при каждой операции заморозки или разморозки.

Автозаморозка при запуске

Если при запуске Anubis обнаруживает активный VPN, он автоматически замораживает приложения группы “Без VPN”. Не нужно ничего нажимать - приложения защищены с первой секунды.

Проверка сети

Встроенная карточка “Сеть” показывает ping (время ответа ipinfo.io), страну и город. IP и провайдер скрыты за спойлером - это приватная информация, если пользователь работает через личный сервер. Проверка автоматически запускается при каждом изменении состояния VPN - видно сразу: VPN включился → страна изменилась.

Quick Settings Tile

Плитка в системной шторке определяет состояние из реальности (через ConnectivityManager), а не из внутренней переменной. Это важно: состояние могло измениться из ShortcutActivity или другого компонента, и плитка должна это отражать.

Фоновый мониторинг VPN (опционально)

Без фонового мониторинга есть один зазор: пользователь включает VPN-клиент напрямую (не через Anubis), а приложения группы “Без VPN” в этот момент разморожены. Они могут увидеть VPN.

Для закрытия этого зазора в настройках есть опция “Фоновый мониторинг VPN”. При включении запускается Foreground Service (сервис с постоянной нотификацией, который Android гарантированно не убивает) с подписчиком на изменения сети NetworkCallback. Он мгновенно реагирует на изменение VPN-состояния:

  • VPN включился → замораживает группу “Без VPN”

  • VPN выключился → замораживает группу “Только VPN”

Цена - постоянная нотификация в шторке. Поэтому это осознанно вынесено в настройку: если вы управляете VPN только через Anubis (или через ярлыки), фоновый мониторинг не нужен - оркестратор и так всё контролирует.

А что если просто firewall?

Казалось бы, можно просто заблокировать доступ приложений к SOCKS5 порту через iptables. Но:

  1. iptables требует root. Shizuku даёт UID 2000 (shell), а для модификации firewall-правил нужен UID 0. AFWall+ и аналоги - только с root.

  2. Даже root-firewall обходится. Статья про уязвимость VLESS-клиентов показала, что приложение может обратиться напрямую к tun0 через setsockopt(SO_BINDTODEVICE), обходя per-app правила VpnService. Firewall iptables этот вызов тоже не блокирует.

  3. Отключённому приложению firewall не нужен. Если приложение отключено через pm disable-user, у него нет процесса - некому подключаться к SOCKS5, некому обращаться к tun0, некому вообще что-либо делать.

Более того, наш подход даёт двойную защиту даже в момент, когда приложение разморожено. Вспомним порядок действий при запуске приложения из группы “Без VPN”:

  1. Выключаем VPN → процесс VPN-клиента завершается → SOCKS5 порт закрывается → tun0 интерфейс исчезает

  2. Проверяем что VPN действительно выключен (поллинг ConnectivityManager каждые 200мс)

  3. Только после подтверждения размораживаем приложение

То есть к моменту, когда приложение оживает, прокси-порт уже закрыт и VPN-интерфейс уничтожен. Приложению просто нечего сканировать – ни открытого порта, ни tun0, ни активного VPN в ConnectivityManager.

Если собрать все подходы вместе – песочницу, firewall, заморозку – картина выглядит так:

Сравнение подходов (итого)

Island/Insular/Shelter

Firewall (root)

Anubis

Метод

Рабочий профиль

iptables

pm disable-user

Приложение работает?

Да

Да

Нет (мертво)

ConnectivityManager видит VPN?

Нет (фильтр по userId)

Зависит от правил

Невозможно

Видит tun0?

Да (ядро общее)

Да (SO_BINDTODEVICE)

Невозможно

Видит SOCKS5?

Да (loopback общий)

Зависит от правил

Невозможно

Видит маршруты?

Да (/proc/net/route)

Да

Невозможно

Фоновая активность?

Да

Да

Невозможно

Защита от простых проверок

Да

Зависит

Да

Защита от методички Минцифры

Нет

Частично

Да

Управление VPN

Нет

Нет

Да (5 клиентов + любой)

Root нужен?

Нет

Да

Нет (Shizuku)

Удобство

Ручная заморозка

Настройка правил

Один тап по ярлыку

Стек

  • Kotlin + Jetpack Compose (Material 3, dynamic colors)

  • Shizuku API 13.1.5 - AIDL UserService для shell-команд без root

  • Room с TypeConverters - хранение групп приложений

  • ConnectivityManager NetworkCallback - мониторинг VPN в реальном времени

  • ShortcutManager - pinned shortcuts с оркестрацией freeze/VPN/launch

Что дальше

  • Self-hosted app_process daemon - для работы без Shizuku

  • Экспорт/импорт конфигурации групп

  • Поддержка дополнительных VPN-клиентов по мере обнаружения их API

Быстрый старт

⚠️ Прочтите перед тем, как добавлять приложения в группы.

Anubis замораживает приложения через системный pm disable-user. Для Android это выглядит как отключение приложения, и большинство лаунчеров убирают ярлыки таких приложений с рабочего стола – иногда полностью из меню приложений. Виджеты тоже исчезают. Папки на рабочем столе, в которых лежали эти приложения, могут распасться.

Это не удаление. Приложения, их настройки и учётные записи остаются в системе в состоянии disabled. Но после разморозки ярлыки не возвращаются автоматически на прежние позиции – их придётся расставить заново. Это поведение лаунчеров, не Anubis.

Поэтому:

  • Не жмите “Авто-выбор” вслепую. Сначала посмотрите, что именно Anubis предлагает – там могут оказаться приложения, чьи ярлыки вам нужны на рабочем столе (Яндекс.Клавиатура, Mir Pay и подобное).

  • Начните с 2-3 приложений (например, Сбер и Ozon). Убедитесь, что всё работает, потом расширяйте список.

  • Если ярлыки уже пропали – приложения не потеряны. Откройте Anubis → зажмите приложение → “Разморозить” → “Убрать из группы”. Оно вернётся в системный список приложений и появится в поиске. Ярлыки на рабочий стол перетаскивать руками.

  • Массовое восстановление удобнее делать через Hail: отсортировать замороженные, отметить галками, разморозить пачкой.

  1. Установите Shizuku (на Android 11+ – через Wireless Debugging прямо с телефона, без компьютера, за 1 минуту)

  2. Установите Anubis

  3. Дайте разрешения (Shizuku + VPN)

  4. Поместите приложения, для которых VPN нежелателен (банки, маркетплейсы), в группу “Без VPN”

  5. Всё. Теперь при включении VPN они замораживаются автоматически

Никогда не пользовались режимом разработчика и Shizuku? Держите пошаговый гайд на русском – от “где вообще эта кнопка разработчика” до первого замороженного приложения.

Как помочь проекту

Anubis - полностью open-source (MIT). Проект на ранней стадии, и ему нужна помощь:

  • Звезда на GitHub - лучшая мотивация развивать проект

  • Какого VPN-клиента не хватает? Пишите в комментариях или в Issues. Добавить поддержку нового v2ray-форка - это 5 строк кода, а инструкцию по реверсу через jadx я оставил выше

  • Нашли баг? Issues на GitHub открыты

  • Хотите контрибьютить? PR приветствуются. Ближайшие задачи: self-hosted daemon без Shizuku, экспорт/импорт конфигурации

Ссылки

Проект:

Инструменты, использованные в Anubis:

  • Shizuku – shell-права для приложений без root

  • jadx – декомпилятор APK для реверса закрытых клиентов

Контекст проблемы:

Смежные решения (рекомендую):

Благодарности

Отдельное спасибо @linux-over – за его серию статей про Island и трёхкаскадный VPN, которые задали контекст для этой работы, и за инвайт, без которого вы бы это не читали. Наши подходы хорошо комбинируются: его схема обеспечивает устойчивость VPN-инфраструктуры на стороне сервера (точка входа из РФ остаётся в тени, бан выходного узла не ломает связность), Anubis устраняет источник проблемы на клиенте. Вместе получается дешевле и спокойнее, чем по отдельности.

Также спасибо @Wendor – его TeapodStream закрывает утечку SOCKS5 на уровне VPN-клиента. Если Anubis – это страховка “шпион не должен запуститься”, то TeapodStream – “даже если запустился, SOCKS5 ему не поможет”. В связке получается многослойная защита: VPN-клиент не светит прокси, Anubis не пускает шпиона до момента, когда VPN активен. Также спасибо @Wendor – его TeapodStream закрывает утечку SOCKS5 на уровне VPN-клиента. Если Anubis – это страховка “шпион не должен запуститься”, то TeapodStream – “даже если запустился, SOCKS5 ему не поможет”. В связке получается многослойная защита: VPN-клиент не светит прокси, Anubis не пускает шпиона до момента, когда VPN активен.


На этом технические решения проблемы, пожалуй, исчерпаны. А нетехнические… Как известно, или Internet Explorer, или падишах.

Anubis – MIT License. Приложение не предоставляет VPN-сервис, не содержит средств обхода блокировок и не предназначено для нарушения законодательства. Оно управляет жизненным циклом установленных приложений через стандартные механизмы Android (pm disable-user, VpnService API) и может использоваться для любых задач, связанных с приватностью и контролем фоновой активности приложений. Автор не призывает к нарушению действующего законодательства.

Комментарии (341)


  1. Vabkab
    14.04.2026 13:02

    Спасибо за проделанную работу! Было бы очень интересно, если бы вы добавили в сравнение подходов вариант от @Wendor. При нем, как я понимаю обнаружить наличие tun0 и не стандартной маршрутизации возможно, а подключиться к ней нет


    1. sogonov Автор
      14.04.2026 13:02

      Спасибо за идею! Добавил упоминание подхода @Wendor в статью (в “Предыстории” и “Благодарностях”). В сравнительную таблицу его вариант добавлять не стал - там у меня ось “что приложение видит” для песочницы/firewall/Anubis, а у Wendor’а другая плоскость: он чинит сам VPN-клиент. Получается не конкурирующий, а комплементарный подход - его TeapodStream закрывает SOCKS5, мой Anubis отключает шпиона целиком. В связке получается многослойная защита: клиент не светит прокси, Anubis не пускает шпиона до момента, когда VPN активен. Его решение также хорошо совместимо с Island и подобными приложениями - от того, что кто-то увидит наличие tun0 но не сможет им воспользоваться, выходной IP не пострадает. А при split per app маршрутизации, рабочем профиле с Island и его исправленном клиенте, не дающем лезть куда не следует, по идее, большинство приложений будут работать нормально с включенным VPN, и даже самые шаловливые из них не принесут вреда выходному серверу.


  1. Byaka8kaka
    14.04.2026 13:02

    1. Установите Shizuku (на Android 11+ - через Wireless Debugging прямо с телефона, без компьютера, за 1 минуту)

    Было бы супер, если бы была прям инструкция для не технических специалистов)
    Примерно так:
    1. Запустите настройку устройства и нажмите на символ поиска.
    2. Наберите build и нажмите Номер сборки в списке ниже.
    3. Нажмите Номер сборки 7 раз
    4. Установите приложение
    И т.д..
    Иначе приложение дальше просто не уедет, а чем меньше людей себе его поставит - тем оно менее эффективно.


    1. sogonov Автор
      14.04.2026 13:02

      Согласен, абсолютно валидное замечание — запуск Shizuku это реальный порог входа для нетехнической аудитории. Сделал отдельный подробный гайд на русском: https://github.com/sogonov/anubis/blob/main/docs/SETUP.md - от “где вообще эта кнопка разработчика” до готовой настройки, с разделением на Android 11+ (без компьютера) и Android 10 (через ADB AppControl). Ссылку на гайд добавил в “Быстрый старт” в статье. Если есть замечания по гайду - буду рад улучшить, присылайте правки в Issues или прямо в комментариях.

      В самой Shizuku сделан достаточно удобный гайд


      1. Zachelovek
        14.04.2026 13:02

        Сделал отдельный подробный гайд на русском

        Спасибо!

        Прочитал, один вопрос по итогам: минимальная версия андроид в гайде - 10. Верно ли я понял, что на более старых всё обсуждаемое тут неприменимо?


        1. sogonov Автор
          14.04.2026 13:02

          На более старых Android Shizuku формально должен работать(minSdk у него 24, это a7), но Anubis рассчитан на API 29+ (а10), и я не тестировал на более старых версиях. Попробую найти для теста устройство или на крайняк эмулятор, по идее, можно тоже понизить minSdk. Но метод с беспроводной отладкой это точно а11+, на всем, что ниже придется выдавать нужные права через adb shell по usb


  1. Arjgsh
    14.04.2026 13:02

    К сожалению эта вонючая шизука никак не хочет работать


    1. sogonov Автор
      14.04.2026 13:02

      А что именно не получается? Каким способом пытаетесь её включить? Я выложил чуть более подробный гайд на русском: https://github.com/sogonov/anubis/blob/main/docs/SETUP.md


      1. Skipy
        14.04.2026 13:02

        Производитель вашего устройства ограничил права adb, приложения, использующие Shizuku, будут работать некорректно

        Обычно эти ограничения можно снять в настройках для разработчиков

        А дальше предлагается почитать справку на сайте shizuku, который с телефона вообще не открывается

        Всё, тупик. Чтобы на Xiaomi включить Shizuku, нужно включить отладку по USB (настройки безопасности). А для этого требуется войти в Mi Account. Которого не существует.


        1. sogonov Автор
          14.04.2026 13:02

          когда-то в очень далеком прошлом я тоже впервые пробовал, не получилось разобраться, а поскольку ноутбук с ADB чаще всего под рукой, я выдавал себе нужные разрешения через adb shell. Но сейчас на всех моих пикселях работает, быстро и удобно... А что у вас за операционная система?

          У вас получается, вот такой выданный системой код не срабатывает?

          Если не получится разобраться с беспроводом, моя рекомендация - установить ADB App Control, это пожалуй самый приятный способ взаимодействия с ADB, даже для меня, хоть и 90% действий я делаю в консоли Far Manager. Через adb shell скорее всего запустится с первого раза



          p.s. пока писал вам ответ, ваш комментарий уже изменился)


          1. Skipy
            14.04.2026 13:02

            Судя по сообщениям, у меня в принципе adb ограничен. И не может быть включен без mi account-а


            1. Heggi
              14.04.2026 13:02

              А что за телефон? На моём Xiaomi adb я без проблем включил (еще давно, когда рекламный маразм выпиливал)


        1. shkryabla
          14.04.2026 13:02

          Включите так же :

          Отладка по usb и Отладка по usb (настройки безопасности)

          На poco заработало


          1. g3falsht
            14.04.2026 13:02

            Подтверждаю. Все шуршит после включения этих пунктов


      1. Arjgsh
        14.04.2026 13:02

        После сопряжения шизука не запускается, просто ожидает и все. И да, ограничение на adb, так же как и писали выше


        1. Snooper
          14.04.2026 13:02

          Попробуйте пункт «Отключить контроль разрешений» в настройках разработчика.


          1. Arjgsh
            14.04.2026 13:02

            Да, спасибо, видел в инструкции к шизуке, просто сейчас нет времени водится с телефоном. Когда разберусь звезду поставлю, а то лазить во второе пространство это неудобно. Сразу вопрос, что придумать для приложений, кидающих флаг ВПН, но для которых я хочу чтобы открывались все приложения (byedpi например), типо игнорировать от него состояние.

            А, и ещё - всю эту порнографию не придется случаем проделывать после каждой перезагрузки устройства?

            Ну а вообще это все полумеры. Тут уже была статья про то, что надо пролить прокси на локалхосте (почему это не делается изкаропки?) и вышла приложение даже, но, пока что, там нет роуминга, что очень и очень нужно


            1. sogonov Автор
              14.04.2026 13:02

              1) если byedpi работает по аналогии с тем же adguard - то есть прописывается в системный VPN, хоть и не является им по своей сути, то да, он будет на общих основаниях триггерить Anubis. Но ему, по идее, не страшны и описанные методы из методички минцифры, нет IP которые можно испортить. Так что, если задача просто скрыть системный флаг "VPN сейчас активен" - в рабочий профиль всех, кому нужен byedpi, и там же его самого запускать, или наоборот, в зависимости от того, как проще организовать.
              2) Придется после каждой перезагрузки, если устройство без root доступа(более того, пока получение прав через root, а не через shizuku приложение и не поддерживает). Но нужно будет всего лишь активировать shizuku. Это одна команда в adb shell или при а11+ способ через беспроводную отладку. Все группы приложений, а так же их состояние(заморожено/разморожено) сохранятся. Только право размораживать/замораживать после перезагрузки потеряется, пока не восстановить shizuku в правах


              1. neit_kas
                14.04.2026 13:02

                У себя на Samsung в разделе для разработчиков нашёл пункт: “Выбрать приложение для отладки”. Помню даже использовал его с Brevent. Не знаете, какие права у такого приложения? Это случаем не self-hosted ADB со всеми вытекающими?

                И, кстати, на счёт “однокнопочных” универсальных решений. Я не Android разработчик, но как понимаю, реально определить, активен VPN или нет. А значит по идее можно не долбаться с API VPN клиентов: мониторим в фоне VPN. Если активируется - переключаемся. Или это будет не надёжно?


      1. clientikshow
        14.04.2026 13:02

        Сделайте пометку в статье, у меня была ситуация когда я поставил шизуку и мне заблок ровали WeChat аккаунт без возможности восстановления. Актуально может для тех кто пользуется приложениями из поднебесной


        1. cjmaxik
          14.04.2026 13:02

          У меня вичат работает без проблем, шизуку не трогал. Совпадение?


          1. clientikshow
            14.04.2026 13:02

            Возможно совпадение, но в моем кейсе только шизуку ставил и сразу бан словил.


            1. sogonov Автор
              14.04.2026 13:02

              я в статье пометку сделал, но впервые слышу о таком


              1. GBQ3
                14.04.2026 13:02

                Спасибо за труд. Но вопрос такой. Толе имею 3 приложения из китая.если их закинуть в песочницу увидят ли они работу шизуки? Или же такой вариант я закинуть их в Песочницу , заморозить . Если нужны , то отключить шизуку и после только запускать. Есть ли в этом смысл, ваше мнение ?


                1. sogonov Автор
                  14.04.2026 13:02

                  они могут видеть список пакетов установленных в системе, и даже замороженная shizuku им может в теории не понравиться. Тем не менее, в рабочем профиле они их скорее всего не увидят, там свое пространство. Установите в рабочее пространство anubis (даже без shizuku) и посмотрите, например в меню ручного выбора VPN, какие приложения он там видит? вот столько же приложений увидит и китайское.. Если только из рабочего профиля - то с вероятностью 80% они ничего не узнаю о том, что происходит в основном профиле


  1. wet-thought
    14.04.2026 13:02

    А ярлыки как вынести обратно? Можно шорткат какой-то для этого запилить?


    1. sogonov Автор
      14.04.2026 13:02

      Да, ярлыки выносятся через долгое нажатие на иконку приложения в Anubis - в контекстном меню есть пункт “Создать ярлык на рабочем столе”. Создаётся pinned shortcut через ShortcutManager: иконка ложится на домашний экран, при нажатии оркеструет freeze/VPN/запуск в одно действие. Если не работает - киньте https://github.com/sogonov/anubis/issues с моделью телефона и версией Android, буду разбираться

      Hidden text


  1. Skipy
    14.04.2026 13:02

    1. Установите Shizuku (на Android 11+ - через Wireless Debugging прямо с телефона, без компьютера, за 1 минуту)

    А можно вот это поподробнее? А то всё найденное стопорится на запуске Android Studio и/или спаривании телефона и компьютера


    1. sogonov Автор
      14.04.2026 13:02

      Вам, скорее всего, запускать Android Studio не понадобится, я обхожусь ADB+VS Code для разработки под андроид. Вы хотите собрать приложение на своем компьютере из исходников?

      А про Shizuku я подробнее уже написал. Если вы установите Anubis, он сам подскажет, откуда скачать shizuku

      Hidden text

      А когда вы установите Shizuku, подробный гайд есть уже внутри него

      И вам остается лишь выбрать, что проще - найти компьютер с ADB и сделать все по проводу, или подключиться к Wi-fi и попробовать способ с беспроводной отладкой

      Я всегда пользовался шнуром, но сейчас снова попробовал способ с беспроводом - достаточно просто, понятно и нет зависимости от пк
      p.s. Добавил в репозиторий гайд
      https://github.com/sogonov/anubis/blob/main/docs/SETUP.md


  1. Sneer1
    14.04.2026 13:02

    Приблизительно о чем-то подобном и бродили мысли (логика работы). Интересная статья.


  1. greenlittlefrog
    14.04.2026 13:02

    Я себе сделал иначе: дома на Keenetic поднял wg клиент и подключил его, затем в маршрутизацию забил домены которые должны ходить только через wg. Таким образом дома всё маршрутизуется. Дополнительно на том же Keenetic поднял wg сервер, к которому вне дома подключается телефон и пользуется той же маршрутизацией. Дальше делаем на iOS автоматизацию, которая автоматически переключает VPN в зависимости от подключения к Wi-Fi.

    На Linux аналогичный конфиг реализуется через dnsmasq и ip route.


    1. Zloymopga
      14.04.2026 13:02

      подумываю о такой же схеме но с vless. только вот вопрос - "шпионы" разве не будут видеть сам факт VPN при таком подходе?


      1. greenlittlefrog
        14.04.2026 13:02

        Некоторые жалуются потому что тумблер включен, но никакой блокировки или замедления нет.


        1. Zloymopga
          14.04.2026 13:02

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


          1. greenlittlefrog
            14.04.2026 13:02

            Они просто дергают стандартный механизм iOS который позволяет им видеть что тумблер включен.
            Дальше они могут посмотреть выходной IP - это будет русский IP, потому что через зарубежный VPN отправляются только определенные домены. Могут пингануть youtube.com - но он пингуется и без блокировки. Могут пустить traceroute - тут да, палево. В общем спалить можно, если сильно увлечься, тут вопрос заинтересованности. С точки зрения базового функционала у нас локация IP и гео совпадают.


            1. SukharevAndrey
              14.04.2026 13:02

              Им достаточно послать запрос на любой иностранный сервис определения айпишников, который отдаёт ответ в json. И сразу всё палится. Поэтому нужно делать triple-hop или иметь второй айпишник на выходной ноде или поднять там warp.


              1. greenlittlefrog
                14.04.2026 13:02

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


                1. linux-over
                  14.04.2026 13:02

                  белые списки ведь не круглосуточно работают

                  пока, во всяком случае


                  1. ilusha_b
                    14.04.2026 13:02

                    Он имел в виду скорее всего свои белые списки.

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


                1. Aelliari
                  14.04.2026 13:02

                  и не понял каким образом какое-то приложение должно узнать от условного ютуба адрес выходной ноды

                  Хм, https://redirector.googlevideo.com/report_mapping


                  1. Aelliari
                    14.04.2026 13:02

                    1. greenlittlefrog
                      14.04.2026 13:02

                      Не показывайте это больше никому :))


                1. vikarti
                  14.04.2026 13:02

                  иностранного сервиса определения айпишников в белом списке,

                  Известных вам сервисов.


                1. Zalechi
                  14.04.2026 13:02

                  уже тонны энергии сливаем ради ИИ для Вас лично, а вы стесняетесь им воспользоваться, чтобы спросить или не доверяете ему или не умеете формулировать вопросы?


        1. spc
          14.04.2026 13:02

          Сегодня приложение Дикси удивило - при включенном ВПН отказывается работать, хотя в настройках клиента указаны приложения, которым разрешен ВПН и Дикси там нет. Из этого я делаю вывод, что они сделали блокировку просто по факту включенного ВПН. Могу, конечно, ошибаться.


          1. navion
            14.04.2026 13:02

            Подтверждаю, Дикси не работает даже с App Tracking Protection в DuckDuckGo. В комментариях ещё писали про Газпромнефть с таким поведением.