Практическое руководство: защита VPN от localhost-атаки

Дата: 7 апреля 2026
Контекст: Уязвимость VLESS-клиентов + эксплуатация localhost Meta/Яндексом
Аудитория: Пользователи VPN, администраторы серверов, разработчики клиентов
Связанные заметки:


Оглавление

  1. Суть проблемы за 30 секунд
  2. Проверенные клиенты: кто уязвим, кто нет
  3. Что делать пользователям Android
  4. Что делать пользователям Windows
  5. Что делать пользователям iOS
  6. Что делать администраторам серверов
  7. Конфигурации: xray-core клиент
  8. Конфигурации: sing-box клиент
  9. Конфигурации: xray-core сервер
  10. Конфигурации: CloudFlare WARP на сервере
  11. Конфигурации: блокировка geoip:ru на сервере
  12. Конфигурации: маршрутизация «Всё кроме РФ» на клиенте
  13. Блокировка Happ на сервере подписок
  14. ГАЙД: v2rayNG — как защититься
  15. ГАЙД: NekoBox — как защититься
  16. ГАЙД: Clash/mihomo — как защититься
  17. Фаерволы на Android: что реально работает
  18. FAQ: hev-socks5-tunnel, Karing, Husi, v2rayN
  19. CVE-2023-43644: обход аутентификации sing-box
  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.0xray10808❌ Нет в UI. ⚠️ Custom config — ненадёжно (v2rayNG может перезаписать inbound)🟡 УязвимПерейти на Husi; или AFWall+ (root)
Hiddify 4.1.1sing-box + xray?❌ Нет в UI🟡 УязвимПерейти на Husi/SFA
NekoBox 1.4.2sing-box 1.12.192080❌ Нет в UI. ⚠️ Custom JSON — возможно, но сбрасывается при обновлении🟡 УязвимПерейти на Husi; или удалить mixed inbound
Npv Tunnelxray?❌ Нет🟡 УязвимПерейти на Husi/SFA
v2RayTun 5.19.64xray?⚠️ Ядро поддерживает, UI — неизвестно🟡 Скорее уязвимУточнить у разработчика
Happxray?❌ + API HandlerService без auth🔴 УДАЛИТЬ НЕМЕДЛЕННОДамп ключей, IP, SNI
Karingsing-box3067⚠️ Ядро поддерживает, в UI нет настройки🟡 Скорее уязвимПроверить custom JSON
Exclavesing-box?✅ Да (через конфиг)🟢 Можно настроитьНастроить auth в конфиге
Husi 1.1.0sing-box (dun)?✅ Да, есть в UI🟢 РекомендованВключить auth в настройках
SFA 1.13.6sing-box?✅ Да (JSON)🟢 Можно настроитьРучная правка JSON
saeeddev94/xrayxray?✅ Да (JSON + UI)🟢 Можно настроитьF-Droid, настроить auth
v2RayTun 5.20.67xray?❌ Нет в UI. Разработчик обещал фикс (март 2026), пока нет🟡 УязвимЖдать фикса или перейти. ⚠️ Шлёт домены подписок на свои сервера
ClashMeta Android 2.11.25mihomo—✅ Да (YAML). По дефолту socks-port выключен (TUN-only) → прокси нет → нечего сканировать🟢 Безопасен по дефолтуЕсли включили socks-port — добавить auth + убрать skip-auth-prefixes
FlClashmihomo—✅ Да (YAML). Аналогично — дефолт TUN-only🟢 Безопасен по дефолтуАналогично ClashMeta
Incy 2.0.8xray 26.3.27?⚠️ Ядро поддерживает, UI-настройка auth не документирована🟡 Вероятно уязвимНужна проверка — closed-source-подобный
anet 0.4.2Собственный (Rust/ASTP)—✅ Не применимо🟢 Не уязвимНет SOCKS5/HTTP прокси на localhost. Чистый TUN через собственный протокол

Windows / Desktop

КлиентЯдроПортSOCKS5 authСтатусЧто делать
v2rayN 7.20.2xray/sing-box10808✅ Да (JSON + UI)🟢 Можно настроитьВключить auth + Windows Firewall
Nekoraysing-box/xray?❌ Нет в UI🔴 Заброшен (2026)Перейти на Throne / v2rayN / Clash Verge Rev
Throne 1.1.1 (март 2026)sing-box (основной) + xray (для VLESS)2080⚠️ Дефолтный mixed нельзя отключить, но можно создать кастомный inbound с auth🟡 Уязвим по дефолту, можно настроитьСоздать кастомный inbound с auth; заблокировать дефолтный фаерволом
XrayFluentxray10808❌ Нет🟡 УязвимБудет исправлено
Karing (Windows)sing-box3067/3066⚠️ Ядро поддерживает, UI-настройка не подтверждена🟡 Вероятно уязвимПроверить custom JSON
Clash Verge Revmihomo—✅ Да (YAML). По дефолту TUN-only, socks-port выключен🟢 Безопасен по дефолтуЕсли включили socks-port — добавить auth + убрать skip
ClashX Meta (macOS)mihomo—✅ Да (YAML). Аналогично🟢 Безопасен по дефолтуАналогично
Incy (Desktop) 2.0.8xray 26.3.27?⚠️ Не документировано🟡 Нужна проверка—

iOS

КлиентЯдроПортSOCKS5 authСтатусЧто делать
Happxray?❌ + API без auth🔴 УДАЛИТЬУдалено из российского App Store; в других регионах может быть доступно, но фикса не будет
V2BOX 5.3.4xray?❌ Нет подтверждения🟡 Скорее уязвимНет решения
RabbitHole 1.3.0? (closed-source)?⚠️ Неизвестно❓ Нужна проверкаClosed-source, поддерживает SOCKS5 — нужна проверка POC
ShadowrocketiOS VPN framework—⚠️ Вероятно не применимо (iOS sandbox)🟢/❓ Скорее не уязвим, нужна проверка POCiOS 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) — это 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). v2.0.8 (7 апреля 2026). Поддерживает VLESS Reality, VMess, Trojan, SS, Hysteria2, WireGuard. Auth-статус на локальном inbound не документирован — нужна проверка.

Throne (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) — полностью кастомный 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:

"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) — форк sing-box для Android с поддержкой SOCKS5-аутентификации в UI. Проверено: POC-приложение per-app-split-bypass не может обнаружить прокси при включённой аутентификации (скриншот выше).

⚠️ Критично: убедитесь что Husi использует sing-box версии 1.4.5 или выше — в более ранних версиях есть CVE-2023-43644 (обход аутентификации). См. раздел 19.


3. Что делать пользователям Android

Приоритет 1: Немедленно

  1. Удалить Happ — HandlerService без аутентификации позволяет дампить ваши ключи и IP сервера. Один пользователь с Happ компрометирует весь сервер. По коду приложения (подробный разбор) эта служба убрана уже в версии 3.16.2 от 7 апреля 2026 года — но закрытый код, собственные домены телеметрии и SOCKS5 без пароля по умолчанию у Happ остаются актуальными претензиями.

  2. Перейти на клиент с SOCKS5 auth:

  3. Включить аутентификацию в настройках клиента (см. конфиги ниже)

Приоритет 2: Серверная защита

  1. Попросить администратора сервера настроить раздельные IP (входной ≠ выходной)
  2. Убедиться что на сервере заблокирован geoip:ru на outbound
  3. Использовать маршрутизацию «Всё кроме РФ» на клиенте

Приоритет 3: Изоляция

  1. Российское ПО — на отдельное устройство. Knox/Shelter/Island НЕ изолируют loopback.
  2. Если есть root: заблокировать доступ к SOCKS-порту через iptables:
    # Разрешить только 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 (от администратора):

    # Заблокировать ВСЕ подключения к 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 на клиенте можно ограничить, какие процессы могут использовать прокси:

    {
      "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: Конфигурация клиента

  1. Включить SOCKS5 auth в конфиге (даже на Windows это полезно):

    В v2rayN: настройки → custom inbound config → изменить "auth": "noauth" на "auth": "password" + добавить "accounts".

  2. Использовать маршрутизацию «Всё кроме РФ»:

    В v2rayN 7.0+: Настройки → Региональные пресеты → Россия → Всё кроме РФ. Автоматически скачивает правила из 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
{
  "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 с аутентификацией)

{
  "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Отключает UDPUDP 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-датаграмма (RFC 1928, раздел 7):

RSVFRAGATYPDST.ADDRDST.PORTDATA
2 байта11переменный2переменный

В датаграмме нет поля для логина и пароля.

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)✅ МожетНомера портов видны, данные — нет
Пароль на localhost защищён изоляцией процессов Android VPN-клиент с UID 10150 подключается к 127.0.0.1:10808 с паролем открытым текстом, но данные видит только ядро и этот UID. Шпион с UID 10200 может сделать connect к порту, но ему нужен пароль, а читать чужой сокет он не может. VPN-клиент (UID 10150) TCP → 127.0.0.1:10808 «user=abc pass=xyz» — открытым текстом ядро: только 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 с аутентификацией)

{
  "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 не создаёт его автоматически — это делают клиенты.

{
  "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 + блокировка РФ)

{
  "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": "user@example.com",
            "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:\\.ru$", "regexp:\\.рф$"],
        "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-сервисах

"services": ["StatsService"]

Включён только StatsService для мониторинга трафика. НЕ включать:

  • ❌ HandlerService — позволяет дампить конфиги (уязвимость Happ)
  • ❌ RoutingService — позволяет менять маршрутизацию
  • ❌ ReflectionService — позволяет обнаружить доступные API

10. Конфигурации: CloudFlare WARP на сервере

Зачем

Если шпион всё-таки узнает выходной IP через SOCKS5, он получит IP Cloudflare WARP, а не вашего сервера. Ваш реальный IP остаётся скрытым.

Получение WARP-ключей

Способ 1: wgcf

# Установка
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 не работает)

wget -N https://gitlab.com/fscarmen/warp/-/raw/main/warp-go.sh
bash warp-go.sh

Конфиг WireGuard outbound для xray

{
  "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

{
  "routing": {
    "rules": [
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "warp-out"
      }
    ]
  }
}

Маршрутизация: только определённый трафик через WARP

{
  "routing": {
    "rules": [
      {
        "type": "field",
        "domain": ["openai.com", "netflix.com", "spotify.com"],
        "outboundTag": "warp-out"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "direct"
      }
    ]
  }
}

11. Конфигурации: блокировка geoip:ru на сервере

Полная блокировка (рекомендуется)

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:ru"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "domain": [
          "geosite:category-gov-ru",
          "regexp:\\.ru$",
          "regexp:\\.рф$"
        ],
        "outboundTag": "block"
      }
    ]
  },
  "outbounds": [
    {
      "protocol": "blackhole",
      "tag": "block"
    }
  ]
}

Расширенная блокировка (с кастомными списками)

Проект runetfreedom/russia-v2ray-rules-dat предоставляет актуальные списки:

{
  "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 клиент

{
  "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+)

{
  "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

# /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

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 на телефоне (через любой текстовый редактор):

{
  "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-приложение. Если показывает «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
  2. Экспортируйте ссылку из v2rayNG: долгое нажатие на сервер → Поделиться → скопируйте VLESS-ссылку
  3. В Husi: импортируйте VLESS-ссылку
  4. В настройках Husi: включите SOCKS5-аутентификацию (login/password)
  5. Проверьте POC — должен показать «VPN not found»

Вариант D: v2rayNG + AFWall+ (требует root)

Если у вас root:

# Узнать 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:

{
  "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-приложением:

  • «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:
{
  "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
  2. Экспортируйте конфигурации из NekoBox (подписки, VLESS-ссылки)
  3. Импортируйте в Husi
  4. Включите SOCKS5-аутентификацию в настройках Husi
  5. Проверьте POC

Миграция: автоматического инструмента нет. Подписки импортируются через ссылки. Routing-правила придётся настроить заново.

Вариант E: AFWall+ iptables (требует root)

# Узнать 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

ПортТипОписание
7890HTTP(S)HTTP-прокси
7891SOCKS5SOCKS5-прокси
10801 (или 7892)MixedHTTP + SOCKS5 на одном порту
7892RedirectПрозрачный прокси
7893TProxyТолько Linux/Android

Уязвимая конфигурация (дефолт)

# ❌ УЯЗВИМО: 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: глобальная)

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:

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

Известные CVE Clash/mihomo

CVEОписаниеЗатронуто
CVE-2024-5732Clash ≤ 0.20.1 Windows — обход аутентификации на Proxy Port (удалённый доступ)Clash (не mihomo)
CVE-2025-50505Clash Verge Rev — уязвимость APIClash Verge Rev
mihomo-party macOSПривилегированный UNIX-сокет /tmp/mihomo-party-helper.sock с world-rw правами, без аутентификации → перехват трафикаmihomo-party < 1.8.1

Безопасность API mihomo

# 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 фаерволы не помогают:

Без root блокировщики не видят localhost Приложение A обращается на 127.0.0.1:10808 к xray или sing-box: это localhost, он не проходит через VPN API. NetGuard и RethinkDNS как VPN перехватывают только реальные интерфейсы eth0, wlan0 и rmnet0, поэтому трафик приложения B к google.com они видят, а локальные обращения нет. Приложение A → 127.0.0.1:10808 это localhost: не проходит через VPN API блокировщики локальный трафик не видят Приложение B → google.com VPN перехватывает: eth0, wlan0, rmnet0 NetGuard и RethinkDNS видят только реальныеинтерфейсы

Loopback-интерфейс — внутренний, он не маршрутизируется через VPN-тоннель. VPN API от Google by design не перехватывает localhost.

С root: AFWall+ (iptables)

AFWall+ (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 → добавьте:

# Защита 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 приложения:

# Через 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 принадлежит владельцу подписки, и вы его не контролируете. Локальный SOCKS5 inbound на localhost:10808 находится на вашем устройстве: именно там вы меняете настройку auth: password. Сервер (владелец подписки) 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 — «How to use custom config feature?»), краши при кастомных DNS-конфигурациях (#1911 — «V2ray Crash When using custom config»), игнорирование кастомных DNS при включённом local DNS (#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)».

Порты 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: Настройки → Региональные пресеты → Россия. Скачивает правила из:

Правила: 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.

CVSS9.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

Техническая суть

В функции 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)

Источники

Документация протоколов

Уязвимости и исследования

Клиенты

GeoIP/GeoSite правила

Серверные панели