Как устроен и как работает VPN‑сервис Happ?

Пытаюсь понять, как xray обеспечивает проксирование всего трафика через tun‑интерфейс (вместо физического). Известно, что запускается локальный прокси, но неясно, какими механизмами xray достигает того, чтобы весь трафик шёл через tun — через изменение дефолтного шлюза, через правила маршрутизации, через iptables/нет? Ниже приведены мои наблюдения:
  • 30 марта 2026 г. 10:02
Ответы на вопрос 2
Коротко — “всё” проксируется не магией xray на уровне физического интерфейса, а одним из двух основных подходов:

1) перехват IP‑пакетов через TUN (VpnService на Android или tun интерфейс в Linux) — трафик целиком приходит в пользоват. процесс, там пакеты разбираются и переводятся в сокеты/запросы к локальному прокси (tun2socks / встроенная обработка TUN) — далее xray шлёт эти соединения на удалённый сервер; или  
2) прозрачное проксирование на уровне сокетов с перенаправлением трафика через iptables/TPROXY/REDIRECT (требует root на Android/Linux) — пакеты/потоки остаются в ядре, но пересылаются на локальный прокси‑порт (dokodemo‑door / локальный socks/http), который потом уже делает outbound через xray.

Детальнее по механизмам и по тому, как это выглядит в Happ / xray‑окружении.

Как TUN‑подход работает (чаще всего на Android без рута)
- Android‑приложение создаёт виртуальный интерфейс через VpnService (tun). Операционная система направляет туда весь (или выбранный) IP‑трафик — т.е. пользовательские приложения «видят» TUN как свой маршрут по умолчанию. Приложение получает дескриптор TUN и может читать/писать сырые IP‑пакеты. Нигде в этом случае система не меняет физический default gateway вручную — ядро просто маршрутизирует пакеты в созданный TUN.
- В userspace запускается компонент, который читает эти IP‑пакеты и «перенаправляет» их в прокси‑потоки:
  - классический вариант — tun2socks (реализует упрощённую TCP/UDP‑стек работая поверх TUN и пересылает соединения в локальный SOCKS5/UDP‑associate), либо аналогичные реализации (tun2http, tun2socks на go/c).
  - альтернативный (новее) вариант — клиент/модуль, у которого есть собственная реализация работы с TUN и он «интегрирован» с xray: он видит IP‑пакеты и создаёт соответствующие outbound соединения через встроенный xray‑модуль.
- Локальный прокси (socks/http/dokodemo) или сам xray принимает эти «сокетоподобные» запросы и отправляет их по выбранному маршруту (внешний сервер), затем возвращает ответы обратно в TUN, приложение их получает как обычные IP‑пакеты.

Преимущества TUN‑подхода: не нужен root; можно перехватить весь трафик (включая приложения, которые не поддерживают прокси); DNS можно перехватывать и обрабатывать отдельно.

Как transparent/iptables‑подход работает (обычно на Linux или на рутованных девайсах)
- На уровне ядра с помощью iptables/nftables + TPROXY/REDIRECT перенаправляют исходящие соединения (обычно TCP/UDP на определённые порты/диапазоны) на локальный порт, где слушает xray (dokodemo‑door или inbound тип, который принимает произвольные соединения).
- dokodemo‑door — специальный inbound в xray/v2ray, который принимает входящие соединения с произвольным адресом назначения и просто проксирует их наружу — этим удобно организовать «прозрачный прокси» вместе с iptables REDIRECT или TPROXY.
- Для UDP нужен TPROXY/сопровождение, либо дополнительные промежуточные решения (redsocks2, udp2raw, или tun2socks для UDP через SOCKS5 UDP ASSOCIATE).

Что именно использует Happ (наpraktical)
- На Android без рута Happ скорее всего использует VpnService + встроенный/внешний tun2socks (или xray с TUN‑поддержкой), то есть всё идёт через TUN. В этом случае приложение не правит iptables и не меняет системный default gateway — ОС сама направляет пакеты в TUN, который приложение объявляет как маршрут для 0.0.0.0/0.
- На устройствах с root (или на десктопе) Happ/инсталляция может использовать iptables/nft + dokodemo‑door/TPROXY, чтобы не заниматься разбором IP‑пакетов в userspace.

Как это можно проверить самому
- На Android (ADB):
  - adb shell dumpsys vpn — покажет активный VPN (VpnService) и связанные PID/UID.
  - adb shell ip addr / ip route — увидите tun-интерфейс (tun0 или подобное) и что маршруты ведут через него.
  - ps | grep tun2socks или ps | grep xray — ищите запущенные бинарники tun2socks / xray.
  - Посмотрите конфигурацию Happ (внутри apk или файлах app data) — есть ли вызовы tun2socks или ключи “tun” / “vpn” / “dns”.
- На Linux/десктопе:
  - ip addr show, ip route show — есть ли tun/wg/tap интерфейс, изменён default route.
  - sudo iptables -t nat -L -n / iptables -t mangle -L -n / ss -ltnp — ищите правила REDIRECT/TPROXY или процессы, слушающие локальные порты.
  - Посмотрите конфиг xray — есть ли dokodemo‑door inbound, есть ли “transparent” опции или routings.

Ключевые термины, на которые стоит смотреть в конфиге/логе
- TUN / VpnService / tun2socks
- dokodemo‑door (transparent inbound)
- socks/http inbound на 127.0.0.1
- iptables REDIRECT / TPROXY / nftables
- default route через tun0 (0.0.0.0/0 → dev tun0)
- “UDP associate” / “udp relay” — как обрабатываются UDP‑запросы/DNS

Итог
- Если Devaices не рутованы, почти наверняка используется TUN (VpnService) + userspace компонент (tun2socks или встроенная обработка), который превращает IP‑пакеты в локальные прокси‑соединения, а не изменение системного default gateway в явном виде и не iptables.  
- Если устройство рутовано или это десктоп, возможен вариант с iptables/TPROXY + dokodemo‑door, когда проксирование делается через перенаправление сокетов в локальный прокси.

Если хотите, могу помочь более конкретно:
- подскажите платформу (Android без рута / с рутом / Linux / macOS), и пришлите выводы команд: ip addr, ip route, ps | grep xray, iptables -t nat -L -n и/или конфигурационный файл xray — и я объясню, какой конкретно метод использует Happ в вашем случае.
<code>ip rule show</code> не показывает все селекторы. <code>not from all</code> скрывает uidrange или fwmark — то правило 9003 на деле что-то вроде <code>not uidrange 1000-1000 iif lo lookup 2022</code> , то есть весь локальный трафик кроме процесса xray уходит в 2022 → tun0. Сам xray свой трафик выводит через физический интерфейс напрямую (sockopt.interface в конфиге), поэтому loop не случается. <code>ip -j rule show | python3 -m json.tool</code> покажет все поля включая скрытые.
Похожие вопросы