Примечание: русская версия была переведена с английского с помощью ИИ. Оригинал на английском языке приведён ниже. Прошу простить возможные неточности в переводе.
Прежде всего, спасибо за подтверждение того, что ранее описанная ошибка со сбросом выделения хостов, а также функция allowlist для внутренних сквадов будут исправлены или добавлены в следующем релизе. Благодарю вас за работу над Remnawave и внимание к предложениям сообщества.
Описание задачи
Я хотел бы предложить возможность добавлять в подписку пользователя временный внешний прокси-сервер, который не управляется Remnawave Node.
Например, основные ноды могут временно быть:
- недоступны;
- заблокированы со стороны провайдера пользователя;
- отключены из-за технических работ;
- недоступны из определённого региона.
В такой ситуации администратор может иметь доступ к другому внешнему серверу с VLESS, Trojan, Shadowsocks или Hysteria2 и захотеть временно добавить его в подписки пользователей.
Этот внешний сервер не должен:
- управляться через Remnawave Node;
- получать список пользователей из панели;
- использовать уникальные данные авторизации каждого пользователя;
- передавать статистику трафика в Remnawave.
Он должен просто появляться в подписке как дополнительный временный вариант подключения.
Ограничение текущего поведения
Обычный Host уже может использовать произвольный адрес, а выбранные Nodes являются только визуальной привязкой. Поэтому сам адрес внешнего сервера не является проблемой.
Проблема заключается в учётных данных.
Сейчас при генерации подписки Remnawave автоматически использует индивидуальные данные пользователя:
- VLESS — UUID пользователя;
- Trojan — пароль пользователя;
- Shadowsocks — пароль пользователя;
- Hysteria2 — индивидуальное значение авторизации пользователя.
Внешний сервер с одним заранее настроенным статическим UUID или паролем не сможет принять эти индивидуальные данные.
Предлагаемое решение
Вместо создания полностью отдельной сущности External Host можно добавить в существующую форму Host настройку:
Источник учётных данных
- Per-user credentials / Учётные данные пользователя — текущее поведение;
- Static credentials / Статические учётные данные — новое поведение для внешнего или неуправляемого сервера.
По умолчанию все существующие и новые хосты должны использовать текущее значение Per-user credentials, чтобы сохранить полную обратную совместимость.
При выборе Static credentials форма может показать только одно дополнительное поле, соответствующее протоколу выбранного Inbound:
- VLESS — статический UUID;
- Trojan — статический пароль;
- Shadowsocks — статический пароль или credential, соответствующий выбранному методу шифрования;
- Hysteria2 — статическое значение auth или пароль.
Получение остальных параметров из Inbound
Чтобы не создавать новый сложный интерфейс для ручной настройки transport, TLS, REALITY, WebSocket, gRPC, XHTTP и других параметров, внешний Host может продолжить использовать существующий Inbound из Config Profile.
Выбранный Inbound будет использоваться только как источник конфигурации:
- protocol;
- transport;
- security;
- flow;
- encryption method;
- SNI;
- path;
- public key и short ID для REALITY;
- TLS и остальные параметры подключения.
Адрес, порт и при необходимости существующие Host Overrides по-прежнему задаются в форме Host.
Такой Inbound не обязательно должен быть активирован на Remnawave Node. Администратор может создать Inbound, соответствующий конфигурации внешнего сервера, и использовать его только для генерации подписки.
Это позволит избежать разработки отдельного ручного конструктора всех протоколов и transport-параметров.
Генерация подписок
Статический Host должен добавляться рядом с обычными Host, а не заменять их.
Он должен поддерживаться во всех форматах подписки, в которых поддерживается выбранный протокол:
- Xray Base64;
- Xray JSON;
- Mihomo;
- Clash;
- Stash;
- Sing-box;
- RAW subscription response.
Особенно важна поддержка Xray Base64, поскольку не все пользователи используют Mihomo или другие структурированные шаблоны.
Для Base64 Remnawave должен сгенерировать обычную ссылку с указанными статическими данными:
- vless://STATIC-UUID@…
- trojan://STATIC-PASSWORD@…
- ss://…
- hysteria2://STATIC-AUTH@…
Предположительно, для этого не потребуется отдельная реализация каждого генератора. После того как Host будет преобразован в обычный ResolvedProxyConfig со статическими учётными данными, существующие генераторы смогут обработать его так же, как остальные Host.
Разумеется, Host должен появляться только в тех форматах и клиентах, которые поддерживают выбранный протокол.
Доступ для внутренних сквадов
Для статического Host должны применяться те же правила видимости, что и для обычных Host:
- доступ для всех подходящих сквадов;
- исключение выбранных внутренних сквадов;
- планируемый режим Allow only selected Internal Squads.
Это позволит:
- показать аварийный Host всем пользователям;
- показать его только определённым сквадам;
- исключить конкретные сквады;
- постепенно включать временный сервер только для затронутых групп пользователей.
Управление и отключение
Для управления можно использовать существующие функции Host:
- Host Visibility;
- Enable/Disable;
- теги;
- порядок отображения;
- исключения по типу подписки;
- Internal Squad visibility.
Администратор предполагается владельцем или оператором внешнего сервера. Поэтому после завершения аварийной ситуации он может:
- отключить статический Host в Remnawave;
- отозвать или изменить статический UUID/пароль непосредственно на внешнем сервере.
Таким образом, даже если клиент сохранил старую конфигурацию и ещё не обновил подписку, администратор сможет немедленно прекратить доступ, отозвав credential на внешнем сервере.
Поскольку статический credential является общим, Remnawave не должен пытаться рассчитывать индивидуальное потребление трафика или управлять пользователями этого внешнего сервера.
В интерфейсе можно показать небольшое предупреждение:
Этот Host использует общие статические учётные данные. Индивидуальный учёт трафика и отзыв доступа для отдельного пользователя недоступны.
Предлагаемый минимальный объём первой версии
Чтобы уменьшить объём разработки, первая версия может включать только:
- переключатель источника учётных данных;
- одно поле для статического UUID, пароля или auth;
- обязательный выбор существующего Inbound;
- использование существующих настроек Host и Internal Squad visibility;
- поддержку существующих генераторов подписок, включая Base64.
Полностью ручной редактор протокола, transport и security-параметров можно не добавлять.
Ожидаемое поведение
- Существующие Host продолжают использовать индивидуальные данные пользователей.
- Static Host использует один заданный администратором credential для всех получателей.
- Static Host отображается рядом с обычными Host.
- Остальные параметры подключения наследуются от выбранного Inbound.
- Static Host не требует подключения к Remnawave Node.
- Remnawave не добавляет пользователей на внешний сервер.
- Трафик через внешний сервер не учитывается в статистике Remnawave.
- Функция работает с Base64 и другими поддерживаемыми форматами.
- Правила Internal Squad visibility применяются так же, как для обычных Host.
- После отключения Host он исчезает при следующем обновлении подписки.
- Администратор может немедленно отозвать credential непосредственно на внешнем сервере.
Возможное название
Название External Host может пересекаться по смыслу с уже существующими External Squads.
Возможные более точные варианты:
- Static-Credential Host;
- Unmanaged Host;
- External Endpoint;
- Subscription-Only Host.
На мой взгляд, наиболее понятным вариантом интерфейса будет не новый тип Host, а настройка:
Credential source: Per-user / Static
Я понимаю, что даже такой сокращённый вариант затрагивает backend, frontend, API-контракты и тестирование нескольких протоколов. Если реализация займёт слишком много времени или не соответствует текущим планам проекта, я полностью это понимаю.
Спасибо за рассмотрение предложения.