Фикс обнаружения и блокировки туннелей | sing-box маршрутизация

Тоже начали всё чаще и чаще душить соединения к self-hosted VPS, а потом и вовсе заблокировали доступ к входному IP? Ещё нет? Перестрахуйтесь заранее!

Контекст

В сети начали подозревать MAX в наличие шпионского модуля.

Что подтвердилось:

Примерно в то же время начали периодически душить соединения, подробнее описал здесь, а потом и вовсе заблокировали входной IP со всех локаций сразу, хотя те самые обрывы чинились банальной сменой внутреннего NAT IP.
РКН действительно продавил закон о получении логов на провайдерах:

Предположение о “Сибирской блокировке” не билось с симптомами, характерностью и последствием.

Причем есть косвенные подтверждения и от остальных пользователей.

И очень похожая на мою ситуация:

Поэтому я абсолютно уверен в том, что шпионы существуют не только в MAX, а на прочих некоторых сервисах. Подробнее даже выложил предположение о потенциальных уязвимостях, которыми они могут воспользоваться.

Спустя какое-то время кто-то выложил новость о том что “минцифры поручило сервисам обнаруживать туннели и отказывать в обслуживании”. Источники не приложу, не знаю уровень их желтизны. Пост и мой ответ к нему загадочно исчез спустя 15 минут после публикации (даже осталась ссылка к нему - https://ntc.party/t/реверс-инжиниринг-модуля-проверки-успешности-блокировок-внутри-мессенджера-max/22584/267) без каких-либо предупреждений. Походу боты РКН спровоцировали блокировку спам-жалобами. Заранее спохватились, видимо)

UPD: Появился новый! https://ntc.party/t/вопросы-по-ограничению-трафика-зарубежных-ресурсов/23526/26

Именно! Потенциально – да, данный пост как раз это и раскрывает.

Проблема (не доказанный факт, но практически подтвержденная гипотеза)

Как выясняется, РКН и подконтрольные им сервисы-шпионы теперь могут в автоматическим режиме заниматься active probing обнаруженных входных IP адресов, особенно если вы сливаете свой домашний IP для однозначной идентификации местоположения ТСПУ, который будет использоваться для корреляционной атаки.

Мы выяснили, что доступ к логам провайдеров они вполне имеют, для однозначной идентификации SRC NAT-IP:

Согласитесь, что мешает им в автоматическом режиме это делать? Мощности? Массово не будут. Будут точечно. Дорогостоящее оборудование на наши же деньги, налогоплательщиков, и поставят.

Фикс | Как вообще избежать этого?

Нет, не запускать “шпионы” в sandbox. Я дал вполне разумное техническое обоснование, почему это не сработает.

Тараканов по одному ловить – плохая идея.

Что не сливать? Кому попало домашний IP – это во-первых. Значит пускаем весь трафик (кроме Bittorrent, это только на ПК!) через VPN (путем создания интерфейса сети И прозрачной маршрутизации через userspace прокси).
Ещё – входной IP сервера – тот что шпионы донесут РКН, для его блокировки.

Как скрыть?

Уже предложили лечение:

“split tunneling” на уровне приложений я крайне не рекомендую, не столько потому, что это закрывает все уязвимости, сколько вы заставляете конечные клиенты-устройства быть умными. Как говорится, когда-нибудь да ошибетесь, да и архитектура неправильная.

“Чекеры IP” или всё что связано с MAX забанить – тоже не получится. Всех тараканов не уничтожишь, IP утечь может сотней разных способов (и пролезть в правила маршрутизации).

Нет, ну вы можете конечно изолировать не только исполняемый код, а ещё и интерфейс сети. Готовы реализовать такой же уровень изолированности, как в QubesOS, на смартфонах? Вот вот, поэтому не стоит и думать в эту сторону, это заведомо проигрышная борьба.

Схема

Минимальная схема, которая закроет банальную уязвимость - обнаружение входного IP, это поменять входной IP (принимать трафик только с него), оставив по дефолту выходным IP тем уже был.

Во-первых у своего хостера купите второй белый IPv4. Где-нибудь в панели управления VPS во вкладке “Сеть” или типа того.

У вас в ip a должны быть все нужные IP адреса. Оба входной/выходной, и IPv6 выходной, если есть. Но выходной IPv6 не обязателен, его WARP предоставляет, например для доступа к данному форуму. Если в ip a после покупки отсутствует новый IPv4, настройте чтобы был, смотря какая у Вас ОС.

Например в Arch Linux

Файл: /etc/systemd/network/20-eth0.network

[Match]
Name=eth0

[Network]
# IPv4
Address=Y.Y.Y.Y/24
Address=X.X.X.X/24
Gateway=Y.Y.Y.1

# IPv6
Address=YYYY:YYYY:Y:Y::YYYY/64
Gateway=YYYY:YYYY:Y:Y::1

DNS=1.1.1.1
DNS=2606:4700:4700::1111
IPv6AcceptRA=yes

X.X.X.X – входной IP, должен идти ПОСЛЕ выходного Y.Y.Y.Y чтобы выходной был дефолтным!

Перезапустить сервис:

systemctl restart systemd-networkd

Используем sing-box как движок маршрутизации трафика на сервере и клиенте.

/etc/sing-box/config.json – типичное местоположение его файла конфигурации.

Изменяем:
inbounds.inbound.listen

"inbounds": [
  {
    "type": "vless",
    "tag": "reality-in",
    "listen": "X.X.X.X",
...
  }
]

Где вместо “X.X.X.X” - входной IP который нельзя ни в коем случае нигде светить.

То что куда-то светится - outbound.direct.inet4_bind_address

"outbounds": [
  {
    "type": "direct",
    "tag": "direct",
    "inet4_bind_address": "Y.Y.Y.Y"
  },
...
]

Где “Y.Y.Y.Y” - выходной IP сервера.

Если вы не доверяете ещё каким-нибудь outbound апстримам на сервере - прикрепите

"inet4_bind_address": "Y.Y.Y.Y"

Туда тоже. Но всё равно должно идти через дефолтный (выходной), это лишь подстраховка.

Это всё? Минимально - да, но не панацея.

Кстати, я ещё долго после фикса пользовался обычным TCP транспортом без мультиплексирования и всё всё равно было супер, проблемы исчезли.

Расширенная схема

Не менее важным считаю и правильную маршрутизацию. Входной IP вы скрыли, а от корреляционных атак (как я предложил здесь) вас это всё равно не спасёт. Да, тех что автоматизированно программно осуществляют, не вручную, да хоть глубокой ночью (в моем случае так и было, тем более я трафика почти не генерировал никакого).

Хорошо, где брать сервера? Нужен только один. Объясняю:

Конечные устройства могут теми или иными способами осущеставлять те или иные манипуляции с трафиком для самих себя. Но это ужасно, и неправильно. Клиенты должны быть тупыми. А сетевой шлюз (например роутер) – умным, он для этого и создан.

При этом роутер не обязательный, вы тоже не готовы ходить с карманным OpenWRT роутером?

И мне что, на условном iOS как курица в кнопку включение/выключение клевать при этом переключая профили стран?

Нет, в том то и дело, что он, как и прочее конечное устройство на это не рассчитан (и не должен), поэтому предлагаю использовать VPS как свой личный удаленный шлюз – мозги маршрутизации.

Гоните весь трафик через VPN на смартфоне, и на ПК (с исключением для bittorrent, его напрямую в direct). Нет, ничего не будет что у вас 95% трафика идет туда (хотя для внутренних сервисов Apple можно и напрямую, внимание – доверенных сервисов, где вы точно уверены, что шпион этим каналом не воспользуется для обхода правил маршрутизации).

Получается цепочка:
Me → VLESS к серверу.

Ах да, протокол де-факто простой:
VLESS: VLESS-XTLS-uTLS-REALITY-xudp-gRPC.

Обязательно используйте как минимум gRPC для транспорта, он достаточно хорош в мультиплексировании для предотвращения триггера пресловутой “Сибирская блокировка”.

Reality к SNI в подсети хостера.

Дальше что? Весь трафик выходит через наш VPS outbound IPv4. Условный Kinopoisk вы с ним не откроете, противятся IP датацентра (принадлежащий ASN датацентра).

Заворачиваем весь неизвестный трафик в WARP тогда:
Me → VLESS → WARP → Неизвестное

Делается это добавлением интерфейса WireGuard в endpoints

"endpoints": [
  {
    "type": "wireguard",
    "tag": "warp-ep",
    "system": false,
    "name": "wg0",
    "mtu": 1280,
    "address": [
      "X.X.X.X/32",
      "YYYY:YYYY:YYY:YYYY:YYYY:YYYY:YY:YYYY/128"
    ],
    "private_key": "Private key here=",
    "domain_resolver": "google",
    "peers": [
      {
        "address": "engage.cloudflareclient.com",
        "port": 2408,
        "public_key": "Public key here=",
        "allowed_ips": [
          "0.0.0.0/0",
          "::/0"
        ]
      }
    ]
  }
]

Чтобы сгенерировать конфиг (делать из VPS) есть инструкция (Usage) в репозитории клиента WARP.
Не забудьте изменить ключевые поля, которые отличаются.

Но Apple CIDR + Telegram (не geosite) (не geosite) и прочие хорошие доверенные сервисы (на CIDR которых нельзя расположить свои сервера) – известные, их напрямую в DIRECT на самом VPS:
Me → VLESS → Apple CIDR, Telegram CIDR и прочие хорошие, доверенные сервисы.

Но я всякий OpenAI / Habr (некоторые статьи) / TikTok – всё равно не открою! Зря купил рувпс!

Это их проблема, а не ваша. Поднимите демон Tor (для outbound) (обычно они его уважают) или апстрим прокси. Современный Tor сейчас довольно-таки шустрый.
Me → VLESS → Tor или ( ShadowSocks с/без WARP ) → Вредные сервисы (с геоблоком)

А SSH что? Какой-нибудь port-knocking или порт на небеса, или ещё какой-нибудь костыль, например firewall по SRC IP?

Всё очень просто.
Me → VLESS → SSH (к выходному IP) → мой сервер.

Всё, слушаете SSH только на выходном IP, он будет идти через VLESS автоматически (с входного IP, там пинг в той же подсети околонулевой). Также можете через IPv6 подключаться, если есть.

А ляжет туннель, как подключусь к серверу?

Через onion сервис SSH. То есть через Tor напрямую.
Me → bridges over (например, ru email-pgp GitHub Actions bot, или напрямую как-то ещё мосты) → Tor → SSH / SSH-over-onion → мой сервер (чтобы не оставлять single point of failure).

А у меня госуслуги через туннель открываться не будут! Зря весь трафик в туннель идет!

Потому что Google DNS не возвращает “правильные IP”. Для всего ру сегмента сети форсируйте Yandex DNS на самом VPS, и всё равно какой там DNS хотел клиент.
DNS over VLESS: RU → Yandex DoU; Default → Google DoT

Не заморачивайте конечные клиенты DNS правилами.

dns.rules

{
  "rule_set": ["geosite-category-ru"],
  "server": "local"
}

route.rules (чтобы заставить РФ сервисы использовать Yandex DNS)

{
  "rule_set": ["geosite-category-ru"],
  "action": "resolve",
  "server": "local"
}

rule_set, если вдруг нет:

{
  "tag": "geosite-category-ru",
  "type": "remote",
  "format": "binary",
  "url": "https://raw.githubusercontent.com/runetfreedom/russia-v2ray-rules-dat/release/sing-box/rule-set-geosite/geosite-category-ru.srs"
}

Это всё? РФ сервисы покрыты, DNS к ним – правильный. Геоблок сервисы - тоже работают. И всё это - с тупого конечного устройства.

Что требуется от конечного устройства?

Туннелировать весь свой трафик через этот “шлюз”, теперь вы сами себе провайдер и решаете что фильтровать/блокировать, и что куда должно и по каким правилами идти, абсолютно прозрачно.

Итоговая схема:

Спойлер, роскошный максимум

Me → VLESS → WARP → Неизвестное

Me → VLESS → Tor или ( ShadowSocks с/без WARP ) → Вредные сервисы (с геоблоком)

Me → VLESS → Apple CIDR, Telegram CIDR и прочие хорошие, доверенные сервисы.

Me → VLESS → I2P, причём I2P роутер на самом сервере.

Me → VLESS → SSH (к выходному IPv4) / SSH на IPv6 → мой сервер.

Ещё есть Me → bridges over ru email-pgp GitHub Actions bot → Tor → SSH / SSH-over-onion → мой сервер (чтобы не оставлять single point of failure).

Me → DIRECT → Bittorrent

DNS over VLESS: RU → Yandex DoU; Default → Google DoT

VLESS: VLESS-XTLS-uTLS-REALITY-xudp-gRPC.

Правила маршрутизации реализованы на сервере по geosite / geoip / портам и user_auth.

Ещё и принуждение Yandex DoU для RU доменов, даже если клиент хотел другой DNS.

Выходной IPv4 – дефолтный в системе, входной IPv4 – дополнительный.

Проброс 80\TCP и 443\UDP на входном. SSH слушать только на выходном IPv4.

А не странно будет, что весь трафик идет только к одному и тому же IP?

Нет, схема обкатана, я ей пользуюсь уже неделями. Давайте решать проблемы по мере их поступления. Как минимум, будет куча ложных срабатываний если по такой эвристике что-то там судить.

Итог

Таким образом это инфраструктурный фикс проблемы утечек, а не одноразовые костыли. Теперь можно спокойно любыми шпионами пользоваться, не опасаясь что они что-то там будут пытаться задетектить.

У меня основная политика маршрутизации расположена на сервере, а не на каждом отдельном клиенте. То есть мозг маршрутизации - на сервере, и тонкие клиенты к нему.

Но минимальный фикс, и самый здесь важный, - разделить входной/выходной IP, а дальше политика маршрутизации на Ваше усмотрение, я лишь предложил архитектуру, но она не обязательна для Ваших условий, Вы можете по своему сделать.

Подразумевается, что данная схема – покрывает типовые сценарии быта среднего пользователя.

И сразу возникает вопрос: а как эту штуку поставить на сервер, не порушив при этом ничего?

sing-box и Xray – практически производные от v2ray.

Устанавливается, например в Arch Linux, просто:

yay -S sing-box

Появляется /etc/sing-box/config.json – единственный файл конфигурации.

Перезапускается, – systemctl restart sing-box.

Документация и мануалы: Introduction - sing-box

Могу помочь с портированием Вашей Xray конфигурации.

Нравится, но не нравится.

Я долго наблюдаю, большинство делают критическую ошибку: 1 outbound.
Сделайте 5 с разными SNI.

Наличие разных IP для inbound и outbound – великолепно.
Промежуточная MSK машина не должна подключаться к единственному VLESS серверу.
Добавьте еще второй, на него поставьте dnsmasq и заблокируйте .ru и .рф (и yandex.net).
А в MSK поставьте балансировку, least ping или round robin.

Разве недостаточно на выходном узле весь траффик по geoip:ru заворачивать в WARP? Тогда все коннекты на сервера потенциальных шпионов будут либо с твоего легитимного домашнего IP(в случае если он белый), либо из подсетки CF, которую и так блочат.

А как же разные IP чекеры, которые не проходят в geoip:ru? Покажут реальный входной IPv4 сервера. Их всех заблокировать не выйдет и неправильно как-то.

Правилами маршрутизации это не решить. Только разделением входного / выходного IPv4 вообще в целом. Иначе везде можно найти уязвимости, а они будут.

Ну дык те что живут на территории этой страны будут видеть имнно ip клаудфлейра, проверено.

А импортные скорее всего нашим не стучат.

Плюс как по мне наоборот хорошей стратегией является не заворачивать весь траффик вообще, а точечно разблокировать по белым спискам. Иначе на любом дампе будет яркая аномалия вида “этот чел весь месяц ходил исключительно на сайт с фотками австрийских такс, накачав аж 100гб. Подозрительно”

З.Ы. В любом случае, в прошлый раз банили ASки хостеров целиком, не размениваясь на олиночные адреса.

Условный фронтэнд какого-то приложения может пускать трафик куда угодно. Полностью по geosite/geoip для каждого отдельного куска исполняемого кода не представляется возможным. Если вы не используете изоляцию сетевого стека как в QubesOS.

В соседней теме уже обсуждали, как MAX умеет обходить эти split маршрутизации.

То есть условно к ifconfig.me трафик пойдет мимо geoip:ru, а к серверам MAX – напрямую.
Расхождение – туннель с split маршрутизацией обнаружен.

Тогда снова появляются уязвимости, описанные мною в соседней теме.

Dreaght, предлагаю вам сделать вариант для xray, т.к. sing-box простой юзер явно не осилит, раз даже файл конфигурации не открывается из консоли. Вообще, в идеале через 3xui панель, графический интерфейс все-таки явно удобнее консоли. И понятнее для простого человека.

Всё равно не совсем понимаю, как ему это поможет. Обход на уровне роутера, точечно, по белым спискам. На входе правило geoip:ru →direct, на выходном узле geoip:ru→warp. icmp траффик в туннель не ходит, трассировка кажет болт.

Да, понятно, если они вынесут какой-нибудь stun сервер за границу, это всё не сработает, но чтобы это проканало, нужно чтобы траффик до этого stun прпал в туннель, а он не попадёт(потому что белые списки).

Даже если софт попытается сделать подмену sni, на роутере то хосты сначала резолвятся в ip листы.

Разумеется, всё вышесказанное не относится к случаю, когда vpn стоит немосредственно на мобилке.

А, неправильно понял Ваш ответ, то есть один ТСПУ почему-то блокирует, а другой, параллельно через который тоже может идти трафик – нет. И видимо переодически то к тому и тому переключается.

Возможно, вполне, только как-будто причин меня блокировать не было. Под, например, симптомы “Сибирской блокировки” не бьется. Может какие-то ещё триггер блоки есть, мне неизвестные..

Хорошо, отправлю в лс. Только с него подключения я не принимаю уже в inbound, мне изменить на 0.0.0.0? Или просто IP нужен без того чтобы на нем что-то слушали (хотя, SSH слушает)?

P.S: По SSH подключения идут, на счёт 443\TCP пока не пробовал.

Не пойдет: заворачиваем по умолчанию все напрямую, а условный ютуб с телегой куда надо.

То есть, geoip:ru в direct, а всё остальное в туннель?
Представьте MAX спрашивает ifconfig.me и получает какое-то IP. Через что пойдет запрос к ifconfig.me, через туннель, так? Всё, уже входной IP получили, т.к ifconfig.me вернул выходной IP туннеля, который в свою очередь совпадает со входным.

Или я чего-то не понимаю? Если на роутере трафик который не входит в geoip:ru идет через туннель - то разумеется он и вернет IP туннеля.

Напрямую в туннель и через выходной IP который совпадает с входным? Тогда какой IP должен вернуть ifconfig.me?

Напрямую как трафик ходит без впн. Ifconfig выдаст айпи который дал мне мой домашний/мобильный провайдер. Точно такой же будет виден условному MAX.

Все что надо обойти - мой личный белый список, и только он будет идти в тунель.

Да, условный макс всё еще может сам факт использования впн определить - потому что из под моего устройства условный ватсап открывается

Нет, не так. У меня на роутере нет правила для ifconfig.me, так что он пойдёт напрямую.

Как вы реализуете списки IP для CDN сайтов? Шпион просто подкинет фейк SNI и готово. Точно также как и делает Zapret.

IP списки для всего и вся в интернете – ну такое…

Через что-то да пролезет шпион.

Да и опять же для мобильных девайсов не сработает схема. Либо будете носить с собой OpenWRT роутер карманный. Ненадежно..

Я так и делаю, всё хорошо работает. Опять же, я где-то видел тут на форуме говорили что любой тогда может нагенерировать кучу трафика к какому-то сервису для провоцирования его блокировки.

Короче, фигня всё это, тема – про прозрачную инфраструктуру (поставил и забыл), а не вылавливание тараканов по одному. Их можно вылавливать, да, некоторое время будет работать, но будут уязвимости.

Я в таком случае думал просто отказаться от TUN полностью и пользоваться другим режимом, скармливая это все дело только нужным приложениям(жаль не все поддерживают, но много у чего есть веб версии). Ну и с аутентификацией онли, чтобы нельзя было просто обстучать все в телефоне и пойти кидать запросы. Ничего не мешает им просто заметив флаг ТУН не пускать никого. Эти плашки по типу “отключите, а то будет тормозить” надоели. Этого не будет достаточно?

Понятно, вы предлагаете какую-то непонятную, странную, костыльную архитектуру.

Здесь пост вообще не о, “101й способ как обмануть MAX”. Здесь пост об элегантной, надежной инфраструктуре где не нужно париться о “как-бы не слить IP”. Когда-нибудь да ошибетесь. РКН когда будет читать логи вашу ошибку увидит.

Никакие костыли на роутере не сравнятся с простым разделением ingress/egress IPv4 с полным туннелированием трафика.

Как минимум потому что нельзя будет прозрачно на любом устройстве реализовывать нормальные правила маршрутизации, а не кустарные сборки из фиг знает чего.

Тогда ничего в direct напрямую с VPS не пускать.

Зачем? Чем мой gRPC + 100% уверенность, что IP невозможно слить хуже? У меня сейчас топ схема.

Пока вы тут тараканов по одному ловите у меня на iOS всё решается VPN 24/7 с полной работоспособностью любых сервисов.

Ну хотите – продолжайте танцы с бубнами плясать, 101й способ как обманывать шпионы придумывать, пока у меня всё стабильно и прозрачно работает.

Поэтому и на всякий случай. Потому что ру сервисы не надо проксировать изначально.

Ну лично у меня нет нужды 24/7 сидеть на гос услугах или озоне, особенно когда я за пк. Полагаю, у вас тоже.

Поможет. Включите белый список приложений, условный ютуб/телега/инст.

Я предполагал, что здесь все имели sing-box (как-будто наилучший выбор сейчас) и быстро сообразят как поправить их конфигурацию.

Можно попробовать нейронку задолбать этим вопросом, если не поможет, могу помочь в лс.

Как по мне проще в vim из консоли декларативно всё настроить в простом конфиге, сверяясь с документацией, чем какие-то непонятные панели, которые ещё и через раз работают (наигрался с Hiddify Manager год/два назад), теряется часть магии и глубокое понимание исскусства элегантной маршрутизации.

Я всё же рассчитывал не на чайников, как в 4pda или Habr, ошибся, здесь такая же аудитория, либо кому надо уже сделали до моей инструкции, хотя может кто-то и заинтересуется.

Думаю в интернете полно гайдов по sing-box и 80% информации надо брать оттуда. Ещё и самому вникать в документацию sing-box, я её от корочки до корочки изучил. А уже потом поверх этого улучшать. Я к своей схеме месяцами подходил путем проб и ошибок. Хотя у меня огромный бэкграунд до этого был.


У меня раньше был Xray на сервере. А sing-box на клиенте. Но я ушел с Xray, не понравилось разбиваться в нем, sing-box конфиги единообразнее, понятнее.

У меня пока нет обкатанного опыта с этой схемой, что я предложил в статье на Xray. А на sing-box есть, поэтому, к сожеланию, для Xray делать не буду, это потребует исследования их документации, разбирательства и т.д, когда у меня уже хороший боевой опыт использования sing-box.

Но sing-box с нуля настроить до готовного продакшн состояния – могу помочь, с радостью. Sing-box это следующий этап эволюции после Xray, это лучший инструмент. В том числе и клиент могу помочь настроить.

Потом можно обновить статью до установки с нуля.

Да, это хорошо, подразумевалось, что сначала выйдет первая версия, потом будет видно что не так. Понятное дело, что я кучу шагов пропустил и она не полная с нуля до продакшн уровня, чтобы не раздувать статью.

Де-факто да, Ubuntu стандарт, но мне не нравится. Уж привык к AUR и yay. Остальные, думал, сами как-то для своих ОС разберутся.

Ясно, не знал какая тут аудитория просто) В общем не стояла задача сделать гайд для чайников, скорее для уже мидлов в теме которые понимают что к чему и которые ещё не доделали себе прекрасную инфраструктуру как у меня.