todo/Localhost-tracking-Meta-Yandex-SOCKS5.md
loop-uh 737f065567 Вики переехала на wiki2.zapret.moe: домен заменён во всём хранилище
wiki.zapret.moe заблокирован в России, читатели до редиректа не доходят. Во всех заметках, плашках [!mirror], ссылках и скриптах домен заменён на wiki2.zapret.moe; в AGENTS.md записано правило — ссылаться только на wiki2. Скрипт статистики считает своими заходы с обоих доменов. Чужие незакоммиченные правки в nuc/ в коммит не попали — только замена домена.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 15:15:27 -04:00

699 lines
40 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

---
description: "Как Meta и Яндекс следят через localhost и почему SOCKS5 без пароля в VLESS-клиентах выдаёт VPN: разбор атак и защита в xray и sing-box."
---
> [!mirror] Резервное зеркало
> Актуальная версия этой страницы — на основной вики: [wiki2.zapret.moe/Localhost-tracking-Meta-Yandex-SOCKS5](https://wiki2.zapret.moe/Localhost-tracking-Meta-Yandex-SOCKS5)
# Localhost-атака: как Meta, Яндекс и шпионское ПО эксплуатируют loopback-интерфейс
**Дата:** 7 апреля 2026
**Статус:** Верифицировано — исследование USENIX Security 26, POC опубликован
**Оригинал исследования:** [localmess.github.io](https://localmess.github.io/)
**Научная статья:** [Bridges to Self: Silent Web-to-App Tracking on Mobile via Localhost](https://localmess.github.io/assets/bridges-to-self-localmess-usenix-security-26.pdf) (USENIX Security 26)
**POC (Meta/Яндекс):** [github.com/localmess/localhost-abuse](https://github.com/localmess/localhost-abuse)
**POC (VLESS обход split tunneling):** [github.com/runetfreedom/per-app-split-bypass-poc](https://github.com/runetfreedom/per-app-split-bypass-poc)
**Связанная заметка:** [[cloudflare-quick-tunnel|Quick Tunnel от Cloudflare]] — обратный случай: локальный порт выставляют в интернет намеренно, одной командой и без аутентификации
---
## Оглавление
1. [Корневая проблема: архитектура loopback в ОС](#1-корневая-проблема-архитектура-loopback-в-ос)
2. [Яндекс: localhost-трекинг с 2017 года](#2-яндекс-localhost-трекинг-с-2017-года)
3. [Meta (Facebook): WebRTC STUN SDP Munging](#3-meta-facebook-webrtc-stun-sdp-munging)
4. [Побочный эффект: утечка истории браузера](#4-побочный-эффект-утечка-истории-браузера)
5. [VLESS/xray/sing-box: та же дыра, другой вектор](#5-vlessxraysing-box-та-же-дыра-другой-вектор)
6. [Happ: бэкдор через xray API HandlerService](#6-happ-бэкдор-через-xray-api-handlerservice)
7. [Протокол SOCKS5: как работает аутентификация (RFC 1928/1929)](#7-протокол-socks5-как-работает-аутентификация-rfc-19281929)
8. [xray-core: настройка аутентификации SOCKS5 inbound](#8-xray-core-настройка-аутентификации-socks5-inbound)
9. [sing-box: настройка аутентификации SOCKS/mixed inbound](#9-sing-box-настройка-аутентификации-socksmixed-inbound)
10. [Сводная таблица атак и защит](#10-сводная-таблица-атак-и-защит)
11. [Как защитить VPN-клиенты](#11-как-защитить-vpn-клиенты)
12. [Статус браузеров и патчей](#12-статус-браузеров-и-патчей)
13. [Хронология событий](#13-хронология-событий)
14. [Источники](#14-источники)
---
## 1. Корневая проблема: архитектура loopback в ОС
Все описанные атаки — трекинг Meta, трекинг Яндекса, и уязвимость VLESS-клиентов — эксплуатируют **одну и ту же фундаментальную архитектурную слабость**: неконтролируемый доступ к loopback-интерфейсу (`127.0.0.1`).
### Как устроен loopback
![[wiki-anim-loopback.svg|Схема: 127.0.0.1 общий для всех процессов устройства]]
### Что ОС разрешает на loopback
| Действие | Android | Windows | iOS |
|----------|---------|---------|-----|
| Слушать порт на localhost | ✅ Любое приложение с `INTERNET` | ✅ Любой процесс | ✅ Ограничено фоновым режимом |
| Подключиться к чужому порту на localhost | ✅ Без ограничений | ✅ Без ограничений | ✅ Технически возможно |
| Сканировать все порты localhost | ✅ За секунды | ✅ За секунды | ⚠️ Ограничено фоном |
| Изоляция между профилями (Knox/Shelter) | ❌ Loopback общий | N/A | N/A |
| Изоляция VPN/TUN от loopback | ❌ Loopback вне VPN | ❌ Loopback вне TUN | ❌ |
| JavaScript из браузера → localhost | ✅ Без согласия | ✅ Без согласия | ✅ |
### Почему loopback не изолирован
Это **by design**, а не баг ОС. Приложениям легитимно нужен localhost для:
- Межпроцессного взаимодействия (IPC)
- Локальных серверов разработки
- Коммуникации между компонентами одного приложения
Проблема в том, что **никто не предусмотрел**, что это станет вектором атаки для трекинга и обнаружения VPN.
---
## 2. Яндекс: localhost-трекинг с 2017 года
### Архитектура атаки
![[wiki-anim-yandex-metrica.svg|Анимация: Яндекс.Метрика в браузере получает идентификаторы у приложения по localhost]]
### Пошаговый процесс
**Шаг 1.** Пользователь открывает приложение Яндекса (Карты, Навигатор, Браузер, Поиск, Go). Приложение уходит в фон и запускает фоновый сервис, слушающий порты.
**Шаг 2.** Приложение обращается к `startup.mobile.yandex.net` для получения конфигурации:
```json
{
"ports": [30102, 29009],
"first_delay_seconds": 259200
}
```
Параметр `first_delay_seconds` задаёт задержку перед началом прослушивания (~3 дня после установки). Вероятно, для маскировки — не начинать слушать сразу после установки.
**Шаг 3.** Пользователь открывает браузер, заходит на сайт с Яндекс.Метрикой (~3 млн сайтов по BuiltWith, ~575K по HTTP Archive).
**Шаг 4.** JavaScript Яндекс.Метрики запрашивает зашифрованные параметры с серверов Яндекса.
**Шаг 5.** Скрипт отправляет HTTP/HTTPS-запросы на localhost:
- `http://127.0.0.1:29009/...`
- `https://yandexmetrica.com:30103/...` ← домен резолвится в `127.0.0.1`
> **Ключевой трюк:** домен `yandexmetrica.com` сконфигурирован резолвиться в `127.0.0.1`. Это позволяет использовать HTTPS (порты 29010, 30103) — запросы выглядят как обычные HTTPS к «настоящему» домену, но идут на localhost. Обнаружить это стандартными средствами **практически невозможно**.
**Шаг 6.** SDK Яндекс.Метрики в нативном приложении получает запрос и отвечает HTTP 200 OK с телом, содержащим Base64-закодированные бинарные данные:
- Android Advertising ID (AAID)
- Google Advertising ID
- UUID, специфичные для Яндекса
**Шаг 7.** JavaScript получает эти идентификаторы и отправляет их на `mc.yango.com` вместе с зашифрованными параметрами и информацией о посещённой странице.
**Результат:** Яндекс связывает **эфемерную веб-сессию** (кука, IP, User-Agent) с **постоянным идентификатором устройства** (AAID). Пользователь деанонимизирован на всех сайтах с Яндекс.Метрикой.
### Проверенные приложения Яндекса
| Приложение | Package name | Тестовая версия | Порты |
|------------|-------------|-----------------|-------|
| Яндекс.Карты | `ru.yandex.yandexmaps` | 23.5.0 | 29009, 30102 |
| Яндекс.Навигатор | `ru.yandex.yandexnavi` | 23.5.0 | 29009, 30102 |
| Яндекс.Браузер | `com.yandex.browser` | 25.4.1.100 | 29009, 30102 |
| Яндекс.Поиск | `com.yandex.searchapp` | 25.41 | 29009, 30102 |
| Метро в Европе | `ru.yandex.metro` | 3.7.3 | 29009, 30102 |
| Яндекс Go: Такси | `ru.yandex.taxi` | 5.24.1 | 29009, 30102 |
### Что обходит этот метод
Метод работает **даже если пользователь:**
- ❌ Не залогинен в Яндексе в браузере
- ❌ Использует режим инкогнито
- ❌ Очистил куки и данные браузера
- ❌ Сбросил рекламный идентификатор Android
---
## 3. Meta (Facebook): WebRTC STUN SDP Munging
### Архитектура атаки
![[wiki-anim-meta-pixel.svg|Анимация: Meta Pixel связывает веб-сессию с устройством и аккаунтом через localhost]]
### Техника SDP Munging
**SDP Munging** — это манипуляция полями SDP (Session Description Protocol) в WebRTC-соединении для передачи произвольных данных.
Meta Pixel вставляет значение куки `_fbp` в поле `ice-ufrag` SDP-предложения. При WebRTC handshake генерируется STUN Binding Request, который отправляется на localhost UDP-порты 12580-12585. Нативное приложение Facebook/Instagram слушает эти порты и извлекает `_fbp` из STUN-пакета.
**Почему это невидимо:**
- WebRTC STUN-трафик **не отображается** в Chrome DevTools
- Нет HTTP-запросов, которые можно было бы перехватить в инспекторе
- Сетевая активность происходит на уровне UDP, ниже HTTP-слоя
### Эволюция техник Meta
| Метод | Начало | Конец | Порты | Обнаружимость |
|-------|--------|-------|-------|---------------|
| HTTP | Сентябрь 2024 | Октябрь 2024 | TCP 12387 | Средняя (видно в DevTools) |
| WebSocket | Ноябрь 2024 | Январь 2025 | TCP 12387 | Средняя |
| WebRTC STUN + SDP Munging | Ноябрь 2024 | Июнь 2025 | UDP 12580-12585 | **Очень низкая** |
| WebRTC TURN (без SDP Munging) | Май 2025 | Июнь 2025 | UDP 12586-12591 | Низкая |
> Meta 4 раза сменила технику за 9 месяцев, каждый раз усложняя обнаружение.
### О куке `_fbp`
- Third most popular first-party cookie в интернете (Web Almanac 2024)
- Присутствует на **~25% из топ-1М сайтов**
- Срок жизни: 90 дней
- First-party cookie = разная на каждом сайте → **нельзя** использовать для кросс-сайтового трекинга
- **НО:** через localhost-атаку Meta связывает разные `_fbp` с одним устройством → кросс-сайтовый трекинг становится возможен
### Масштаб
| Регион | Сайтов с Meta Pixel (из 100K) | Без согласия пользователя |
|--------|-------------------------------|---------------------------|
| США | 17,223 | 13,468 (78.2%) |
| Европа | 15,677 | 11,890 (75.8%) |
| Регион | Сайтов с Яндекс.Метрикой (из 100K) | Без согласия пользователя |
|--------|-------------------------------------|---------------------------|
| США | 1,312 | 1,095 (83.5%) |
| Европа | 1,260 | 1,064 (84.4%) |
### Пошаговый процесс Meta
1. Пользователь открывает Facebook/Instagram → приложение уходит в фон → слушает TCP 12387/12388 и UDP 12580-12585
2. Пользователь открывает браузер → заходит на сайт с Meta Pixel (~5.8 млн сайтов)
3. Meta Pixel JS читает куку `_fbp`
4. JS создаёт WebRTC peer connection с SDP Munging: `ice-ufrag = <_fbp value>`
5. STUN Binding Request с `_fbp` в поле ice-ufrag летит на `127.0.0.1:12580-12585`
6. Facebook/Instagram получают `_fbp`
7. Приложение отправляет GraphQL на `graph.facebook.com/graphql`: `_fbp` + Device ID + Facebook Account ID
8. Meta связывает: веб-сессия ↔ устройство ↔ аккаунт Facebook
---
## 4. Побочный эффект: утечка истории браузера
Поскольку Яндекс использует **обычные HTTP-запросы** (не WebRTC), любое стороннее приложение, слушающее те же порты, может перехватить эти запросы и прочитать заголовок `Origin`, который содержит **URL посещённого сайта**.
### Кто уязвим
| Браузер | Яндекс (утечка истории) | Meta (утечка истории) | Защита |
|---------|------------------------|----------------------|--------|
| Chrome | ✅ Уязвим | ✅ Уязвим | Chrome 137+ — блокировка портов и SDP Munging |
| Firefox | ✅ Уязвим | ❌ Не затронут | В разработке |
| Edge | ✅ Уязвим | ✅ Уязвим | Неизвестно |
| Brave | ❌ Защищён | ❌ Защищён | С 2022: blocklist + запрос согласия на localhost |
| DuckDuckGo | ⚠️ Минимально | ❌ Защищён | Blocklist (3 домена Яндекса отсутствовали — исправлено) |
**Работает в режиме инкогнито: ДА.** Инкогнито не влияет на доступ к localhost.
### POC-демонстрация
Исследователи создали POC-приложение ([github.com/localmess/localhost-abuse](https://github.com/localmess/localhost-abuse)), которое:
1. Слушает порты 29009, 30102 (как приложения Яндекса)
2. Перехватывает HTTP-запросы от Яндекс.Метрики
3. Извлекает `Origin` заголовок
4. Отображает список посещённых сайтов в реальном времени
---
## 5. VLESS/xray/sing-box: та же дыра, другой вектор
### Связь с Meta/Яндекс
Meta и Яндекс доказали: **localhost на Android не изолирован, и это можно массово эксплуатировать.** [[VLESS-SOCKS5-vulnerability|Уязвимость VLESS-клиентов]] — **тот же фундаментальный баг**, но другой вектор атаки.
| Аспект | Meta/Яндекс | VLESS-клиенты |
|--------|------------|---------------|
| **Что на localhost** | Трекинг-сервис приложения | SOCKS5-прокси без аутентификации |
| **Кто атакует** | JavaScript с веб-страницы | Шпионский модуль в приложении |
| **Что получает атакующий** | Device ID (AAID) + связь с аккаунтом | Выходной IP VPN-сервера |
| **Цель** | Деанонимизация + таргетированная реклама | Блокировка VPN-серверов |
| **Фундаментальная проблема** | Loopback не изолирован | Loopback не изолирован |
| **Knox/Shelter помогает?** | Нет | Нет |
| **Инкогнито помогает?** | Нет | N/A |
### Как эксплуатируется VLESS
![[wiki-anim-socks5-spy.svg|Анимация: как шпионский модуль получает выходной IP через открытый SOCKS5]]
### Почему per-app split tunneling не помогает
![[wiki-anim-socks5-bypass.svg|Анимация: шпион обращается на localhost:10808 мимо VpnService]]
VpnService перехватывает трафик через TUN-интерфейс. Но подключение к `127.0.0.1` **не проходит через TUN** — это внутренний loopback. Split tunneling бессилен.
### Почему Knox/Shelter/Island не помогают
Android Private Spaces изолируют файловую систему и VpnService, но **loopback-интерфейс общий** для всех профилей. Процесс из Knox видит `127.0.0.1:10808` основного профиля.
### Контекст: методичка Минцифры РФ
Минцифры разослало аккредитованным IT-компаниям методичку по обнаружению VPN. Характерные порты из методички:
| Тип | Порты |
|-----|-------|
| SOCKS | 1080, 9000, 5555, 16000-16100 |
| HTTP | 80, 443, 3128, 3127, 8000, 8080, 8081, 8888 |
| Прозрачные Proxy | 80, 443, 4080, 7000/7044, 8082, 12345 |
| Tor | 9050, 9051, 9150 |
Стандартные порты xray (10808) и nekobox (2080) **пока не указаны**, но полный скан 65535 портов на localhost — секунды.
### Список уязвимых VLESS-клиентов
| Клиент | Платформа | Ядро | SOCKS5 auth | Статус |
|--------|-----------|------|-------------|--------|
| **Happ** | iOS | xray | ❌ | 🔴 Особо опасен (API без auth) |
| v2RayTun | Android | xray | ❌ | 🟡 Обещали исправить |
| V2BOX | iOS/Android | xray | ❌ | 🟡 Уязвим |
| v2rayNG | Android | xray | ❌ | 🟡 Уязвим (порт 10808) |
| Hiddify | Android/iOS | sing-box | ❌ | 🟡 Уязвим |
| Exclave | iOS | xray | ❌ | 🟡 Уязвим |
| Npv Tunnel | Android | xray | ❌ | 🟡 Уязвим |
| Neko Box | Android | sing-box | ❌ | 🟡 Уязвим (порт 2080) |
| Husi | Android | sing-box | ✅ | 🟢 Можно настроить |
| SFA (sing-box) | Android | sing-box | ✅ | 🟢 Ручной JSON |
| saeeddev94/xray | Android | xray | ✅ | 🟢 F-Droid, ручной JSON |
---
## 6. Happ: бэкдор через xray API HandlerService
Клиент Happ — отдельная категория. Помимо уязвимого SOCKS5, он включает **xray gRPC API с HandlerService БЕЗ аутентификации**.
### Сервисы xray API
| Сервис | Назначение | Опасность |
|--------|-----------|-----------|
| **StatsService** | Статистика трафика, онлайн-пользователи | Низкая |
| **LoggerService** | Управление логированием | Низкая |
| **HandlerService** | Добавление/удаление inbound/outbound, дамп конфигов, управление пользователями | 🔴 **Критическая** |
| **RoutingService** | Управление маршрутизацией | Средняя |
| **ReflectionService** | Список доступных API | Средняя |
### gRPC методы HandlerService
| Метод | Что делает |
|-------|-----------|
| `AddInbound` | Добавить новый inbound |
| `RemoveInbound` | Удалить inbound |
| `AlterInbound` | Изменить inbound |
| `AddOutbound` | Добавить outbound |
| `RemoveOutbound` | Удалить outbound |
| `AlterOutbound` | Изменить outbound |
| `GetInboundUsers` | Получить пользователей (включая ключи) |
### Цепочка атаки
![[wiki-anim-grpc-chain.svg|Схема: цепочка атаки через открытый gRPC API прокси-ядра]]
**Позиция Happ:** заявили, что API нужен «для статистики». Это ложь — для статистики достаточно `StatsService`. При смене конфига Happ перезапускает xray целиком, а не использует HandlerService.
**Рекомендация:** немедленно удалить Happ. Заблокировать `Happ/*` по UserAgent на серверах подписок. Один пользователь с Happ компрометирует весь сервер.
> [!warning] Открытый API убрали в день огласки
> По коду приложения ([[xray/happ-problems|подробный разбор]]) `HandlerService` была в Happ для Android 3.16.1 от 1 апреля 2026 года и исчезла в 3.16.2 от 7 апреля — в день публикации разбора на Хабре. Но закрытый код, собственные домены телеметрии и SOCKS5 без пароля по умолчанию у Happ остаются актуальными на 18 октября 2026 года.
---
## 7. Протокол SOCKS5: как работает аутентификация (RFC 1928/1929)
### Зачем нужна аутентификация SOCKS5
Без аутентификации SOCKS5-прокси — это **открытая дверь**: кто угодно может подключиться и маршрутизировать через него трафик. В контексте VPN это означает, что шпионский модуль может:
- Обнаружить прокси сканированием портов
- Подключиться без учётных данных
- Узнать выходной IP VPN-сервера
- Гонять через прокси произвольный трафик
Аутентификация добавляет **барьер**: без знания логина/пароля подключение отклоняется.
### Фаза 1: Согласование метода (RFC 1928)
**Клиент → сервер**
| VER | NMETHODS | METHODS |
|:--|:--|:--|
| `0x05` | `0x01` | `0x02` |
«Я хочу SOCKS5, предлагаю метод `0x02` (пароль)».
**Сервер → клиент**
| VER | METHOD |
|:--|:--|
| `0x05` | `0x02` |
«Принято, используем метод `0x02`».
**Методы аутентификации:**
- `0x00` — **NO AUTHENTICATION REQUIRED** ← уязвимый вариант
- `0x01` — GSSAPI
- `0x02` — **USERNAME/PASSWORD** ← безопасный вариант
- `0xFF` — нет подходящего метода (отказ)
### Фаза 2: Аутентификация по логину/паролю (RFC 1929)
**Клиент → сервер**
| VER | ULEN | UNAME | PLEN | PASSWD |
|:--|:--|:--|:--|:--|
| `0x01` | `0x08` | `"user123"` | `0x0C` | `"pass456abc"` |
**Сервер → клиент**
| VER | STATUS |
|:--|:--|
| `0x01` | `0x00` |
`0x00` — успех, любое другое значение — отказ.
**Поля:**
- `VER` = `0x01` (версия подпротокола аутентификации)
- `ULEN` = длина логина (1-255 байт)
- `UNAME` = логин
- `PLEN` = длина пароля (1-255 байт)
- `PASSWD` = пароль
> ⚠️ **Важно:** логин и пароль передаются **открытым текстом**. RFC 1929: *«Since the request carries the password in cleartext, this subnegotiation is not recommended for environments where 'sniffing' is possible and practical.»* Но для localhost это не проблема — трафик не выходит за пределы устройства.
### Фаза 3: Запрос (после успешной аутентификации)
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|:--|:--|:--|:--|:--|:--|
| `0x05` | `0x01` | `0x00` | `0x01` | IP-адрес | порт |
**CMD:**
- `0x01` — CONNECT (TCP)
- `0x02` — BIND
- `0x03` — UDP ASSOCIATE
### Проблема UDP ASSOCIATE
UDP ASSOCIATE (`CMD = 0x03`) создаёт UDP-ретранслятор. **Но:** после успешной TCP-аутентификации UDP-датаграммы **не проходят повторную аутентификацию**.
UDP-датаграмма (RFC 1928, раздел 7):
| RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA |
|:--|:--|:--|:--|:--|:--|
| 2 байта | 1 | 1 | переменный | 2 | переменный |
В заголовке UDP-датаграммы **нет поля для аутентификации**. RFC 1928 допускает опциональное шифрование/целостность, но большинство реализаций (включая xray и sing-box) **не реализуют** per-packet auth для UDP.
**Вывод:** для полной защиты от localhost-атак **UDP нужно отключать** или блокировать фаерволом.
---
## 8. xray-core: настройка аутентификации SOCKS5 inbound
### Уязвимая конфигурация (как есть сейчас)
```json
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
]
}
```
**Проблемы:**
- `"auth": "noauth"` — любой процесс на устройстве может подключиться
- `"udp": true` — UDP тоже доступен без ограничений
- Порт 10808 — стандартный, легко угадывается
### Безопасная конфигурация
```json
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "password",
"accounts": [
{
"user": "xf_a8b3c2d1",
"pass": "7e4f91d0c3b8a2e5"
}
],
"udp": false
}
}
]
}
```
**Что изменилось:**
- `"auth": "password"` — требуется аутентификация
- `"accounts"` — массив учётных записей `{user, pass}`
- `"udp": false` — UDP отключён (убирает вектор атаки через UDP ASSOCIATE)
### Поля конфигурации xray SOCKS inbound
| Поле | Тип | По умолчанию | Описание |
|------|-----|-------------|----------|
| `auth` | `"noauth"` / `"password"` | `"noauth"` | Режим аутентификации |
| `accounts` | `[{user, pass}]` | — | Учётные записи (только при `auth: "password"`) |
| `udp` | `boolean` | `false` | Включение UDP ASSOCIATE |
| `ip` | `string` | auto | IP для UDP-ответов |
| `userLevel` | `number` | `0` | Уровень политик |
### Рекомендации для xray-клиентов
1. **Генерировать credentials при каждом запуске** — рандомные user/pass, не хардкодить
2. **Отключить UDP** (`"udp": false`) — UDP не аутентифицируется per-packet
3. **Слушать только на 127.0.0.1** — никогда на `0.0.0.0`
4. **Рандомизировать порт** — не использовать стандартный 10808
5. **Не включать HandlerService** в API — достаточно StatsService/LogService
---
## 9. sing-box: настройка аутентификации SOCKS/mixed inbound
### Уязвимая конфигурация
```json
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "0.0.0.0",
"listen_port": 2080
}
]
}
```
**Проблемы:**
- Нет массива `users` — аутентификации нет
- `"listen": "0.0.0.0"` — доступен из сети (ещё хуже чем localhost)
- Порт 2080 — стандартный для nekobox
### Безопасная конфигурация
```json
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 2080,
"users": [
{
"username": "sb_d4c1a7f2",
"password": "9e2f5b83a1c7d0e4"
}
]
}
]
}
```
### Поля конфигурации sing-box SOCKS/mixed inbound
| Поле | Тип | Описание |
|------|-----|----------|
| `type` | `"socks"` / `"mixed"` | `mixed` поддерживает SOCKS4/4a/5 + HTTP |
| `listen` | `string` | Адрес прослушивания |
| `listen_port` | `number` | Порт |
| `users` | `[{username, password}]` | Учётные записи (без этого поля — без auth) |
| `set_system_proxy` | `boolean` | Автоматическая системная прокси-настройка |
### Разница SOCKS vs Mixed
| Возможность | `type: "socks"` | `type: "mixed"` |
|-------------|-----------------|-----------------|
| SOCKS4/4a | ✅ | ✅ |
| SOCKS5 | ✅ | ✅ |
| HTTP-прокси | ❌ | ✅ |
| `users` (аутентификация) | ✅ | ✅ (для SOCKS и HTTP) |
| `set_system_proxy` | ❌ | ✅ |
### Позиция разработчика sing-box
Разработчик sing-box считает эту проблему **«skill issue»** клиентов: sing-box **не создаёт** mixed inbound автоматически — это делают конкретные клиенты и генераторы конфигов. Если не добавлять mixed inbound в конфиг, прокси не будет.
---
## 10. Сводная таблица атак и защит
| Механизм | Против Meta/Яндекс | Против VLESS-скана | Против Happ API |
|----------|--------------------|--------------------|-----------------|
| SOCKS5 auth (password) | N/A | ✅ Блокирует подключение | N/A |
| Отключение UDP | N/A | ✅ Убирает вектор | N/A |
| Рандомный порт | N/A | ⚠️ Замедляет, не блокирует | N/A |
| iptables/root | ✅ Можно заблокировать | ✅ Можно заблокировать | ✅ |
| Knox/Shelter/Island | ❌ Не помогает | ❌ Не помогает | ❌ |
| Режим инкогнито | ❌ Не помогает | N/A | N/A |
| Очистка куки | ❌ Не помогает | N/A | N/A |
| Brave Browser | ✅ Blocklist + consent | N/A | N/A |
| Chrome 137+ | ✅ Блокировка портов | N/A | N/A |
| Отключение HandlerService | N/A | N/A | ✅ Убирает API |
| Блокировка Happ по UserAgent | N/A | N/A | ✅ На сервере |
| Отдельное устройство | ✅ Физическая изоляция | ✅ | ✅ |
| Windows Firewall (process) | ✅ | ✅ | ✅ |
---
## 11. Как защитить VPN-клиенты
### Для разработчиков клиентов
1. **SOCKS5 auth по умолчанию** — генерировать рандомные credentials при каждом запуске, передавать их только доверенным приложениям
2. **Отключить UDP** в SOCKS5 inbound — UDP ASSOCIATE не поддерживает per-packet auth
3. **Рандомизировать порт** — не стандартные 10808/2080/1080
4. **Только 127.0.0.1** — никогда 0.0.0.0
5. **Не включать xray API HandlerService** — для статистики хватит StatsService/LogService
6. **На Android с root:** добавить iptables-правила, ограничивающие доступ к порту по UID процесса
### Для пользователей Android
1. Использовать клиенты с SOCKS5 auth: **Husi**, **SFA**, **saeeddev94/xray**
2. **Удалить Happ** немедленно
3. Держать российское ПО на **отдельном устройстве**
4. Не полагаться на Knox/Shelter — loopback не изолирован
5. С root: `iptables -I OUTPUT -p tcp -d 127.0.0.1 --dport 10808 -j DROP` для всех кроме VPN-клиента
### Для пользователей Windows
1. Windows Firewall: правила на блокировку доступа к портам 10808/10809 для всех процессов кроме xray.exe и доверенных
2. В xray routing: `process name` для разрешённых приложений
3. Рандомный порт вместо стандартного 10808
### Для администраторов серверов
1. **Раздельные входной/выходной IP** — утечка выходного не компрометирует входной
2. **CloudFlare WARP на выходе** — маскировка выходного IP
3. **geoip:ru → block на сервере** — шпион не сможет связать трафик
4. **Блокировка Happ** по UserAgent `Happ/*`
### Маршрутизация
**На клиенте:**
| Правило | Действие |
|:--|:--|
| `geoip:ru` | direct: российские IP напрямую |
| `geoip:private` | direct: локальные сети |
| остальное | proxy: через VPN |
**На сервере:**
| Правило | Действие |
|:--|:--|
| `geoip:ru` | block: запретить выход на РФ |
| остальное | freedom: разрешить |
---
## 12. Статус браузеров и патчей
### Meta Pixel
| Дата | Событие |
|------|---------|
| Сентябрь 2024 | Начало HTTP-коммуникации с localhost |
| Ноябрь 2024 | Переход на WebSocket, затем WebRTC STUN |
| Май 2025 | Добавлен WebRTC TURN (обход блокировки SDP Munging) |
| 26 мая 2025 | Chrome 137 — блокировка SDP Munging и абьюзимых портов |
| **3 июня 2025** | **Meta полностью прекратила localhost-трекинг, код удалён** |
### Яндекс.Метрика
| Дата | Событие |
|------|---------|
| Февраль 2017 | Начало HTTP-коммуникации с localhost |
| Май 2018 | Добавлен HTTPS (порты 29010, 30103) |
| Июнь 2025 | Яндекс сообщил о прекращении использования и удалении функции |
### Браузеры
| Браузер | Статус | Детали |
|---------|--------|--------|
| Chrome 137+ | ✅ Исправлено | Блокировка портов + SDP Munging |
| Brave 1.54+ | ✅ Защищён с 2022 | Blocklist + localhost consent |
| DuckDuckGo | ✅ Исправлено | Обновлён blocklist |
| Firefox 139 | 🟡 В разработке | Патч в процессе |
| Edge | ❌ Неизвестно | Chromium-based, должен следовать за Chrome |
### VLESS-клиенты
На **7 апреля 2026** ни один массовый VLESS-клиент не добавил SOCKS5 аутентификацию, несмотря на уведомление 10 марта 2026.
---
## 13. Хронология событий
| Дата | Событие |
|------|---------|
| Февраль 2017 | Яндекс начинает localhost-трекинг через HTTP |
| Май 2018 | Яндекс добавляет HTTPS-канал (yandexmetrica.com → 127.0.0.1) |
| 2022 | Brave добавляет защиту localhost (consent + blocklist) |
| Сентябрь 2024 | Meta начинает localhost-трекинг через HTTP |
| Ноябрь 2024 | Meta переходит на WebRTC STUN SDP Munging |
| 10 марта 2026 | runetfreedom уведомляет разработчиков VLESS-клиентов об уязвимости SOCKS5 |
| Апрель 2026 | Минцифры рассылает методичку по обнаружению VPN |
| 7 апреля 2026 | Публикация уязвимости VLESS-клиентов, ни один клиент не исправлен |
| 26 мая 2025 | Chrome 137 блокирует SDP Munging и абьюзимые порты |
| 3 июня 2025 | Meta полностью удаляет код localhost-трекинга |
| Июнь 2025 | Публикация исследования USENIX Security 26 (localmess.github.io) |
---
## 14. Источники
### Исследование Meta/Яндекс (LocalMess)
- [localmess.github.io — оригинал](https://localmess.github.io/)
- [Bridges to Self — PDF статья USENIX Security 26](https://localmess.github.io/assets/bridges-to-self-localmess-usenix-security-26.pdf)
- [POC: localhost-abuse](https://github.com/localmess/localhost-abuse)
- [The Register: Meta halts localhost tracking](https://www.theregister.com/2025/06/03/meta_pauses_android_tracking_tech/)
- [AdGuard: Meta and Yandex abuse localhost](https://adguard.com/en/blog/meta-yandex-abuse-localhost-to-track-users.html)
- [Android Police: researchers catch Meta](https://www.androidpolice.com/meta-yandex-apps-de-anonymize-localhost-tracking/)
- [Habr: перевод статьи](https://habr.com/ru/articles/920714/)
### Уязвимость VLESS
- [ntc.party: оригинальная публикация runetfreedom](https://ntc.party/)
- [Habr: Критическая уязвимость VLESS клиентов](https://habr.com/ru/articles/1020080/)
- [POC: per-app-split-bypass](https://github.com/runetfreedom/per-app-split-bypass-poc)
- [XTLS BBS: Malicious Activity of Closed-Source Xray Clients](https://github.com/XTLS/BBS/issues/8)
### Документация протоколов
- [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 API](https://xtls.github.io/en/config/api.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/)
### Защита браузеров
- [Brave: localhost permission](https://brave.com/privacy-updates/27-localhost-permission/)
- [Chrome 137 release](https://chromereleases.googleblog.com/2025/05/)
- [Meduza: методичка Минцифры](https://meduza.io/news/2026/04/06/mintsifry-razoslalo-rossiyskim-kompaniyam-metodichku-po-poisku-vpn-na-ustroystvah-polzovateley)