Обновить

Написал NetRuleRouter, чтобы сайты, приложения и сети работали через разные подключения без отключения VPN

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели12K
Всего голосов 14: ↑12 и ↓2+10
Комментарии29

Комментарии 29

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

Да, раздельная маршрутизация трафика есть у многих VPN-клиентов, и я не утверждаю, что NetRuleRouter первым реализовал эту возможность.

Если вам достаточно направить Яндекс и Хабр напрямую, а остальные сайты через VPN, и БатяVPN уже решает эту задачу, то дополнительная программа действительно может быть не нужна.

Вопрос скорее в глубине настройки. NetRuleRouter не привязан к конкретному VPN-провайдеру или протоколу и работает с уже существующими сетевыми интерфейсами. Можно задавать правила по доменам, IP-адресам, подсетям, диапазонам и приложениям, просматривать пересечения правил, отслеживать соединения и управлять поведением при отключении дополнительного подключения.

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

Думаю, будет полезно подготовить отдельную статью со сравнением NetRuleRouter, популярных VPN-клиентов, sing-box и других решений — на конкретных сценариях, с указанием не только преимуществ, но и ограничений каждого.

Далеко не все, тот же весьма известный hidemyname не умеет

Хотелось бы увидеть возможность работы с неограниченным (3-4 и даже 8) количеством одновременных подключений VPN. Чтобы трафик от приложений можно было направлять по определенным маршрутам.

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

Сейчас важно различать количество VPN, одновременно работающих в операционной системе, и количество маршрутов, которыми непосредственно управляет NetRuleRouter.

Например, у меня одновременно используются рабочие VPN — один с аутентификацией через Рутокен, другой на WireGuard. В NetRuleRouter я указал, что подключения к их шлюзам должны идти через основной канал. При необходимости эти подключения можно направить через дополнительный канал или назначить один из самих VPN дополнительным подключением NetRuleRouter.

То есть несколько VPN уже могут сосуществовать, сохраняя собственные маршруты. Но непосредственно выбирать третий, четвёртый или восьмой канал для произвольных правил NetRuleRouter пока не позволяет.

Такая возможность потребует расширения архитектуры, обработки конфликтующих маршрутов, DNS и защиты от утечек. А самое сложное — проверка различных сочетаний на реальных системах.

Пока мой приоритет — стабилизировать существующие возможности на Windows и Linux. Позднее хочу рассмотреть поддержку macOS и большего количества управляемых подключений.

А для вашего сценария речь идёт о нескольких независимых VPN для выхода в интернет или о подключениях к разным корпоративным сетям?

Несколько одновременно запущенных клиентов VPN (например, Throne и FLClash), в режиме локальных прокси, без TUN и подмены системного прокси. В каждом свои наборы конфигураций для разных задач (+ прямое подключение никуда не делось).

Сейчас я могу использовать разные браузеры, указав в них 127.0.0.1:[разные порты для разных клиентов], и тогда трафик из разных браузеров (в каждом свои наборы вкладок) пойдет по разным маршрутам. Использовать один браузер я не могу, а хочется.

Спасибо за подробное описание! Теперь гораздо понятнее, какую именно задачу вы хотите решить. И спасибо за идею — такой сценарий я раньше подробно не рассматривал.

В текущем NetRuleRouter можно распределять исходящие соединения самих Throne и FLClash между основным и дополнительным сетевыми подключениями. Но автоматически выбирать между их локальными прокси для разных сайтов одного браузера программа пока не умеет.

Я немного изучил ваш сценарий. Уже сейчас его частично можно решить через FoxyProxy или PAC-файл, задав правила выбора локальных прокси по доменам. Для NetRuleRouter в перспективе вижу как минимум два возможных варианта: управление такими правилами через единый интерфейс с формированием PAC-файла либо собственный механизм выбора между локальными прокси. Второй вариант сложнее, зато потенциально применим не только к браузерам.

Хотелось бы подробнее узнать ваши потребности. Например, достаточно ли автоматически распределять разные сайты между прокси или необходимо открывать даже один и тот же сайт в разных вкладках через разные подключения? Есть ли другие сценарии, которые нынешняя схема с несколькими браузерами не позволяет реализовать?

Если будет желание, напишите подробнее здесь в комментариях, в личные сообщения на Хабре или в ТГ лично — как вам удобнее.

Я зафиксирую этот сценарий для дальнейшего развития NetRuleRouter. Публичную дорожную карту обновлю немного позднее, когда сформулирую требования и оценю возможные варианты реализации. Сроки пока обещать не буду: сейчас основной приоритет — стабилизация первой альфы.

Ещё раз спасибо за предметное предложение!

  1. Как решить можно сейчас, я знаю. 😁 Просто хотелось бы некоторого отдельного слоя роутера, над слоем клиентов VPN (и сетевых соединений, включая физические).

  2. Один сайт - один маршрут, разумеется, но я пока не знаю, что сказать про работу с геоIP и доменами. Ниже правильно сказали, что на российских сервисах могут быть встроенные ловушки внутри кода страниц.

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

Теперь картина ещё понятнее, спасибо! 🙂 Получается, нужен единый слой маршрутизации над физическими подключениями, VPN-клиентами и локальными прокси, а не ещё один VPN-клиент.

Причём здесь интересны обе стороны: NRR должен уметь использовать существующие SOCKS5/HTTP-прокси как выходы и сам предоставлять локальный SOCKS5 для приложений, выбирая дальнейший маршрут по правилам.

Согласен, что один сайт — один маршрут. А для чувствительных сервисов можно предусмотреть строгое закрепление, чтобы соединения не переключались между выходными IP. Хотя от проверок на стороне самих сайтов это, конечно, не гарантирует защиты.

Добавлю эту архитектуру в исследовательскую часть roadmap. Пока приоритет — довести текущее до стабильного релиза.

Правильно понимаю, что в идеале вы хотите прописать во всех поддерживающих прокси приложениях один адрес SOCKS5 от NRR, а уже внутри него управлять всеми маршрутами?

Да, в идеале вынести роутинг в отдельный слой, дать всем приложениям единый интерфейс подключения, чтобы потом менять клиентов VPN не задумываясь о том, как у них внутри что устроено. Был, проще говоря, v2RayN на localhost:2000 - как "Интерфейс 2" в NRR, потом по каким-то своим причинам (подписка в формате .yaml удачная попалась) убрал v2RayN, запустил FLClash с тем же localhost:2000, объявил его как "Интерфейс 2" и у меня все продолжает роутиться так, как и было настроено в NRR.

Теперь понял, спасибо за конкретный пример!

По сути, вы хотите привязывать правила не к определённому VPN-клиенту, а к логическому подключению. В вашем случае это локальный SOCKS5 на 127.0.0.1:2000. Кто его предоставляет — v2RayN, FLClash или что-то другое — для NRR не должно иметь значения.

И это вполне соответствует идее проекта: маршрутизация должна быть независима от используемых VPN и прокси-клиентов.

Здесь нужно будет добавить поддержку прокси как выходных каналов, а для приложений — возможность использовать NRR как единую точку входа. Отдельно придётся продумать DNS, UDP и поведение при смене или остановке прокси-клиента.

Сценарий зафиксировал, теперь есть вполне конкретное требование для проектирования. Пока доводим до стабильности текущую версию, но направление определённо интересное.

Для подключения приложений в большинстве случаев хватит socks5 сервера. Фиксируем его на 127.0.0.1:50000 (50000 - условно, просто красиво) и всё.

Во-первых, не всегда надо настраивать VPN как сетевой интерфейс, да ещё и в качестве default gateway. Тогда вместо "пускай весь трафик через вот это" будет настройка прокси в тех приложениях, которым это надо. Да, есть приложения без поддержки прокси - но вот с ними как раз и стоит разбираться, а не пускать всё подряд.

Во-вторых, тот же singbox (и все GUI на его основе вроде Throne или V2rayN) уже решает задачи роутинга. Просто пропишите ему набор проксей, предоставляемых разными туннелями.

В-третьих, такая схема слишком легко позволяет обнаружить не только наличие VPN, но и адрес выходного узла. Достаточно злонамеренному приложению/сайту сделать запрос на неприметный зарубежный сервер. Более того, есть пара весёлых легитимных URL, которые отдают IP клиента в теле ответа:
https://redirector.googlevideo.com/report_mapping для гугла и
https://www.cloudflare.com/cdn-cgi/trace для любого сайта за cloudflare
Стукачу достаточно сделать запрос к ним.

В-четвёртых, never credit AI assistant? А что так?

Да, неудачная формулировка в сообщении коммита, мой недосмотр.

Посмотрел сам diff: в этом коммите исправлены два места с условной компиляцией под Windows, из-за которых сломалась Linux-сборка. Изменений документации об использовании ИИ в нём вообще нет.

ИИ и кодинг-агентов при разработке проекта я действительно использую — для работы с кодом, тестами, документацией и разбора технических задач. Скрывать это не собираюсь.

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

Спасибо, что обратили внимание. Формулировка в истории коммитов действительно выглядит странно.

Спасибо за развёрнутый комментарий. Отвечу по пунктам.

1. Согласен, если приложение поддерживает прокси и его достаточно настроить отдельно, это вполне рабочее решение.

Но NetRuleRouter не требует назначать VPN шлюзом по умолчанию для всей системы. Он управляет маршрутизацией через уже существующие подключения, в том числе для приложений, которые прокси не поддерживают.

Кроме того, у нас предусмотрена защита от утечек: если дополнительное подключение недоступно, трафик из защищённых правил не должен автоматически переходить на основной канал. Для новых установок такой режим предлагается по умолчанию. У защиты пока есть известные ограничения, которые открыто описаны в документации.

2. sing-box и mihomo я рассматривал ещё при проектировании NetRuleRouter. Это зрелые решения с широкими возможностями, по некоторым из которых они сейчас превосходят мой проект. Например, поддерживают маршрутизацию по портам и протоколам. Такие возможности я тоже рассматриваю на будущее.

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

Поэтому концепция NetRuleRouter другая: установить самостоятельное приложение, выбрать основной интернет и существующий VPN, загрузить готовый набор правил и при необходимости скорректировать его через GUI. Уже есть региональные наборы правил, система рекомендаций дополнительных адресов, проверка пересечений, диагностика и трассировка соединений.

И ещё один важный момент — независимость правил от VPN-клиента. Пользователь один раз настраивает, какие сайты, приложения и сети через какое подключение должны работать. Если позднее он решит сменить WireGuard на OpenVPN, AmneziaVPN или другой VPN с собственным сетевым адаптером, не придётся заново создавать правила маршрутизации для каждого клиента. Достаточно настроить и подключить новый VPN, выбрать его адаптер в качестве дополнительного маршрута NetRuleRouter — существующие правила сохранятся.

То же относится к Linux: при наличии подходящей версии Qt можно через графический интерфейс выбрать уже работающий VPN-адаптер и управлять маршрутизацией без редактирования конфигурации самого VPN ради каждого сайта.

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

Пока это первая публичная альфа, и до зрелости существующих решений ещё далеко. Сейчас мой приоритет — стабильность и совместимость, а не максимальное количество переключателей.

3. С замечанием об определении внешних IP согласен. Но это не уникальная особенность NetRuleRouter, а свойство самой модели раздельной маршрутизации.

В sing-box также можно направлять часть соединений напрямую, а часть через VPN или прокси. Если недоверенное приложение способно инициировать обращения через оба маршрута, оно потенциально может определить оба внешних адреса.

Здесь важно различать защиту от непреднамеренного перехода трафика на другой маршрут и защиту от активного выявления IP-адресов. NetRuleRouter решает первую задачу, но не является инструментом анонимизации и не обещает защиты от второй.

Примеры с Google и Cloudflare полезные, спасибо. Этот сценарий стоит отдельно описать в документации по безопасности.

Но это не уникальная особенность NetRuleRouter, а свойство самой модели раздельной маршрутизации.

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

Риск действительно существует, спорить не буду. Но раздельная маршрутизация используется далеко не только для сервисов с региональными ограничениями. Это и корпоративные VPN, и несколько интернет-подключений, и просто возможность пользоваться разными сайтами и приложениями без постоянного ручного переключения.

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

А вот технические риски можно и нужно минимизировать. У нас уже есть защита от перехода на основной маршрут при недоступности дополнительного, диагностика соединений и проверка доступности сайтов.

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

Всё это включу в дорожную карту проекта, публичную версию которой обновлю немного позднее. Так что спасибо за критику — из неё уже получились вполне конкретные задачи по улучшению защиты и диагностики.

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

Имхо натравить нейросетку на ответы вопросы заданные и напечатанные человеком - зашквар, не делайте так.

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

Вы получили инструмент и пилите новые продукты которые раньше не могли,так и не поняв, что эти продукты с нейронками уже никому не нужны.

А как вы вообще определили, что ответы написаны с помощью ИИ? По стилю?) Если вы предлагаете нейросети даже настройку собственной сети доверять, может, она вам теперь уже в каждом комментарии мерещится?

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

А насчёт «попросить Клода поставить sing-box» — для этого понадобится агент вроде Claude Code с доступом к системе, обычно платный. Технически подготовленный человек и без него всё настроит. А обычному пользователю вслепую доверять агенту маршруты, DNS и файрвол — сомнительная затея. Одна ошибочная команда, и можно вообще без интернета остаться. И хорошо, если без интернета. А если решит исправить что-то и в итоге вообще все данные удалит... Прецеденты есть. Или не знаете? Интересно, как после этого Клода просить всё исправить? :)

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

ИИ — инструмент, а не повод отказываться от разработки удобного софта.

Для того, чтобы это приложение было полезно тем, у кого есть и корпоративный ВПН, нужен дополнительный инструментарий аля dnsmasq, который будет перехватывать (или станет основным dns сервером) и маршрутизировать dns запросы к разным доменам на разные DNS серверы. К корпоративным доменам - на внутренние dns серверы компании, а другим - на другие, к третьим - на публичные например.

Простой пример - при подключении к корпоративному ВПН в большинстве случаев dns резольвером для dns клиента станет корпоративный dns а там может быть наверчено/ заблокировано всякое разное.

Спасибо, хорошее замечание! С корпоративными DNS мы уже частично разобрались: в NRR есть собственный локальный резолвер, а для других VPN предусмотрено определение их DNS-суффиксов и серверов, чтобы не перехватывать запросы к внутренним доменам компании. Это работает через механизмы Windows и Linux, без обязательного dnsmasq.

Но полноценной настройки вида «эти домены разрешать через корпоративный DNS, эти — через домашний, остальные — через публичный» пока действительно нет.

Идея правильная, добавлю её в roadmap. Особенно важно проверить разные корпоративные VPN, включая те, которые принудительно меняют системный DNS или управляются групповыми политиками. В альфе гарантировать совместимость со всеми такими конфигурациями пока не могу.

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

Постараюсь описать обобщенный пример.
В корпоративных VPN есть три основные сущности для управления:
1. При подключении к VPN в таблицу маршрутизации добавляются статические маршруты.
2. При подключении к VPN в таблицу в VPN интерфейс может быть перенаправлен и маршрут по умолчанию 0.0.0.0.
3. При подключении к VPN для всех и публичных и внутренних доменов компании в качестве основного DNS сервера для dns клиента им станет внутренний DNS сервер компании.

Соответственно по первому пункту важно следующее - оперировать маршрутами, так как в компании могут туда добавить не только серые сети, но и публичные (например чтобы заблокировать доступ\перенаправить доступ).
По второму - нужно уметь удалять \ переключать на другой интерфейс маршрут по умолчанию).
По третьему - уметь перенаправлять запросы от DNS клиента ОС к разным DNS серверам по именам доменов. Часто DNS серверы компаний также используются для блокировки доступа\перенаправления трафика.
А еще есть частый вариант - одна и таже DNS зона, принадлежащая организации\компании, отдает разные ip адреса с внутреннего и внешнего DNS компании. Здесь за собой тянется вариант, что этот универсальный DNS резольвер должен понимать, что если корпоративный VPN подключен - то DNS сервер для зоны company.ru - внутренний, а если выключен - то внешний.

IMHO идеальный вариант такой:
1. Руками прописанные\испортированные из таблицы маршрутизации и доступные для редактирования маршруты для каждого VPN и механизм их переприменения с предварительной очисткой при каждом изменении в списке интерфейсов в ОС.
2. по DNS - руками созданный набор доменов и соответствующих им зон, применяемый в зависимости от статуса VPN соединений.

Спасибо за подробное описание! Теперь гораздо понятнее, что вы предлагаете. Особенно интересен случай с одной DNS-зоной, которая отдаёт разные адреса в зависимости от подключения к корпоративному VPN.

Часть механизмов уже есть: NRR отслеживает маршруты сторонних VPN, учитывает их сети (в том числе публичные подсети) и умеет сохранять разрешение внутренних корпоративных доменов через соответствующие DNS. Но полноценного управления маршрутами и DNS-политиками для каждого VPN пока действительно нет.

С идеей согласен, добавлю её к задачам по Split DNS и совместимости нескольких VPN. Только полную очистку и переприменение чужих маршрутов я бы делал очень осторожно: корпоративный клиент может устанавливать их принудительно, и вмешиваться в политику компании не всегда допустимо. Лучше различать собственные маршруты NRR и те, которыми управляет другой VPN, а конфликты явно показывать.

Ещё хотел уточнить: вы рассматриваете сценарий, когда пользователь сам управляет настройками корпоративного VPN, или когда маршруты и DNS принудительно задаются организацией и клиент их постоянно восстанавливает? Для проектирования это довольно существенная разница.

О, не только мне значит такое надо. Я тоже такое навайбкодил, но только для MacOS. Правда функционала чуть меньше и еще требуется тестить (связку с большим количеством vpn) https://splitpipe.tech

Привет. Изучил документацию SplitPipe, интересно получилось! Особенно реализация через NetworkExtension, поддержка нескольких VPN и работа с kill-switch.

А как у вас обстоят дела с Apple Developer Program? Пришлось оформлять платный аккаунт разработчика, получать entitlement для NetworkExtension, подписывать и нотариализовать приложение? Не возникало проблем или ограничений со стороны Apple?

И ещё интересно, какие сочетания VPN уже проверяли на практике и что оказалось самым сложным — сама маршрутизация, DNS или совместимость с чужими kill-switch?

Я macOS пока отложил на будущее, поэтому ваш опыт был бы очень полезен. Кстати, планируете открывать исходники?

Исходники открыты https://github.com/gigimon/splitpipe (надо на сайт ссылку добавить).

Да, я покупал аккаунт apple developer, без него нельзя использовать network extension. Пока что проверено только с амнезией и openvpn, не было времени наставить разных vpn и проверять.

Проблемой было чужие kill switch и то, как все ставят свои правила маршрутизации и когда

Спасибо! Заглянул в репозиторий, особенно понравились подробные технические заметки о проблемах с AmneziaVPN.

Прямо знакомая история :) Самое сложное — не маршрутизировать трафик, а ужиться с другими VPN, которые постоянно меняют маршруты, DNS и правила файрвола. У нас на Windows и Linux тоже немало времени ушло на такие вещи.

Кстати, AmneziaVPN и OpenVPN проверяли одновременно или пока по отдельности?

И ещё два вопроса: удалось уже пройти подпись и нотариализацию приложения у Apple без проблем? И под какой лицензией планируете публиковать код? В репозитории LICENSE пока не увидел.

В любом случае интересно будет обмениваться опытом. У нас платформы разные, а проблемы удивительно похожие :)

да, нотаризация проходит, мне кажется она автоматическая. В app store выложить не получится, там приложение должно быть в песочнице, а из нее многие вещи не сделать

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации