Skip to content

Лимит устройств/IP на пользователя (limitIp) с просмотром активных IP #109

Description

@Postlog

Категория: feature · Приоритет: medium · Размер: XL · Ранг: 7/10

Что построить

Поле «Лимит IP/устройств» (0 = без лимита) в форме пользователя и просмотр текущих IP клиента в детальной карточке. Старт — display-only список активных IP; энфорсмент (отключение при превышении) добавляется позже поверх флага enable (#89).

Паритет с конкурентами

3x-ui (limitIp + CheckClientIpJob по access-логу Xray), Remnawave (HWID device limit по x-hwid заголовкам), Hiddify. Ограничение шеринга — флагманская анти-resale фича.

Чего не хватает сейчас (код)

add_client.go хардкодит limitIp:0; ClientSpec не несёт лимита IP. Главное: subgen вообще не читает access-логи узлов (xui-клиент знает только inbounds/clients) — нет источника текущих IP и нет цикла энфорсмента. Самый тяжёлый пункт списка.

Зачем

Один оплаченный аккаунт, расшаренный на компанию друзей, — крупнейшая утечка выручки у VPN-реселлеров; лимит IP/устройств её закрывает. Subgen сегодня не ограничивает число подключений с одного credential.

Предлагаемая реализация

Фаза 1 (display-only): новый метод xui-клиента GetClientIps (POST /panel/api/inbounds/clientIps/:email) — один файл + тест; провести limitIp как ClientSpec.LimitIp в AddClient; колонка limit_ip в users. Карточка пользователя показывает текущие IP. Фаза 2 (энфорсмент): периодический воркер сравнивает число IP с лимитом и отключает через флаг enable (#89). Чтение access-логов узла — отдельный большой кусок, в фазу 2. Поэтому в беклоге это xl, но начинается с дешёвого read-пути.

Затронутые файлы

  • internal/entity/panel.go (ClientSpec.LimitIp), internal/clients/xui/get_client_ips.go (новый) + тест, contract.go, add_client.go
  • internal/service/provisioning/service.go, migrations/NNNN-user-limit-ip.sql
  • openapi/{user_create,user_edit,user_ips}.yaml, internal/handlers/user_ips/, internal/handlers/web/static/

Продуктовый ресёрч: изучены аналоги (Marzban/Marzneshin, 3x-ui, Remnawave, Hiddify, sub-store + клиентские стандарты импорта). Паритет и subgen-gap код-обоснованы. Ранг = продуктовый приоритет.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions