# Практическое руководство: защита VPN от localhost-атаки **Дата:** 7 апреля 2026 **Контекст:** Уязвимость VLESS-клиентов + эксплуатация localhost Meta/Яндексом **Аудитория:** Пользователи VPN, администраторы серверов, разработчики клиентов **Связанные заметки:** - [Уязвимость VLESS-клиентов](VLESS-SOCKS5-vulnerability.md) - [Localhost-трекинг Meta/Яндекс](Localhost-tracking-Meta-Yandex-SOCKS5.md) --- ## Оглавление 1. [Суть проблемы за 30 секунд](#1-суть-проблемы-за-30-секунд) 2. [Проверенные клиенты: кто уязвим, кто нет](#2-проверенные-клиенты-кто-уязвим-кто-нет) 3. [Что делать пользователям Android](#3-что-делать-пользователям-android) 4. [Что делать пользователям Windows](#4-что-делать-пользователям-windows) 5. [Что делать пользователям iOS](#5-что-делать-пользователям-ios) 6. [Что делать администраторам серверов](#6-что-делать-администраторам-серверов) 7. [Конфигурации: xray-core клиент](#7-конфигурации-xray-core-клиент) 8. [Конфигурации: sing-box клиент](#8-конфигурации-sing-box-клиент) 9. [Конфигурации: xray-core сервер](#9-конфигурации-xray-core-сервер) 10. [Конфигурации: CloudFlare WARP на сервере](#10-конфигурации-cloudflare-warp-на-сервере) 11. [Конфигурации: блокировка geoip:ru на сервере](#11-конфигурации-блокировка-geoipru-на-сервере) 12. [Конфигурации: маршрутизация «Всё кроме РФ» на клиенте](#12-конфигурации-маршрутизация-всё-кроме-рф-на-клиенте) 13. [Блокировка Happ на сервере подписок](#13-блокировка-happ-на-сервере-подписок) 14. [**ГАЙД: v2rayNG — как защититься**](#14-гайд-v2rayng--как-защититься) 15. [**ГАЙД: NekoBox — как защититься**](#15-гайд-nekobox--как-защититься) 16. [**ГАЙД: Clash/mihomo — как защититься**](#16-гайд-clashmihomo--как-защититься) 17. [Фаерволы на Android: что реально работает](#17-фаерволы-на-android-что-реально-работает) 18. [FAQ: hev-socks5-tunnel, Karing, Husi, v2rayN](#18-faq-hev-socks5-tunnel-karing-husi-v2rayn) 19. [CVE-2023-43644: обход аутентификации sing-box](#19-cve-2023-43644-обход-аутентификации-sing-box) 20. [Чеклист действий](#20-чеклист-действий) --- ## 1. Суть проблемы за 30 секунд Все VPN-клиенты на базе xray/sing-box создают на телефоне/компьютере **локальный SOCKS5-прокси без пароля**. Любое приложение-шпион (Яндекс, WB, Ozon, гос.приложения) может: 1. Найти этот прокси за секунды (скан портов localhost) 2. Подключиться без пароля 3. Узнать IP вашего VPN-сервера 4. Передать IP в РКН → сервер заблокирован **Knox, Shelter, Island, режим инкогнито, split tunneling — НЕ помогают.** Скриншот POC-приложения с включённой SOCKS5-аутентификацией (Husi): ``` Per-app split tunnel bypass Status: VPN not found ← прокси не обнаружен Direct IP: xxx.xxx.xxx.xxx IP via proxy: - ← не смог подключиться Xray API: Not found ← API недоступен ``` **Вывод:** аутентификация работает — POC не смог пробиться через запароленный SOCKS5. --- ## 2. Проверенные клиенты: кто уязвим, кто нет ### Android | Клиент | Ядро | Порт | SOCKS5 auth | Статус | Что делать | |--------|------|------|-------------|--------|------------| | **v2rayNG** 2.0.0 | xray | 10808 | ❌ Нет в UI. ⚠️ Custom config — ненадёжно (v2rayNG может перезаписать inbound) | 🟡 Уязвим | Перейти на Husi; или AFWall+ (root) | | **Hiddify** 4.1.1 | sing-box + xray | ? | ❌ Нет в UI | 🟡 Уязвим | Перейти на Husi/SFA | | **NekoBox** 1.4.2 | sing-box 1.12.19 | 2080 | ❌ Нет в UI. ⚠️ Custom JSON — возможно, но сбрасывается при обновлении | 🟡 Уязвим | Перейти на Husi; или удалить mixed inbound | | **Npv Tunnel** | xray | ? | ❌ Нет | 🟡 Уязвим | Перейти на Husi/SFA | | **v2RayTun** 5.19.64 | xray | ? | ⚠️ Ядро поддерживает, UI — неизвестно | 🟡 Скорее уязвим | Уточнить у разработчика | | **Happ** | xray | ? | ❌ + API HandlerService без auth | 🔴 **УДАЛИТЬ НЕМЕДЛЕННО** | Дамп ключей, IP, SNI | | **Karing** | sing-box | 3067 | ⚠️ Ядро поддерживает, в UI нет настройки | 🟡 Скорее уязвим | Проверить custom JSON | | **Exclave** | sing-box | ? | ✅ Да (через конфиг) | 🟢 Можно настроить | Настроить auth в конфиге | | **Husi** 1.1.0 | sing-box (dun) | ? | ✅ **Да, есть в UI** | 🟢 **Рекомендован** | Включить auth в настройках | | **SFA** 1.13.6 | sing-box | ? | ✅ Да (JSON) | 🟢 Можно настроить | Ручная правка JSON | | **saeeddev94/xray** | xray | ? | ✅ Да (JSON + UI) | 🟢 Можно настроить | F-Droid, настроить auth | | **v2RayTun** 5.20.67 | xray | ? | ❌ Нет в UI. Разработчик обещал фикс (март 2026), пока нет | 🟡 Уязвим | Ждать фикса или перейти. ⚠️ Шлёт домены подписок на свои сервера | | **ClashMeta Android** 2.11.25 | mihomo | — | ✅ Да (YAML). По дефолту `socks-port` **выключен** (TUN-only) → прокси нет → нечего сканировать | 🟢 **Безопасен по дефолту** | Если включили `socks-port` — добавить auth + убрать `skip-auth-prefixes` | | **FlClash** | mihomo | — | ✅ Да (YAML). Аналогично — дефолт TUN-only | 🟢 **Безопасен по дефолту** | Аналогично ClashMeta | | **Incy** 2.0.8 | xray 26.3.27 | ? | ⚠️ Ядро поддерживает, UI-настройка auth не документирована | 🟡 Вероятно уязвим | Нужна проверка — closed-source-подобный | | **anet** 0.4.2 | Собственный (Rust/ASTP) | — | ✅ **Не применимо** | 🟢 **Не уязвим** | Нет SOCKS5/HTTP прокси на localhost. Чистый TUN через собственный протокол | ### Windows / Desktop | Клиент | Ядро | Порт | SOCKS5 auth | Статус | Что делать | |--------|------|------|-------------|--------|------------| | **v2rayN** 7.20.2 | xray/sing-box | 10808 | ✅ Да (JSON + UI) | 🟢 Можно настроить | Включить auth + Windows Firewall | | **Nekoray** | sing-box/xray | ? | ❌ Нет в UI | 🔴 **Заброшен (2026)** | Перейти на Throne / v2rayN / Clash Verge Rev | | **Throne** 1.1.1 (март 2026) | sing-box (основной) + xray (для VLESS) | 2080 | ⚠️ Дефолтный mixed нельзя отключить, но можно создать кастомный inbound с auth | 🟡 Уязвим по дефолту, **можно настроить** | Создать кастомный inbound с auth; заблокировать дефолтный фаерволом | | **XrayFluent** | xray | 10808 | ❌ Нет | 🟡 Уязвим | Будет исправлено | | **Karing** (Windows) | sing-box | 3067/3066 | ⚠️ Ядро поддерживает, UI-настройка не подтверждена | 🟡 Вероятно уязвим | Проверить custom JSON | | **Clash Verge Rev** | mihomo | — | ✅ Да (YAML). По дефолту TUN-only, `socks-port` выключен | 🟢 **Безопасен по дефолту** | Если включили socks-port — добавить auth + убрать skip | | **ClashX Meta** (macOS) | mihomo | — | ✅ Да (YAML). Аналогично | 🟢 **Безопасен по дефолту** | Аналогично | | **Incy** (Desktop) 2.0.8 | xray 26.3.27 | ? | ⚠️ Не документировано | 🟡 Нужна проверка | — | ### iOS | Клиент | Ядро | Порт | SOCKS5 auth | Статус | Что делать | |--------|------|------|-------------|--------|------------| | **Happ** | xray | ? | ❌ + API без auth | 🔴 **УДАЛИТЬ** | Удалено из **российского** App Store; в других регионах может быть доступно, но фикса не будет | | **V2BOX** 5.3.4 | xray | ? | ❌ Нет подтверждения | 🟡 Скорее уязвим | Нет решения | | **RabbitHole** 1.3.0 | ? (closed-source) | ? | ⚠️ Неизвестно | ❓ Нужна проверка | Closed-source, поддерживает SOCKS5 — нужна проверка POC | | **Shadowrocket** | iOS VPN framework | — | ⚠️ Вероятно не применимо (iOS sandbox) | 🟢/❓ **Скорее не уязвим, нужна проверка POC** | iOS sandbox ограничивает listening sockets | > **Shadowrocket** — использует iOS Network Extension (VPN framework). Основной режим — TUN через системный VPN. В отличие от Android-клиентов (v2rayNG, NekoBox), Shadowrocket **не является прокси-сервером** — он подключается К прокси-серверам. Однако верификация показала, что Shadowrocket может поддерживать SOCKS5-конфигурации на localhost. При этом iOS sandbox **жёстко ограничивает** фоновые listening-сокеты, доступные другим приложениям. **Вердикт: скорее не уязвим** из-за ограничений iOS, но для полной уверенности **требуется проверка POC на реальном устройстве**. > **Exclave** ранее указывался как iOS-клиент — это ошибка. Exclave ([github.com/dyhkwong/Exclave](https://github.com/dyhkwong/Exclave)) — это **Android**-клиент на базе sing-box, доступен на F-Droid. Поддерживает аутентификацию через конфиг. > **RabbitHole** — closed-source iOS/macOS клиент от RABBIT HOLE STUDIO LTD. Поддерживает VLESS, VMess, Hysteria2, SOCKS5 и др. Без публичного репозитория невозможно точно определить, создаёт ли он SOCKS5 на localhost. Требуется ручная проверка POC-приложением. > **Incy** — кроссплатформенный клиент на xray-core 26.3.27 ([github.com/INCY-DEV/incy-platforms](https://github.com/INCY-DEV/incy-platforms)). v2.0.8 (7 апреля 2026). Поддерживает VLESS Reality, VMess, Trojan, SS, Hysteria2, WireGuard. Auth-статус на локальном inbound не документирован — нужна проверка. > **Throne** ([github.com/throneproj/Throne](https://github.com/throneproj/Throne)) — **преемник заброшенного Nekoray**. Qt-based, sing-box + встроенный xray-core. v1.1.1 (март 2026). Дефолтный mixed inbound **нельзя отключить**, но можно: (1) перевесить на другой IP:port, (2) заблокировать фаерволом, (3) создать кастомный socks/mixed inbound с auth. Из обсуждения на ntc.party: «в Throne ситуация получше — можно создать кастомный инбаунд и закрыть его логопассом». > **anet** ([github.com/ZeroTworu/anet](https://github.com/ZeroTworu/anet)) — полностью кастомный Rust VPN с собственным протоколом ASTP v0.5 (ChaCha20Poly1305/X25519/Ed25519). **Не создаёт** SOCKS5/HTTP прокси — только чистый TUN. Нишевый проект для «сети друзей» (624 звезды). К данной уязвимости **не применим**. > **v2RayTun** — xray-core, 16 млн скачиваний, open-source. Разработчик **подтвердил уязвимость** (март 2026) и обещал фикс, но на апрель 2026 фикса нет. ⚠️ Privacy concern: отправляет домены подписок на свои серверы при каждом запуске. ### О hev-socks5-tunnel (используется в v2rayNG) **hev-socks5-tunnel** — это легковесная реализация tun2socks. Сама библиотека **поддерживает** SOCKS5-аутентификацию (username/password). Но **v2rayNG не включает auth** при настройке туннеля — передаёт `noauth`. Проблема не в hev-socks5-tunnel, а в том, что v2rayNG не выставляет аутентификацию на inbound xray-core, к которому подключается туннель. ### О Karing (sing-box) **Karing** использует ядро sing-box. Создаёт local proxy на портах: - HTTP/HTTPS: `127.0.0.1:3066` - SOCKS5: `127.0.0.1:3067` Karing использует sing-box core с тремя mixed-inbound портами: 3065, 3066, 3067. По умолчанию — **без аутентификации**. **Защита**: в настройках каждого профиля необходимо отредактировать блок `inbounds` и добавить `users` с паролем ко **всем трём** inbound: ```json "inbounds": [ { "type": "mixed", "tag": "mixed_in_direct", "set_system_proxy": false, "users": [ { "username": "local", "password": "СЮДА_ДЛИННЫЙ_РАНДОМНЫЙ_ПАРОЛЬ" } ], "listen": "127.0.0.1", "listen_port": 3065 }, { "type": "mixed", "tag": "mixed_in_proxy", "set_system_proxy": false, "users": [ { "username": "local", "password": "СЮДА_ДЛИННЫЙ_РАНДОМНЫЙ_ПАРОЛЬ" } ], "listen": "127.0.0.1", "listen_port": 3066 }, { "type": "mixed", "tag": "mixed_in_rule", "set_system_proxy": false, "users": [ { "username": "local", "password": "СЮДА_ДЛИННЫЙ_РАНДОМНЫЙ_ПАРОЛЬ" } ], "listen": "127.0.0.1", "listen_port": 3067 } ] ``` **Важно:** - Пароль должен быть одинаковым во всех трёх inbound (Karing использует один пароль для всех) - Это нужно делать **вручную** для каждого профиля - Подключение и стабильность работы это **не затрагивает** - Без этой правки все три порта (3065-3067) открыты для любого приложения > ⚠️ **Важно:** Karing использует нестандартные порты (3065-3067), которых нет в методичке Минцифры. Но скан всех портов localhost — дело секунд. ### О Husi (подтверждённый фикс) **Husi** ([codeberg.org/xchacha20-poly1305/husi](https://codeberg.org/xchacha20-poly1305/husi)) — форк sing-box для Android с поддержкой SOCKS5-аутентификации в UI. Проверено: POC-приложение per-app-split-bypass **не может** обнаружить прокси при включённой аутентификации (скриншот выше). > ⚠️ **Критично:** убедитесь что Husi использует sing-box версии **1.4.5 или выше** — в более ранних версиях есть CVE-2023-43644 (обход аутентификации). См. [раздел 19](#19-cve-2023-43644-обход-аутентификации-sing-box). --- ## 3. Что делать пользователям Android ### Приоритет 1: Немедленно 1. **Удалить Happ** — HandlerService без аутентификации позволяет дампить ваши ключи и IP сервера. Один пользователь с Happ компрометирует весь сервер. 2. **Перейти на клиент с SOCKS5 auth:** - **Husi** (рекомендован) — [codeberg.org/xchacha20-poly1305/husi](https://codeberg.org/xchacha20-poly1305/husi) - **SFA** (sing-box for Android) — ручная настройка JSON - **saeeddev94/xray** — [F-Droid](https://f-droid.org/packages/io.github.saeeddev94.xray/) — ручной JSON 3. **Включить аутентификацию** в настройках клиента (см. конфиги ниже) ### Приоритет 2: Серверная защита 4. Попросить администратора сервера настроить **раздельные IP** (входной ≠ выходной) 5. Убедиться что на сервере **заблокирован geoip:ru на outbound** 6. Использовать маршрутизацию **«Всё кроме РФ»** на клиенте ### Приоритет 3: Изоляция 7. **Российское ПО — на отдельное устройство.** Knox/Shelter/Island **НЕ изолируют loopback**. 8. Если есть root: заблокировать доступ к SOCKS-порту через iptables: ```bash # Разрешить только UID VPN-клиента (например, 10150) iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10808 -m owner --uid-owner 10150 -j ACCEPT iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10808 -j DROP # То же для UDP iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 10808 -m owner --uid-owner 10150 -j ACCEPT iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 10808 -j DROP ``` > UID приложения: `adb shell dumpsys package <package.name> | grep userId` ### Чего НЕ делать - ❌ Не полагаться на смену порта — скан 65535 портов на localhost за секунды - ❌ Не полагаться на Knox/Shelter/Island — loopback общий - ❌ Не полагаться на split tunneling — шпион ходит напрямую на 127.0.0.1 - ❌ Не полагаться на режим инкогнито — не влияет на localhost --- ## 4. Что делать пользователям Windows На Windows ситуация **лучше**, чем на Android: есть Windows Firewall с контролем по процессам. ### Приоритет 1: Firewall 1. **Заблокировать доступ к порту 10808/10809 для всех процессов кроме доверенных:** PowerShell (от администратора): ```powershell # Заблокировать ВСЕ подключения к SOCKS-порту New-NetFirewallRule -DisplayName "Block SOCKS5 10808" ` -Direction Outbound -LocalPort 10808 -Protocol TCP ` -Action Block -Profile Any # Разрешить только xray.exe New-NetFirewallRule -DisplayName "Allow xray SOCKS5" ` -Direction Outbound -LocalPort 10808 -Protocol TCP ` -Program "C:\path\to\xray.exe" -Action Allow -Profile Any # Разрешить браузеру (если нужен прямой SOCKS) New-NetFirewallRule -DisplayName "Allow Firefox SOCKS5" ` -Direction Outbound -LocalPort 10808 -Protocol TCP ` -Program "C:\Program Files\Mozilla Firefox\firefox.exe" ` -Action Allow -Profile Any # То же для HTTP-прокси порта New-NetFirewallRule -DisplayName "Block HTTP proxy 10809" ` -Direction Outbound -LocalPort 10809 -Protocol TCP ` -Action Block -Profile Any New-NetFirewallRule -DisplayName "Allow xray HTTP" ` -Direction Outbound -LocalPort 10809 -Protocol TCP ` -Program "C:\path\to\xray.exe" -Action Allow -Profile Any ``` > **Важно:** правила `Allow` должны быть выше правил `Block` по приоритету. В Windows Firewall `Block` имеет приоритет по умолчанию, поэтому нужно настроить через GPO или использовать `netsh` с правильным порядком. 2. **Альтернатива — xray routing с process name:** В конфиге xray-core на клиенте можно ограничить, какие процессы могут использовать прокси: ```json { "routing": { "rules": [ { "type": "field", "processName": ["firefox", "chrome", "msedge", "telegram"], "outboundTag": "proxy" }, { "type": "field", "processName": ["yandex", "vk", "ozon"], "outboundTag": "block" } ] } } ``` > **Ограничение:** `processName` работает только для локальных подключений (тот же хост). Формат: `"firefox"` (без .exe) или `"C:\\Program Files\\app.exe"` (абсолютный путь). ### Приоритет 2: Конфигурация клиента 3. **Включить SOCKS5 auth** в конфиге (даже на Windows это полезно): В v2rayN: настройки → custom inbound config → изменить `"auth": "noauth"` на `"auth": "password"` + добавить `"accounts"`. 4. **Использовать маршрутизацию «Всё кроме РФ»:** В v2rayN 7.0+: `Настройки → Региональные пресеты → Россия → Всё кроме РФ`. Автоматически скачивает правила из [runetfreedom/russia-v2ray-rules-dat](https://github.com/runetfreedom/russia-v2ray-rules-dat). --- ## 5. Что делать пользователям iOS Ситуация на iOS **самая сложная:** - Большинство клиентов удалено из App Store → обновлений не будет - Нет root → нет iptables - Нет возможности редактировать inbound JSON в большинстве клиентов ### Что можно сделать 1. **Удалить Happ** — самый опасный клиент, удалён из App Store, фикса не будет 2. **Использовать клиенты с поддержкой custom JSON** — если такие ещё установлены 3. **Защита на стороне сервера** — единственная реальная опция: - Раздельные входной/выходной IP - WARP на выходе - geoip:ru → block на сервере ### Особенность iOS Исследователи LocalMess отмечают: iOS **технически уязвима** к тому же вектору (loopback не изолирован), но фоновые приложения iOS **жёстко ограничены** — им сложнее запускать постоянные фоновые сканеры. Это не защита, а лишь усложнение атаки. --- ## 6. Что делать администраторам серверов ### Приоритет 1: Раздельные IP Если у сервера **один IP** — выходной IP = входной IP. Утечка выходного = потеря сервера. **Решение: два IP-адреса.** - Входной IP (для подключения клиентов) → inbound слушает на нём - Выходной IP (для исходящего трафика) → freedom outbound через `sendThrough` ```json { "outbounds": [ { "protocol": "freedom", "sendThrough": "203.0.113.46", "tag": "freedom-out" } ] } ``` Если второй IP недоступен → используйте WARP (раздел 10). ### Приоритет 2: WARP на выходе CloudFlare WARP маскирует выходной IP. Даже если шпион узнает выходной IP через SOCKS5, он получит IP Cloudflare, а не вашего сервера. ### Приоритет 3: Блокировка geoip:ru на outbound Шпионский модуль, пробравшийся через SOCKS5, отправит запрос на российский сервер (для передачи вашего IP в РКН). Если заблокировать исходящий трафик на geoip:ru, шпион не сможет связаться со своим сервером через ваш VPN. ### Приоритет 4: Блокировка Happ На сервере подписок заблокировать UserAgent `Happ/*`. Один пользователь с Happ = компрометация всего сервера (ключи, SNI, входной IP). ### Приоритет 5: Мониторинг Отслеживать нетипичные запросы через прокси: - `ifconfig.me`, `ipinfo.io`, `whatismyip.com`, `api.ipify.org` - Массовые запросы на российские IP - Паттерны, характерные для сканирования --- ## 7. Конфигурации: xray-core клиент ### Безопасный inbound (SOCKS5 с аутентификацией) ```json { "inbounds": [ { "tag": "socks-in", "listen": "127.0.0.1", "port": 10808, "protocol": "socks", "settings": { "auth": "password", "accounts": [ { "user": "xfl_a8b3c2d1", "pass": "p_7e4f91d0c3b8a2e5f6" } ], "udp": false }, "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"], "routeOnly": true } }, { "tag": "http-in", "listen": "127.0.0.1", "port": 10809, "protocol": "http", "settings": { "accounts": [ { "user": "xfl_a8b3c2d1", "pass": "p_7e4f91d0c3b8a2e5f6" } ] }, "sniffing": { "enabled": true, "destOverride": ["http", "tls"], "routeOnly": true } } ] } ``` ### Описание полей | Поле | Значение | Почему | |------|----------|--------| | `"auth": "password"` | Включает аутентификацию | Шпион не сможет подключиться без логина/пароля | | `"accounts"` | `[{user, pass}]` | Рандомные credentials — генерировать при каждом запуске | | `"udp": false` | Отключает UDP | UDP ASSOCIATE не аутентифицирует per-packet (RFC 1928) | | `"listen": "127.0.0.1"` | Только localhost | Никогда `0.0.0.0` — иначе прокси доступен из сети | | `"sniffing"` | Определение протоколов | Нужно для правильной маршрутизации | ### Почему UDP отключён Протокол SOCKS5 (RFC 1928, Section 7) аутентифицирует **только TCP-соединение**. Команда UDP ASSOCIATE создаёт UDP-ретранслятор, но сами UDP-датаграммы **не содержат поля аутентификации**: ``` UDP-датаграмма SOCKS5: +-----+------+------+----------+----------+----------+ | RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | +-----+------+------+----------+----------+----------+ | 2 | 1 | 1 | Variable | 2 | Variable | +-----+------+------+----------+----------+----------+ ↑ Нет поля для логина/пароля ``` xray-core и sing-box **не реализуют** per-packet аутентификацию для UDP. Поэтому при включённой SOCKS5-аутентификации UDP нужно отключать. ### Без UDP — что перестанет работать? - ❌ DNS через SOCKS UDP (решение: использовать DNS over HTTPS/TLS) - ❌ QUIC через SOCKS UDP (решение: fallback на TCP) - ✅ Обычный веб-браузинг работает (TCP) - ✅ Telegram работает (TCP fallback) - ✅ Стриминг работает (TCP) ### «Но ведь пароль передаётся открытым текстом — шпион его перехватит?» **Нет.** Это частый вопрос, основанный на предупреждении из RFC 1929: *«Since the request carries the password in cleartext, this subnegotiation is not recommended for environments where 'sniffing' is possible.»* Но это предупреждение про **сетевой сниффинг** (Wi-Fi, Ethernet), а не про localhost. **На Android без root приложение НЕ может перехватить чужой TCP-трафик на localhost:** | Действие | Без root | Почему | |----------|----------|--------| | Подключиться к чужому порту localhost | ✅ Может | Именно это и есть уязвимость | | **Читать чужой TCP-трафик** на localhost | ❌ **Не может** | Нет raw socket без `CAP_NET_RAW` | | Снифать loopback (tcpdump) | ❌ Не может | Требует root | | Читать fd/память другого процесса | ❌ Не может | Android sandbox, разные UID | | Видеть что порт открыт (/proc/net/tcp) | ✅ Может | Номера портов видны, данные — нет | ``` ┌─────────────────────────────────────────────────┐ │ Android Kernel │ │ │ │ VPN Client (UID 10150) │ │ ├── TCP → 127.0.0.1:10808 │ │ └── "user=abc pass=xyz" ← plaintext │ │ ↑ │ │ Ядро: только UID 10150 видит эти данные │ │ │ │ Шпион (UID 10200) │ │ ├── connect() к :10808 ✅ → нужен пароль → ❌ │ │ └── read() чужого сокета → НЕВОЗМОЖНО │ └─────────────────────────────────────────────────┘ ``` **С root — да, всё плохо:** `tcpdump -i lo port 10808 -A` увидит пароль. Но если у шпиона root, ему не нужен SOCKS5 — он читает конфиг-файлы напрямую, дампит память, контролирует iptables. Root = game over независимо от auth. **Вывод:** SOCKS5 auth на localhost защищает от **прямого подключения** (основной вектор атаки). Перехват plaintext пароля между процессами без root невозможен. Для дополнительной безопасности: генерировать рандомный пароль при каждом запуске (чтобы не утёк из файла/лога). --- ## 8. Конфигурации: sing-box клиент ### Безопасный inbound (mixed с аутентификацией) ```json { "inbounds": [ { "type": "mixed", "tag": "mixed-in", "listen": "127.0.0.1", "listen_port": 2080, "users": [ { "username": "sb_d4c1a7f2", "password": "p_9e2f5b83a1c7d0e4" } ], "set_system_proxy": false } ] } ``` ### Без inbound вообще (если не нужен локальный прокси) Если клиент использует только TUN-режим и вам не нужен локальный SOCKS5-прокси, **удалите mixed inbound полностью**. sing-box **не создаёт** его автоматически — это делают клиенты. ```json { "inbounds": [ { "type": "tun", "tag": "tun-in", "inet4_address": "172.19.0.1/30", "auto_route": true, "strict_route": true, "stack": "system" } ] } ``` Без mixed/socks inbound шпиону нечего сканировать на localhost. ### Разница type: "socks" vs type: "mixed" | | `"socks"` | `"mixed"` | |---|-----------|-----------| | SOCKS4/4a | ✅ | ✅ | | SOCKS5 | ✅ | ✅ | | HTTP proxy | ❌ | ✅ | | `users` (auth) | ✅ | ✅ | | Рекомендация | Если нужен только SOCKS | Если нужен SOCKS + HTTP | --- ## 9. Конфигурации: xray-core сервер ### Безопасный серверный конфиг (VLESS + Reality + WARP + блокировка РФ) ```json { "log": { "loglevel": "warning" }, "api": { "tag": "api", "services": ["StatsService"] }, "stats": {}, "policy": { "levels": { "0": { "statsUserUplink": true, "statsUserDownlink": true } }, "system": { "statsInboundUplink": true, "statsInboundDownlink": true, "statsOutboundUplink": true, "statsOutboundDownlink": true } }, "inbounds": [ { "listen": "0.0.0.0", "port": 443, "protocol": "vless", "settings": { "clients": [ { "id": "ваш-UUID", "email": "[email protected]", "flow": "xtls-rprx-vision" } ], "decryption": "none" }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "show": false, "dest": "www.microsoft.com:443", "xver": 0, "serverNames": ["www.microsoft.com", "microsoft.com"], "privateKey": "ВАШЕ_ЗНАЧЕНИЕ_ИЗ_xray_x25519", "shortIds": ["", "abcdef12"] } }, "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"] }, "tag": "vless-reality-in" }, { "listen": "127.0.0.1", "port": 62789, "protocol": "dokodemo-door", "settings": { "address": "127.0.0.1" }, "tag": "api-in" } ], "outbounds": [ { "protocol": "freedom", "tag": "direct" }, { "protocol": "blackhole", "tag": "block" }, { "protocol": "wireguard", "settings": { "secretKey": "ВАШЕ_WARP_PRIVATE_KEY", "address": ["172.16.0.2/32", "fd01:5ca1:ab1e:823e::/128"], "peers": [ { "publicKey": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", "allowedIPs": ["0.0.0.0/0", "::/0"], "endpoint": "engage.cloudflareclient.com:2408" } ], "reserved": [0, 0, 0], "mtu": 1280 }, "tag": "warp-out" } ], "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "inboundTag": ["api-in"], "outboundTag": "api" }, { "type": "field", "ip": ["geoip:private"], "outboundTag": "block", "ruleTag": "block-private" }, { "type": "field", "ip": ["geoip:ru"], "outboundTag": "block", "ruleTag": "block-russia-ip" }, { "type": "field", "domain": ["regexp:\\.ruquot;, "regexp:\\.рфquot;], "outboundTag": "block", "ruleTag": "block-russia-domains" }, { "type": "field", "protocol": ["bittorrent"], "outboundTag": "block", "ruleTag": "block-torrent" }, { "type": "field", "network": "tcp,udp", "outboundTag": "warp-out", "ruleTag": "default-to-warp" } ] } } ``` ### Что делает каждое правило маршрутизации | Правило | Что блокирует/перенаправляет | Зачем | |---------|------------------------------|-------| | `geoip:private` → block | Частные IP (10.x, 192.168.x, 127.x) | Шпион не сможет «вернуться» на локалку через прокси | | `geoip:ru` → block | Российские IP | Шпион не свяжется с РКН через ваш VPN | | `category-gov-ru` → block | Госсайты РФ | Госсервисы не получат трафик через прокси | | `regexp:\.ru
→ block | Все .ru домены | Дополнительная защита | | `bittorrent` → block | Торренты | Экономия ресурсов, правовая безопасность | | default → warp-out | Весь остальной трафик | Маскировка выходного IP через WARP | ### О API-сервисах ```json "services": ["StatsService"] ``` Включён **только** StatsService для мониторинга трафика. **НЕ включать:** - ❌ `HandlerService` — позволяет дампить конфиги (уязвимость Happ) - ❌ `RoutingService` — позволяет менять маршрутизацию - ❌ `ReflectionService` — позволяет обнаружить доступные API --- ## 10. Конфигурации: CloudFlare WARP на сервере ### Зачем Если шпион всё-таки узнает выходной IP через SOCKS5, он получит IP **Cloudflare WARP**, а не вашего сервера. Ваш реальный IP остаётся скрытым. ### Получение WARP-ключей #### Способ 1: wgcf ```bash # Установка curl -fsSL git.io/wgcf.sh | sudo bash # Регистрация wgcf register wgcf generate # Файл wgcf-profile.conf содержит: # PrivateKey = ВАШЕ_WARP_PRIVATE_KEY # PublicKey = bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo= # Address = 172.16.0.2/32, fd01:5ca1:ab1e:823e::/128 # Endpoint = engage.cloudflareclient.com:2408 ``` #### Способ 2: warp-go (если wgcf не работает) ```bash wget -N https://gitlab.com/fscarmen/warp/-/raw/main/warp-go.sh bash warp-go.sh ``` ### Конфиг WireGuard outbound для xray ```json { "protocol": "wireguard", "settings": { "secretKey": "ЗНАЧЕНИЕ_ИЗ_PrivateKey", "address": [ "172.16.0.2/32", "fd01:5ca1:ab1e:823e::/128" ], "peers": [ { "publicKey": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", "allowedIPs": ["0.0.0.0/0", "::/0"], "endpoint": "engage.cloudflareclient.com:2408" } ], "reserved": [0, 0, 0], "mtu": 1280 }, "tag": "warp-out" } ``` **Параметры:** - `secretKey` — приватный ключ из WARP-регистрации - `address` — IP-адреса туннеля (IPv4 + IPv6) - `peers[0].publicKey` — публичный ключ Cloudflare (фиксированный) - `endpoint` — сервер Cloudflare - `reserved` — обязательно `[0, 0, 0]` (или значения из wgcf) - `mtu` — 1280 для максимальной совместимости ### Маршрутизация: весь трафик через WARP ```json { "routing": { "rules": [ { "type": "field", "network": "tcp,udp", "outboundTag": "warp-out" } ] } } ``` ### Маршрутизация: только определённый трафик через WARP ```json { "routing": { "rules": [ { "type": "field", "domain": ["openai.com", "netflix.com", "spotify.com"], "outboundTag": "warp-out" }, { "type": "field", "network": "tcp,udp", "outboundTag": "direct" } ] } } ``` --- ## 11. Конфигурации: блокировка geoip:ru на сервере ### Полная блокировка (рекомендуется) ```json { "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "ip": ["geoip:ru"], "outboundTag": "block" }, { "type": "field", "domain": [ "geosite:category-gov-ru", "regexp:\\.ruquot;, "regexp:\\.рфquot; ], "outboundTag": "block" } ] }, "outbounds": [ { "protocol": "blackhole", "tag": "block" } ] } ``` ### Расширенная блокировка (с кастомными списками) Проект [runetfreedom/russia-v2ray-rules-dat](https://github.com/runetfreedom/russia-v2ray-rules-dat) предоставляет актуальные списки: ```json { "routing": { "rules": [ { "type": "field", "ip": ["ext:geoip_RU.dat:ru-block"], "outboundTag": "block" }, { "type": "field", "domain": ["ext:geosite_RU.dat:ru-block"], "outboundTag": "block" } ] } } ``` Файлы `geoip_RU.dat` и `geosite_RU.dat` нужно скачать и поместить в директорию ресурсов xray (обычно рядом с `geoip.dat`). ### Зачем блокировать geoip:ru на СЕРВЕРЕ Если шпион на устройстве пользователя подключится к SOCKS5-прокси и попытается передать выходной IP на российский сервер (например, `api.rkn.gov.ru`), запрос уйдёт через VPN-сервер. Если на сервере geoip:ru → block, запрос будет заблокирован — шпион не сможет передать данные. Без этой блокировки шпион может анализировать паттерн трафика, сопоставлять его с логами провайдера и вычислить ваш входной IP. --- ## 12. Конфигурации: маршрутизация «Всё кроме РФ» на клиенте ### xray-core клиент ```json { "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "domain": ["geosite:category-ru"], "outboundTag": "direct", "ruleTag": "ru-sites-direct" }, { "type": "field", "ip": ["geoip:ru"], "outboundTag": "direct", "ruleTag": "ru-ip-direct" }, { "type": "field", "ip": ["geoip:private"], "outboundTag": "direct", "ruleTag": "private-direct" }, { "type": "field", "network": "tcp,udp", "outboundTag": "proxy", "ruleTag": "default-proxy" } ] }, "outbounds": [ { "protocol": "vless", "tag": "proxy", "settings": { "vnext": [{ "address": "ВАШ_СЕРВЕР", "port": 443, "users": [{ "id": "ВАШ_UUID", "encryption": "none", "flow": "xtls-rprx-vision" }] }] }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "fingerprint": "chrome", "serverName": "www.microsoft.com", "publicKey": "ВАШ_PUBLIC_KEY", "shortId": "" } } }, { "protocol": "freedom", "tag": "direct" } ] } ``` ### sing-box клиент (v1.8+) ```json { "route": { "rules": [ { "rule_set": ["geoip-ru", "geosite-ru"], "outbound": "direct" }, { "rule_set": "geoip-private", "outbound": "direct" } ], "rule_set": [ { "tag": "geoip-ru", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-ru.srs" }, { "tag": "geosite-ru", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ru.srs" }, { "tag": "geoip-private", "type": "remote", "format": "binary", "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-private.srs" } ], "final": "proxy" } } ``` > sing-box v1.8+ использует `rule_set` вместо устаревших `geoip`/`geosite` полей. ### v2rayN — настройка пресета 1. Откройте v2rayN → **Настройки** → **Региональные пресеты** 2. Выберите **Россия** 3. Выберите пресет **«Все, кроме РФ»** (RUv1-All except RF) 4. Правила скачаются автоматически из: - GeoIP: `runetfreedom/russia-v2ray-rules-dat` - GeoSite: `nicknameisthekey/russia-v2ray-custom-routing-list` ### Зачем маршрутизация «Всё кроме РФ» на клиенте 1. Российские сайты открываются **напрямую** (быстрее, стабильнее) 2. Шпионский модуль в приложении не может отправить данные через VPN (geoip:ru → direct) 3. Нет заблокированных ресурсов на российских IP (блокировки реализованы иначе) --- ## 13. Блокировка Happ на сервере подписок ### Почему это критично Happ включает **xray API HandlerService без аутентификации**. Через него можно: - Дампить **полный outbound-конфиг** (ключи, IP, SNI) - Узнать **входной IP сервера** (не только выходной) - Потенциально **расшифровать трафик** **Один пользователь с Happ компрометирует ВЕСЬ сервер.** ### xray-core НЕ умеет фильтровать по UserAgent xray-core не имеет встроенной возможности проверять HTTP UserAgent в VLESS/VMess inbound. Фильтрацию нужно делать на уровне **сервера подписок** (nginx/caddy). ### Nginx: блокировка Happ по UserAgent ```nginx # /etc/nginx/conf.d/block-happ.conf map $http_user_agent $is_happ { default 0; ~*Happ 1; ~*Happ/ 1; } server { listen 443 ssl http2; server_name sub.example.com; # SSL конфигурация... # Блокировка Happ if ($is_happ) { return 403 "Access denied"; } location /api/subscribe { # ваша конфигурация подписок proxy_pass http://127.0.0.1:8080; } } ``` ### Caddy: блокировка Happ по UserAgent ```caddy sub.example.com { @happ_blocked header_regexp User-Agent "(?i)Happ" respond @happ_blocked 403 reverse_proxy /api/subscribe localhost:8080 } ``` ### 3x-ui: блокировка (если подписки через панель) Если вы используете 3x-ui и раздаёте подписки через встроенный API — поставьте nginx/caddy перед панелью как reverse proxy и добавьте UserAgent-фильтр. --- ## 14. ГАЙД: v2rayNG — как защититься > **Статус:** v2rayNG 2.0.0 (апрель 2026) — **SOCKS5-аутентификация НЕ поддерживается через UI** ### Текущая ситуация v2rayNG — самый популярный xray-клиент на Android. Он создаёт локальный SOCKS5-прокси на `127.0.0.1:10808` **без аутентификации**. В UI приложения **нет настройки** для включения auth. Последняя версия (2.0.0 от 4 апреля 2026) эту проблему **не исправляет**. Разработчики уведомлены 10 марта 2026 — на 7 апреля фикса нет. ### Вариант A: Custom Config (частичная защита) v2rayNG поддерживает импорт полного xray JSON-конфига. Можно попробовать включить auth через custom config: **Шаг 1.** Создайте файл `config.json` на телефоне (через любой текстовый редактор): ```json { "log": { "loglevel": "warning" }, "inbounds": [ { "tag": "socks-in", "port": 10808, "listen": "127.0.0.1", "protocol": "socks", "settings": { "auth": "password", "accounts": [ { "user": "myuser_r4nd0m", "pass": "mypass_s3cur3_x7k9" } ], "udp": false }, "sniffing": { "enabled": true, "destOverride": ["http", "tls", "quic"], "routeOnly": true } }, { "tag": "http-in", "port": 10809, "listen": "127.0.0.1", "protocol": "http", "settings": { "accounts": [ { "user": "myuser_r4nd0m", "pass": "mypass_s3cur3_x7k9" } ] } } ], "outbounds": [ { "protocol": "vless", "tag": "proxy", "settings": { "vnext": [ { "address": "ВАШ_СЕРВЕР_IP", "port": 443, "users": [ { "id": "ВАШ_UUID", "encryption": "none", "flow": "xtls-rprx-vision" } ] } ] }, "streamSettings": { "network": "tcp", "security": "reality", "realitySettings": { "fingerprint": "chrome", "serverName": "www.microsoft.com", "publicKey": "ВАШ_PUBLIC_KEY", "shortId": "" } } }, { "protocol": "freedom", "tag": "direct" }, { "protocol": "blackhole", "tag": "block" } ], "routing": { "domainStrategy": "IPIfNonMatch", "rules": [ { "type": "field", "ip": ["geoip:ru"], "outboundTag": "direct" }, { "type": "field", "ip": ["geoip:private"], "outboundTag": "direct" }, { "type": "field", "network": "tcp,udp", "outboundTag": "proxy" } ] } } ``` **Шаг 2.** В v2rayNG: нажмите **+** → **Custom config** → **Import custom config from locally** → выберите файл. **Шаг 3.** Нажмите на импортированный конфиг, чтобы активировать его. Нажмите **V** для подключения. ### ⚠️ Важное ограничение Custom Config **v2rayNG может перезаписать ваши inbound-настройки своими дефолтными.** Это известная проблема: - GitHub Issue #275: «Which parts of custom configs are honored?» — ответ: v2rayNG частично перезаписывает inbounds - GitHub Issue #646: «Custom configurations don't work properly» - На практике v2rayNG может проигнорировать `"auth": "password"` и выставить `"noauth"` **Как проверить:** после подключения запустите [POC-приложение](https://github.com/runetfreedom/per-app-split-bypass-poc). Если показывает «VPN not found» / «IP via proxy: -» → auth работает. Если показывает IP → auth перезаписан. ### Вариант B: Смена порта (слабая защита) Если custom config не работает: 1. В v2rayNG: **Настройки** → прокрутите вниз → поле **Local SOCKS5 port** 2. Замените `10808` на **нестандартный** (например, `47293`) 3. HTTP-порт: аналогично замените `10809` на другой **Почему это слабая защита:** - Скан всех 65535 портов — секунды - Но в методичке Минцифры перечислены конкретные порты, и многие POC/шпионы проверяют только известные - Это **не защита**, а **усложнение** — лучше чем ничего ### Вариант C: Перейти на Husi (рекомендация) Если для вас критична защита — **перейти на Husi**: 1. Скачайте Husi: [codeberg.org/xchacha20-poly1305/husi](https://codeberg.org/xchacha20-poly1305/husi/releases) 2. Экспортируйте ссылку из v2rayNG: долгое нажатие на сервер → **Поделиться** → скопируйте VLESS-ссылку 3. В Husi: импортируйте VLESS-ссылку 4. В настройках Husi: включите SOCKS5-аутентификацию (login/password) 5. Проверьте POC — должен показать «VPN not found» ### Вариант D: v2rayNG + AFWall+ (требует root) Если у вас root: ```bash # Узнать UID v2rayNG dumpsys package com.v2ray.ang | grep userId # Например: userId=10150 # Разрешить только v2rayNG подключаться к порту 10808 iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10808 -m owner --uid-owner 10150 -j ACCEPT iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10808 -j DROP iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 10808 -m owner --uid-owner 10150 -j ACCEPT iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 10808 -j DROP # То же для HTTP-порта iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10809 -m owner --uid-owner 10150 -j ACCEPT iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10809 -j DROP ``` > Правила iptables сбрасываются при перезагрузке. Используйте AFWall+ для автоматического применения при старте. ### Сводка по v2rayNG | Метод | Эффективность | Сложность | Root? | |-------|--------------|-----------|-------| | Custom config с auth | ⚠️ Может не работать (v2rayNG перезаписывает) | Средняя | Нет | | Смена порта | 🟡 Слабая (скан все равно найдёт) | Лёгкая | Нет | | Переход на Husi | ✅ **Подтверждённая защита** | Средняя | Нет | | AFWall+ iptables | ✅ Полная защита | Сложная | **Да** | | Отдельное устройство | ✅ Полная изоляция | — | Нет | --- ## 15. ГАЙД: NekoBox — как защититься > **Статус:** NekoBox 1.4.2 (февраль 2026) — **SOCKS5-аутентификация НЕ поддерживается через UI** > **Ядро:** sing-box 1.12.19-neko-1 (CVE-2023-43644 исправлена) > **Nekoray (десктоп):** прекращён, не поддерживается с 2026 года ### Текущая ситуация NekoBox создаёт **mixed inbound** (SOCKS4/4a/5 + HTTP) на `127.0.0.1:2080` **без аутентификации**. В UI нет настройки SOCKS5 auth. Порт 2080 нестандартный (не в методичке Минцифры), но это не защита — скан все равно найдёт. ### Вариант A: Custom sing-box JSON (лучший вариант без root) NekoBox позволяет кастомизировать sing-box конфигурацию. Нужно добавить аутентификацию в mixed inbound: **Шаг 1.** В NekoBox: **Настройки** → **Config Override** (или **Custom Config**) **Шаг 2.** Добавьте в секцию `inbounds` поле `users`: ```json { "inbounds": [ { "type": "mixed", "tag": "mixed-in", "listen": "127.0.0.1", "listen_port": 2080, "users": [ { "username": "neko_x8f2a1", "password": "p_k3m9v7c4b6n1" } ], "sniff": true, "sniff_override_destination": false } ] } ``` **Шаг 3.** Сохраните и перезапустите NekoBox. **Шаг 4.** Проверьте [POC-приложением](https://github.com/runetfreedom/per-app-split-bypass-poc): - «VPN not found» = auth работает ✅ - Показывает IP = auth не применился ❌ ### ⚠️ Важное ограничение NekoBox генерирует sing-box JSON автоматически из UI-настроек. При обновлении конфигурации (смена сервера, обновление подписки) **кастомные inbound могут быть перезаписаны**. Проверяйте auth после каждого изменения. ### Вариант B: Удалить mixed inbound полностью Если вы используете NekoBox **только в TUN-режиме** (весь трафик через VPN), локальный SOCKS5-прокси вам не нужен. Можно попробовать отключить его: 1. В custom config: удалите mixed inbound из `inbounds` 2. Оставьте только TUN inbound: ```json { "inbounds": [ { "type": "tun", "tag": "tun-in", "inet4_address": "172.19.0.1/30", "auto_route": true, "strict_route": true } ] } ``` **Без mixed inbound** шпиону нечего сканировать на localhost — прокси не существует. **Ограничение:** некоторые приложения (Telegram, Firefox с ручной настройкой прокси) могут требовать SOCKS5-прокси напрямую. Без mixed inbound они не смогут подключиться через VPN. ### Вариант C: Смена порта 1. В NekoBox: **Настройки** → **Basic Settings** → **Mixed Port** 2. Замените `2080` на нестандартный (например, `38741`) 3. Перезапустите Та же оговорка: слабая защита, скан найдёт. Но лучше чем дефолтный 2080. ### Вариант D: Переход на Husi Husi — тоже sing-box клиент, конфиги **совместимы**: 1. Скачайте Husi: [codeberg.org/xchacha20-poly1305/husi/releases](https://codeberg.org/xchacha20-poly1305/husi/releases) 2. Экспортируйте конфигурации из NekoBox (подписки, VLESS-ссылки) 3. Импортируйте в Husi 4. Включите SOCKS5-аутентификацию в настройках Husi 5. Проверьте POC **Миграция:** автоматического инструмента нет. Подписки импортируются через ссылки. Routing-правила придётся настроить заново. ### Вариант E: AFWall+ iptables (требует root) ```bash # Узнать UID NekoBox dumpsys package moe.nb4a | grep userId # Например: userId=10200 # Разрешить только NekoBox на порт 2080 iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 2080 -m owner --uid-owner 10200 -j ACCEPT iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 2080 -j DROP iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 2080 -m owner --uid-owner 10200 -j ACCEPT iptables -I OUTPUT -p udp -d 127.0.0.1 --dport 2080 -j DROP ``` ### Nekoray (десктоп) — прекращён Nekoray (десктопная версия) **больше не поддерживается** с 2026 года. Разработчик: «不再维护,自寻替代品» (больше не обслуживается, ищите альтернативы). Альтернативы на десктопе: - **v2rayN** (Windows) — пресет «Все, кроме РФ», ручная правка JSON - **sing-box** CLI (все платформы) — полный контроль конфигурации - **XrayFluent** (Windows) — будет исправлен ### Сводка по NekoBox | Метод | Эффективность | Сложность | Root? | |-------|--------------|-----------|-------| | Custom JSON с users | ⚠️ Работает, но может сброситься при обновлении | Средняя | Нет | | Удаление mixed inbound | ✅ Нет прокси = нечего сканировать | Средняя | Нет | | Смена порта | 🟡 Слабая | Лёгкая | Нет | | Переход на Husi | ✅ **Подтверждённая защита** | Средняя | Нет | | AFWall+ iptables | ✅ Полная защита | Сложная | **Да** | --- ## 16. ГАЙД: Clash/mihomo — как защититься > **Ядро:** mihomo (Clash Meta) — поддерживает SOCKS5 auth нативно > **Проблема:** по дефолту `skip-auth-prefixes` включает `127.0.0.1/8` → **localhost обходит аутентификацию** > **Клиенты:** ClashMeta Android, FlClash, Clash Verge Rev, ClashX Meta ### Текущая ситуация mihomo/Clash — **единственное ядро** с двумя важными преимуществами: 1. **По дефолту `socks-port` выключен** (`# socks-port: 7891` — закомментировано). Дефолтный режим — **rule-based** (правила маршрутизации), без локального SOCKS5-прокси. Шпиону нечего сканировать → **безопасен из коробки**. 2. **Аутентификация поддерживается нативно** через YAML-конфиг — проще чем в xray/sing-box. **НО:** если вы **сами включили** `socks-port` (раскомментировали строку), возникают два сценария: - Без `authentication` → прокси полностью открыт → **уязвим** - С `authentication`, но дефолтным `skip-auth-prefixes: [127.0.0.1/8]` → localhost обходит пароль → **всё ещё уязвим** Поле `skip-auth-prefixes` по дефолту содержит `127.0.0.1/8` и `::1/128` — это by design, localhost считается «доверенной» зоной. Для защиты от шпионского ПО нужно **убрать localhost из skip-auth-prefixes**. ### Фундаментальное отличие от xray/sing-box | | xray/sing-box клиенты | mihomo/Clash клиенты | |---|---|---| | **SOCKS5 по дефолту** | ✅ Всегда включён | ❌ Выключен (TUN-only) | | **Auth по дефолту** | `noauth` (открыт) | N/A (порт не открыт) | | **Риск из коробки** | 🔴 Высокий | 🟢 Низкий | | **Если включить socks-port** | Открыт без auth | Открыт без auth (аналогично) | | **Нативная поддержка auth** | Да, но через JSON | Да, через YAML (проще) | **Вывод:** если вы используете Clash/mihomo в дефолтном TUN-режиме без `socks-port` — **вы не уязвимы**. Проблема возникает только если вы сами включили SOCKS5-порт. ### Дефолтные порты mihomo | Порт | Тип | Описание | |------|-----|----------| | `7890` | HTTP(S) | HTTP-прокси | | `7891` | SOCKS5 | SOCKS5-прокси | | `10801` (или `7892`) | Mixed | HTTP + SOCKS5 на одном порту | | `7892` | Redirect | Прозрачный прокси | | `7893` | TProxy | Только Linux/Android | ### Уязвимая конфигурация (дефолт) ```yaml # ❌ УЯЗВИМО: localhost обходит auth port: 7890 socks-port: 7891 mixed-port: 10801 authentication: - "user:password" # Вот в чём проблема — дефолтные значения: skip-auth-prefixes: - 127.0.0.1/8 - ::1/128 ``` Даже с `authentication` шпион с localhost подключится **без пароля** через `skip-auth-prefixes`. ### Безопасная конфигурация (Вариант 1: глобальная) ```yaml port: 7890 socks-port: 7891 mixed-port: 10801 allow-lan: false # Не слушать на 0.0.0.0 bind-address: 127.0.0.1 # Только localhost authentication: - "clash_x8f2a:p_k3m9v7c4b6" # ✅ КРИТИЧНО: убрать localhost из skip-auth-prefixes skip-auth-prefixes: [] # Пустой массив = auth для ВСЕХ ``` > ⚠️ **Побочный эффект:** некоторые приложения (Telegram, браузеры с настроенным прокси) могут потребовать ввод логина/пароля для подключения к локальному прокси. Если используете TUN-режим — это не проблема. ### Безопасная конфигурация (Вариант 2: per-listener) Более гибкий подход — настроить auth на уровне отдельных listeners: ```yaml listeners: - name: socks-local type: socks port: 7891 listen: 127.0.0.1 users: - username: clash_local password: s3cur3_p4ss_x7k9 - name: mixed-local type: mixed port: 10801 listen: 127.0.0.1 udp: true users: - username: clash_local password: s3cur3_p4ss_x7k9 - name: http-local type: http port: 7890 listen: 127.0.0.1 users: - username: clash_local password: s3cur3_p4ss_x7k9 ``` > ⚠️ **Верификацией установлено:** per-listener `users` перезаписывает глобальный `authentication`, но **может НЕ перезаписывать** `skip-auth-prefixes`. Глобальный `skip-auth-prefixes` применяется на уровне сети и может обходить даже per-listener auth. **Рекомендация:** всегда устанавливать `skip-auth-prefixes: []` глобально, даже при использовании per-listener `users`. ### Инструкция по клиентам **ClashMeta for Android** (v2.11.25+): 1. Откройте конфиг (Profile → Edit) 2. Добавьте `authentication` и `skip-auth-prefixes: []` 3. Или используйте `listeners` с `users` 4. Сохраните и перезапустите **Clash Verge Rev** (Windows/macOS/Linux): 1. Профиль → правый клик → «Open File» 2. Отредактируйте YAML 3. Или: Settings → Merge Config → добавьте override **FlClash:** 1. Аналогично — редактирование YAML профиля 2. Документация: [flclash.cc](https://flclash.cc/) ### Известные CVE Clash/mihomo | CVE | Описание | Затронуто | |-----|----------|-----------| | **CVE-2024-5732** | Clash ≤ 0.20.1 Windows — обход аутентификации на Proxy Port (удалённый доступ) | Clash (не mihomo) | | **CVE-2025-50505** | Clash Verge Rev — уязвимость API | Clash Verge Rev | | **mihomo-party macOS** | Привилегированный UNIX-сокет `/tmp/mihomo-party-helper.sock` с world-rw правами, без аутентификации → перехват трафика | mihomo-party < 1.8.1 | ### Безопасность API mihomo ```yaml # config.yaml external-controller: 127.0.0.1:9090 secret: "ваш_секретный_токен" ``` > ⚠️ **Важно:** API-аутентификация через `Authorization: Bearer {secret}` **НЕ проверяется** при подключении через Unix-сокет или Windows named pipe. Защита — только file permissions (0600). ### Сводка по Clash/mihomo | Метод | Эффективность | Сложность | |-------|--------------|-----------| | `authentication` + `skip-auth-prefixes: []` | ✅ Полная защита | Лёгкая (3 строки YAML) | | Per-listener `users` | ✅ Полная, гибкая | Средняя | | Только смена порта | 🟡 Слабая | Лёгкая | | TUN без SOCKS-прокси | ✅ Нет прокси = нечего сканировать | Средняя | **Вывод:** Clash/mihomo — **лучшая ситуация** из всех ядер. Auth поддерживается нативно, фикс — 3 строки в YAML. Нужно только убрать `127.0.0.1/8` из `skip-auth-prefixes`. --- ## 17. Фаерволы на Android: что реально работает ### Без root: почти ничего | Приложение | Блокирует localhost? | Почему | |------------|---------------------|--------| | **NetGuard** (VPN-based) | ❌ **Нет** | Android VPN API не перехватывает localhost-трафик. VPN видит только трафик через сетевые интерфейсы, а loopback (127.0.0.1) — внутренний | | **RethinkDNS** (VPN-based) | ❌ **Нет** | Та же причина — VPN API не покрывает localhost | | **Blokada** (VPN-based) | ❌ **Нет** | Аналогично | | **AdGuard** (VPN-based) | ❌ **Нет** (localhost) | Но блокирует скрипты Meta Pixel/Яндекс.Метрики на уровне DNS/HTTP — **полезно против трекинга** | **Почему VPN-based фаерволы не помогают:** ``` ┌─────────────────────────────────────────────────────┐ │ Android │ │ │ │ Приложение A ──→ 127.0.0.1:10808 ──→ xray/sing-box│ │ ↑ │ │ │ ← Это localhost, не проходит через VPN API │ │ │ │ │ NetGuard/RethinkDNS (VPN) перехватывают ТОЛЬКО: │ │ eth0, wlan0, rmnet0 (реальные интерфейсы) │ │ ↓ │ │ Приложение B ──→ google.com ──→ [VPN перехватывает]│ └─────────────────────────────────────────────────────┘ ``` Loopback-интерфейс — **внутренний**, он не маршрутизируется через VPN-тоннель. VPN API от Google **by design** не перехватывает localhost. ### С root: AFWall+ (iptables) **AFWall+** ([github.com/ukanth/afwall](https://github.com/ukanth/afwall)) использует iptables **напрямую в ядре Linux**, минуя Android VPN API. Это единственный способ заблокировать localhost-доступ на Android. **Установка:** 1. Убедитесь что есть root (Magisk/KernelSU) 2. Установите AFWall+ из F-Droid или GitHub 3. Откройте → разрешите root-доступ 4. Режим: **Whitelist** (разрешить только выбранным) **Настройка кастомных правил:** В AFWall+: **Меню** → **Set custom script** → добавьте: ```bash # Защита SOCKS5-порта v2rayNG (10808) # Разрешить только UID v2rayNG (замените 10150 на реальный UID) iptables -I "afwall" -p tcp -d 127.0.0.1 --dport 10808 -m owner --uid-owner 10150 -j ACCEPT iptables -I "afwall" -p tcp -d 127.0.0.1 --dport 10808 -j REJECT # Защита HTTP-порта v2rayNG (10809) iptables -A "afwall" -p tcp -d 127.0.0.1 --dport 10809 -m owner --uid-owner 10150 -j ACCEPT iptables -A "afwall" -p tcp -d 127.0.0.1 --dport 10809 -j REJECT # Защита mixed-порта NekoBox (2080) # (замените 10200 на реальный UID NekoBox) iptables -A "afwall" -p tcp -d 127.0.0.1 --dport 2080 -m owner --uid-owner 10200 -j ACCEPT iptables -A "afwall" -p tcp -d 127.0.0.1 --dport 2080 -j REJECT ``` **Как узнать UID приложения:** ```bash # Через adb adb shell dumpsys package com.v2ray.ang | grep userId # userId=10150 adb shell dumpsys package moe.nb4a | grep userId # userId=10200 ``` Или в AFWall+ UI: каждое приложение показывает свой UID в скобках. **Важно:** правила iptables сбрасываются при перезагрузке. AFWall+ автоматически применяет кастомный скрипт при каждом старте — поэтому используйте именно AFWall+, а не ручные iptables. ### Без root: что хоть немного помогает 1. **AdGuard DNS** — блокирует скрипты Meta Pixel и Яндекс.Метрики, которые могут обнаруживать VPN через localhost. Не защищает от прямого сканирования шпионским модулем, но убирает трекинг из браузера. 2. **Brave Browser** — с 2022 года блокирует запросы к localhost из веб-страниц. Защищает от трекинга Meta/Яндекс через браузер, но не от нативного шпионского приложения. 3. **Отдельное устройство** — физическая изоляция. Российское ПО на одном телефоне, VPN на другом. Loopback не пересекается между устройствами. --- ## 18. FAQ: hev-socks5-tunnel, Karing, Husi, v2rayN ### Q: Как включить auth, если я не владелец подписки? **A: Владение подпиской НЕ имеет значения.** SOCKS5-аутентификация на local inbound — это **чисто клиентская настройка**. Она защищает локальный прокси на ВАШЕМ устройстве от других приложений. Сервер подписки об этом даже не знает. ``` СЕРВЕР (владелец подписки) ВАШЕ УСТРОЙСТВО (вы контролируете) ┌──────────────────────┐ ┌──────────────────────────────┐ │ VLESS Reality inbound│◄──────────│ xray outbound (VLESS) │ │ Вы НЕ контролируете │ туннель │ │ └──────────────────────┘ │ SOCKS5 inbound ← ВОТ ЭТО │ │ localhost:10808 ВАШЕ │ │ auth: password ← МЕНЯТЬ ТУТ │ └──────────────────────────────┘ ``` **Реальная проблема:** при обновлении подписки некоторые клиенты перегенерируют конфиг и могут **сбросить** ваши кастомные inbound-настройки. Но это зависит от клиента: - **v2rayN** (Windows) ✅ — хранит inbound-настройки (`Config.Inbound`) в `guiNConfig.json` **отдельно** от подписок (SQLite `guiN.db`). Auth **не сбрасывается** при обновлении подписки. Архитектура подтверждена через DeepWiki и исходный код. - **Clash/mihomo** ✅ — `authentication` и `skip-auth-prefixes` в глобальной секции config.yaml. `proxy-providers` (подписки) обновляют **только список прокси**, не трогая глобальный конфиг. Clash Verge Rev дополнительно защищает глобальные настройки через Merge-профили. - **Husi** (Android) ⚠️ — вероятно сохраняет auth в настройках приложения, но **документально не подтверждено**. Рекомендуется проверить auth после каждого обновления подписки. - **v2rayNG** (Android) ⚠️ — custom config **проблематичен**. Известные проблемы: нет документации какие секции custom config реально применяются — пользователи вынуждены спрашивать ([#275](https://github.com/2dust/v2rayNG/issues/275) — «How to use custom config feature?»), краши при кастомных DNS-конфигурациях ([#1911](https://github.com/2dust/v2rayNG/issues/1911) — «V2ray Crash When using custom config»), игнорирование кастомных DNS при включённом local DNS ([#3670](https://github.com/2dust/v2rayNG/issues/3670)). Прямых доказательств перезаписи auth при обновлении подписки не найдено, но стабильность custom config не гарантирована — **не рекомендуется** как единственный метод защиты. Надёжнее перейти на Husi. ### Q: Нужно ли просить админа сервера что-то менять? **A:** Для защиты local inbound — **нет**. Но для полной защиты **рекомендуется** попросить админа: - Настроить раздельные входной/выходной IP (или WARP) - Заблокировать geoip:ru на outbound - Заблокировать Happ по UserAgent ### Q: v2rayNG использует hev-socks5-tunnel — в нём та же уязвимость? **A:** `hev-socks5-tunnel` — это библиотека tun2socks, которая **сама по себе поддерживает** SOCKS5-аутентификацию (username/password). Уязвимость не в библиотеке, а в том что **v2rayNG не включает аутентификацию** на SOCKS5 inbound xray-core. hev-socks5-tunnel подключается к xray-core inbound `127.0.0.1:10808` с `noauth` — и шпион может сделать то же самое. **Чтобы исправить:** - v2rayNG должен добавить `"auth": "password"` в xray inbound - И передать те же credentials в конфиг hev-socks5-tunnel - Пока этого нет — v2rayNG уязвим ### Q: Karing уязвим? **A:** Скорее всего **да**. Karing использует ядро sing-box и создаёт три mixed inbound на `127.0.0.1:3065`, `127.0.0.1:3066`, `127.0.0.1:3067`. В UI Karing **нет настройки SOCKS5 auth**. Защита возможна через ручную правку JSON-конфига — добавить `users` с паролем ко всем трём inbound. Подробная инструкция с JSON-примером — см. [раздел 2, «О Karing (sing-box)»](#о-karing-sing-box). Порты 3065-3067 нестандартные (не в методичке Минцифры), но скан всех портов — секунды. ### Q: Husi — действительно безопасен? **A:** Husi — единственный Android-клиент с **подтверждённой** SOCKS5-аутентификацией в UI. POC-приложение не смогло обнаружить прокси при включённой аутентификации. **НО:** 1. Убедитесь что используется sing-box **v1.4.5+** — в более ранних есть CVE-2023-43644 (обход auth) 2. UDP ASSOCIATE всё равно не аутентифицируется per-packet — лучше отключить 3. Аутентификация — не панацея, а барьер. Сложную атаку она не остановит ### Q: В v2rayN на Windows можно включить SOCKS5 auth? **A:** Да, начиная с v7.0+, через ручную правку конфига: 1. Настройки → параметры ядра → кастомный inbound 2. Изменить `"auth": "noauth"` на `"auth": "password"` 3. Добавить `"accounts": [{"user": "xxx", "pass": "yyy"}]` 4. Сохранить и перезапустить Также в v2rayN 7.0+ есть пресет «Все, кроме РФ» в региональных настройках. ### Q: Как v2rayN реализует «Все, кроме РФ»? **A:** Настройки → Региональные пресеты → Россия. Скачивает правила из: - [runetfreedom/russia-v2ray-rules-dat](https://github.com/runetfreedom/russia-v2ray-rules-dat) — geoip - [nicknameisthekey/russia-v2ray-custom-routing-list](https://github.com/nicknameisthekey/russia-v2ray-custom-routing-list) — geosite Правила: `geoip:ru → direct`, `geosite:ru → direct`, всё остальное → proxy. --- ## 19. CVE-2023-43644: обход аутентификации sing-box ### Критическая уязвимость **CVE-2023-43644** — Missing Authentication for Critical Function в sing-box SOCKS5 inbound. | | | |---|---| | **CVSS** | 9.1 (Critical) | | **Затронуто** | sing-box < 1.4.5, sing-box < 1.5.0-rc.5 | | **Исправлено** | sing-box ≥ 1.4.5, sing-box ≥ 1.5.0-rc.5 | | **Суть** | Атакующий может обойти SOCKS5-аутентификацию специально сформированным запросом | | **Источник** | [GHSA-r5hm-mp3j-285g](https://github.com/advisories/GHSA-r5hm-mp3j-285g) | ### Техническая суть В функции `HandleConnection0` (файл `protocol/socks/handshake.go`) обработка запросов продолжалась **даже после неудачной аутентификации**. Не проверялся код статуса аутентификации. ### Кого затрагивает - **Husi** — если использует старую версию sing-box (до 1.4.5) - **Karing** — если использует старую версию sing-box - **SFA** — если использует старую версию sing-box - **Все клиенты на базе sing-box** с SOCKS5 inbound ### Как проверить версию В sing-box клиенте: настройки → о программе → версия ядра. Должна быть **≥ 1.4.5**. ### Рекомендация Даже если вы включили SOCKS5 auth — **обновите sing-box**. На старых версиях аутентификация обходится. --- ## 20. Чеклист действий ### Для пользователей - [ ] Удалить Happ (если установлен) - [ ] Перейти на клиент с SOCKS5 auth (Husi, SFA, saeeddev94/xray) - [ ] Включить аутентификацию на SOCKS5 inbound - [ ] Отключить UDP в SOCKS5 (или убедиться что не критично) - [ ] Включить маршрутизацию «Все, кроме РФ» на клиенте - [ ] Российское ПО — на отдельное устройство (Android) - [ ] На Windows: настроить Firewall по процессам - [ ] Убедиться что sing-box ≥ 1.4.5 (если на sing-box) ### Для администраторов серверов - [ ] Настроить раздельные входной/выходной IP (или WARP) - [ ] Заблокировать geoip:ru на outbound - [ ] Заблокировать geoip:private на outbound - [ ] Заблокировать .ru/.рф домены на outbound - [ ] Заблокировать Happ по UserAgent на сервере подписок - [ ] Убрать HandlerService из API (оставить только StatsService) - [ ] Убрать ReflectionService из API - [ ] Включить WARP как outbound (маскировка выходного IP) - [ ] Мониторить запросы к ifconfig.me/ipinfo.io через прокси ### Для разработчиков клиентов - [ ] Включить `"auth": "password"` по умолчанию - [ ] Генерировать рандомные credentials при каждом запуске - [ ] Отключить UDP в SOCKS5 или реализовать per-packet auth - [ ] Рандомизировать порт (не стандартные 10808/2080/1080) - [ ] Слушать только на `127.0.0.1` (никогда `0.0.0.0`) - [ ] Не включать HandlerService в xray API - [ ] Обновить sing-box до ≥ 1.4.5 (CVE-2023-43644) --- ## Источники ### Документация протоколов - [RFC 1928 — SOCKS Protocol Version 5](https://www.rfc-editor.org/rfc/rfc1928) - [RFC 1929 — Username/Password Auth for SOCKS V5](https://www.rfc-editor.org/rfc/rfc1929) - [xray-core SOCKS inbound](https://xtls.github.io/en/config/inbounds/socks.html) - [xray-core Routing](https://xtls.github.io/en/config/routing.html) - [xray-core Freedom outbound](https://xtls.github.io/en/config/outbounds/freedom.html) - [xray-core WireGuard outbound](https://xtls.github.io/en/config/outbounds/wireguard.html) - [xray-core API](https://xtls.github.io/en/config/api.html) - [xray-core WARP guide](https://xtls.github.io/en/document/level-2/warp.html) - [sing-box SOCKS inbound](https://sing-box.sagernet.org/configuration/inbound/socks/) - [sing-box Mixed inbound](https://sing-box.sagernet.org/configuration/inbound/mixed/) - [sing-box Route rules](https://sing-box.sagernet.org/configuration/route/rule/) ### Уязвимости и исследования - [CVE-2023-43644 — sing-box SOCKS5 auth bypass](https://github.com/advisories/GHSA-r5hm-mp3j-285g) - [localmess.github.io — Meta/Яндекс localhost-трекинг](https://localmess.github.io/) - [Habr: Критическая уязвимость VLESS клиентов](https://habr.com/ru/articles/1020080/) - [POC: per-app-split-bypass](https://github.com/runetfreedom/per-app-split-bypass-poc) ### Клиенты - [Husi (Codeberg)](https://codeberg.org/xchacha20-poly1305/husi) - [saeeddev94/xray (F-Droid)](https://f-droid.org/packages/io.github.saeeddev94.xray/) - [Karing](https://github.com/KaringX/karing) - [hev-socks5-tunnel](https://github.com/heiher/hev-socks5-tunnel) - [v2rayN](https://github.com/2dust/v2rayN) ### GeoIP/GeoSite правила - [runetfreedom/russia-v2ray-rules-dat](https://github.com/runetfreedom/russia-v2ray-rules-dat) - [nicknameisthekey/russia-v2ray-custom-routing-list](https://github.com/nicknameisthekey/russia-v2ray-custom-routing-list) - [Loyalsoldier/v2ray-rules-dat](https://github.com/Loyalsoldier/v2ray-rules-dat) ### Серверные панели - [3x-ui](https://github.com/MHSanaei/3x-ui) - [3x-ui WARP setup](https://3x-ui.com/)