vpnhide/README.ru.md

144 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# vpnhide
Скрывает активное VPN-соединение на Android от выбранных приложений.
## Чем vpnhide лучше аналогов?
Существующие модули, такие как [NoVPNDetect](https://bitbucket.org/yuri-project/novpndetect) и [NoVPNDetect Enhanced](https://github.com/BlueCat300/NoVPNDetectEnhanced), хукают **внутри процесса** целевого приложения через Xposed. Это означает, что любое приложение с anti-tamper защитой может обнаружить инъекцию и отказаться работать. Автор NoVPNDetect Enhanced прямо пишет: *«Модуль не будет работать если у подключаемого приложения есть защита от LSPosed, проверка на инъекции в память. Например MirPay, Т-Банк.»*
vpnhide использует принципиально другой подход:
- **lsposed** хукает `system_server` (а не целевое приложение) — данные о VPN удаляются на уровне Binder до того, как попадут в процесс приложения. Anti-tamper SDK проверяет свой процесс и ничего не находит.
- **kmod** хукает само ядро — ioctl, netlink и /proc/net фильтруются до возврата из системного вызова. Нулевой след в процессе. Никакой инъекции библиотек. Нечего обнаруживать.
- Процесс целевого приложения полностью нетронут — ни Xposed, ни inline-хуков, ни модифицированных регионов памяти.
Благодаря этому vpnhide работает с такими приложениями, как MirPay, Т-Банк, Альфа-Банк и другими банковскими/государственными приложениями, которые активно обнаруживают и блокируют модули на основе Xposed.
Кроме того, vpnhide покрывает нативные векторы обнаружения (ioctl, netlink, /proc/net), которые аналоги вообще не хукают — именно эти векторы используют приложения на кроссплатформенных фреймворках и нативных SDK.
## Какие модули нужны?
Всегда нужен `lsposed` (обрабатывает обнаружение через Java API) плюс один нативный модуль:
- **`kmod` + `lsposed`** (рекомендуется) — хуки на уровне ядра, нулевой след в процессе приложения. Невидим для anti-tamper SDK в банковских/госприложениях. Требуется поддерживаемое GKI-ядро (см. ниже).
- **`zygisk` + `lsposed`** — хуки libc внутри процесса приложения. Используйте, если ваше устройство не поддерживается сборками kmod, или если нет возможности установить модуль ядра.
## Установка
Скачайте последний релиз из [Releases](https://github.com/okhsunrog/vpnhide/releases).
### kmod + lsposed (рекомендуется)
1. Установите `vpnhide-kmod-<ваш-gki>.zip` через менеджер KernelSU-Next → Модули → Установить из хранилища
2. Установите `vpnhide-lsposed.apk` как обычное приложение
3. В менеджере LSPosed включите модуль vpnhide и добавьте **«System Framework»** в его область действия
4. Перезагрузите устройство (обязательно — хуки LSPosed внедряются в `system_server` при загрузке, поэтому модуль должен быть активен до запуска `system_server`)
5. Откройте приложение VPN Hide, предоставьте ему root-доступ (Magisk запросит автоматически; на KernelSU-Next выдайте разрешение вручную в менеджере) и выберите целевые приложения
**Как узнать поколение GKI:** выполните `adb shell uname -r`. Вывод выглядит как `6.1.75-android14-11-g...` — поколение `android14-6.1`. Скачайте соответствующий `vpnhide-kmod-android14-6.1.zip`.
> **Примечание:** `android14` в названии GKI — это НЕ версия Android, а поколение ядра. Все Pixel с 6 по 9a используют одно ядро `android14-6.1`. Серия Pixel 10 перешла на `android16-6.12`.
### zygisk + lsposed
1. Установите `vpnhide-zygisk.zip` через менеджер KernelSU-Next или Magisk → Модули
2. Установите `vpnhide-lsposed.apk` как обычное приложение
3. В менеджере LSPosed включите модуль vpnhide и добавьте **«System Framework»** в его область действия
4. Перезагрузите устройство (обязательно — хуки LSPosed внедряются в `system_server` при загрузке)
5. Откройте приложение VPN Hide, предоставьте ему root-доступ (Magisk запросит автоматически; на KernelSU-Next выдайте разрешение вручную в менеджере) и выберите целевые приложения
## Настройка
**Приложение VPN Hide (рекомендуется):** откройте приложение VPN Hide (устанавливается как `vpnhide-lsposed.apk`) и предоставьте ему root-доступ (Magisk запрашивает автоматически; на KernelSU-Next выдайте разрешение в менеджере). Приложение показывает все установленные приложения с иконками, названиями и поиском. Отметьте приложения, от которых нужно скрыть VPN, нажмите «Сохранить». Работает и с kmod, и с zygisk — автоматически записывает во все нужные файлы через `su`.
**WebUI:** на KernelSU-Next откройте модуль в менеджере и нажмите WebUI. Тот же функционал, но доступен только на KernelSU-Next (Magisk не поддерживает WebUI).
**Командная строка:** редактируйте `/data/adb/vpnhide_kmod/targets.txt` или `/data/adb/vpnhide_zygisk/targets.txt` напрямую (одно имя пакета на строку). Для применения изменений требуется перезагрузка.
После изменения целей принудительно остановите и перезапустите затронутые приложения — хуки вступают в силу при следующем запуске приложения.
## Проверка
Установите `vpnhide-test.apk` из релиза, добавьте его в список целевых приложений и запустите при активном VPN. Все проверки должны показать PASS.
## Компоненты
| Директория | Что | Как |
|---|---|---|
| **[kmod/](kmod/)** | Модуль ядра (C) | Хуки `kretprobe` в пространстве ядра. Нулевой след в процессе приложения. ([подробнее](kmod/README.md)) |
| **[lsposed/](lsposed/)** | LSPosed-модуль + приложение выбора целей (Kotlin) | Хуки `writeToParcel` в `system_server` для per-UID фильтрации Binder. APK также служит UI для управления целями. ([подробнее](lsposed/README.md)) |
| **[zygisk/](zygisk/)** | Zygisk-модуль (Rust) | Inline-хуки `libc.so` в процессе приложения. Альтернатива kmod. ([подробнее](zygisk/README.md)) |
| **[test-app/](test-app/)** | Диагностическое приложение (Kotlin + Rust) | 24 проверки, покрывающие все векторы обнаружения. |
## Покрытие обнаружения
| # | Вектор обнаружения | SELinux | kmod | zygisk | lsposed |
|---|---|---|---|---|---|
| 1 | `ioctl(SIOCGIFFLAGS)` на tun0 | | x | x | |
| 2 | `ioctl(SIOCGIFNAME)` разрешение индекса в имя | | x | x | |
| 3 | `ioctl(SIOCGIFCONF)` перечисление интерфейсов | | x | x | |
| 4 | `getifaddrs()` (использует netlink внутри) | | x | x | |
| 5 | netlink `RTM_GETLINK` дамп | блок. | x | x | |
| 6 | netlink `RTM_GETADDR` дамп (IPv4 + IPv6) | блок. | x | | |
| 7 | netlink `RTM_GETROUTE` дамп | блок. | | | |
| 8 | `/proc/net/route` | блок. | x | x | |
| 9 | `/proc/net/ipv6_route` | блок. | | x | |
| 10 | `/proc/net/if_inet6` | блок. | | x | |
| 11 | `/proc/net/tcp`, `tcp6` | блок. | | | |
| 12 | `/proc/net/udp`, `udp6` | блок. | | | |
| 13 | `/proc/net/dev` | блок. | | | |
| 14 | `/proc/net/fib_trie` | блок. | | | |
| 15 | `/sys/class/net/tun0/` | блок. | | | |
| 16 | `NetworkCapabilities` (hasTransport, NOT_VPN, transportInfo) | | | | x |
| 17 | `NetworkInfo` (getType, getTypeName) | | | | x |
| 18 | `ConnectivityManager.getActiveNetwork()` | | | | x |
| 19 | `ConnectivityManager.getAllNetworks()` + VPN-сканирование | | | | x |
| 20 | `LinkProperties` (interfaceName, routes, DNS) | | | | x |
| 21 | `NetworkInterface.getNetworkInterfaces()` | | x | x | |
| 22 | `System.getProperty` (настройки прокси) | | | x | |
| 23 | `/proc/net/route` через Java `FileInputStream` | блок. | x | x | |
**блок.** = SELinux запрещает доступ для обычных приложений (Android 10+). Хуки не нужны.
Строки 14, 19 и 21 — единственные векторы, доступные обычным приложениям. Всё остальное либо заблокировано SELinux, либо проходит через Java API (покрывается lsposed).
## Сборка из исходников
- **kmod**: `cd kmod && make && ./build-zip.sh` — см. [kmod/BUILDING.md](kmod/BUILDING.md)
- **zygisk**: `cd zygisk && ./build-zip.sh` (Rust + NDK + cargo-ndk)
- **lsposed**: `cd lsposed && ./gradlew assembleDebug` (JDK 17)
- **test-app**: `cd test-app && ./gradlew installDebug` (JDK 17 + Rust + NDK)
## Проверено на
- [RKNHardering](https://github.com/xtclovver/RKNHardering/) — все векторы обнаружения чисты
- [YourVPNDead](https://github.com/loop-uh/yourvpndead) — все векторы обнаружения чисты
Оба реализуют официальную методику обнаружения VPN/прокси Минцифры РФ ([источник](https://t.me/ruitunion/893)).
## Раздельное туннелирование (split tunneling)
Корректно работает с конфигурациями VPN с раздельным туннелированием. Затрагиваются только приложения из списка целей.
Приложения-детекторы, сравнивающие публичный IP устройства с внешними чекерами, требуют раздельного туннелирования — трафик приложения-детектора должен выходить через оператора, а не через туннель.
## Модель угроз
vpnhide скрывает активный VPN от конкретных приложений. Он НЕ предназначен для:
- Скрытия root или кастомной прошивки
- Обхода Play Integrity
- Обмана серверной детекции (утечки DNS, чёрные списки IP, фингерпринтинг латентности/TLS)
## Известные ограничения
- `kmod` требует GKI-ядро с `CONFIG_KPROBES=y` (стандарт на устройствах Android 12+)
- `lsposed` требует LSPosed, LSPosed-Next или Vector
- `zygisk` — только arm64
- Прямые системные вызовы `svc #0` обходят хуки libc в zygisk — для этого и нужен kmod
- Серверная детекция неисправима на стороне клиента — используйте раздельное туннелирование
## Лицензия
MIT. См. [LICENSE](LICENSE).
Модуль ядра объявляет `MODULE_LICENSE("GPL")`, как требуется ядром Linux для разрешения символов `EXPORT_SYMBOL_GPL` во время выполнения.