Addon: Remnawave subscription with HWID restriction on XKeen + Mihomo (Keenetic)

Дополнение: подписка Remnawave с HWID-ограничением на XKeen + Mihomo (Keenetic)

Это дополнение к основной статье «Установка XKeen на ядре Mihomo на роутер Keenetic».
Здесь разбираем узкий, но болезненный случай: на панели Remnawave включён HWID Device Limit — и роутер вдруг перестаёт получать подписку (или получает 404). Чиним за пять минут, добавив пару заголовков в proxy-providers.


Зачем это нужно

В Remnawave есть функция HWID Device Limit — ограничение количества устройств на одного пользователя. Когда она включена, панель ждёт, что клиент при запросе подписки пришлёт заголовок с уникальным идентификатором устройства — x-hwid. По нему панель считает устройства и решает, отдавать конфиг или нет.

Большинство мобильных клиентов (Happ, v2rayTun, Streisand и пр.) формируют и шлют x-hwid сами. А вот Mihomo внутри XKeen по умолчанию его не отправляет — он просто тянет подписку обычным HTTP-запросом. Результат:

  • подписка не обновляется;
  • в логах Mihomo — ошибка загрузки провайдера;
  • при прямой проверке ссылки панель отвечает 404.

Информация. Согласно документации Remnawave: «Если клиент не передаёт обязательный заголовок x-hwid при включённой функции, Remnawave вернёт ошибку 404». То есть это не баг роутера — панель намеренно отклоняет «безымянный» запрос.

Решение — научить Mihomo отправлять нужные заголовки при запросе подписки. В Mihomo для этого есть штатное поле header в секции proxy-providers.

Схема: слева роутер с Mihomo, справа панель Remnawave. Без x-hwid панель отвечает 404; с заголовками — отдаёт конфиг и учитывает роутер как одно устройство.


Как работает HWID Device Limit (коротко)

При включённой функции панель смотрит на заголовки входящего запроса к эндпоинту подписки:

Заголовок Обязателен Назначение Пример значения
x-hwid Да Уникальный ID устройства, по нему считаются устройства keenetic-4426
user-agent Нет Идентификация клиента, влияет на формат отдаваемого конфига Mihomo
x-device-os Нет «ОС» устройства (для отображения в панели) xKeen
x-ver-os Нет «Версия ОС» XKeen 2.0 Beta
x-device-model Нет Модель устройства Keenetic Giga KN-1012

Обязателен только x-hwid. Остальные — опциональны и нужны лишь для красивого отображения устройства в панели.

В ответ Remnawave добавляет служебные заголовки, по которым удобно отлаживать (пригодятся ниже в разделе проверки):

  • x-hwid-active: true — функция активна и запрос принят;
  • x-hwid-max-devices-reached — лимит устройств исчерпан;
  • x-hwid-not-supported — клиент не прислал поддержку HWID;
  • x-hwid-limit — текущий лимит (для совместимости).

Заметка. Роутер — это одно устройство в терминах HWID, даже если за ним сидит вся семья. Поэтому важно задать стабильный x-hwid: тогда роутер всегда занимает ровно один слот в лимите, а не «съедает» новые при каждом обновлении подписки.


Шаг 1. Открываем конфиг Mihomo

Конфиг лежит там же, где и в основной статье:

/opt/etc/mihomo/config.yaml

По сети с Windows тот же файл обычно доступен как:

\\Keenetic-<имя>\new volume\etc\mihomo\config.yaml

Редактировать можно как удобно — по SSH (nano /opt/etc/mihomo/config.yaml), через сетевую шару или через ваш любимый редактор.


Шаг 2. Добавляем заголовки в proxy-providers

Находим секцию proxy-providers с вашей подпиской. Было так:

proxy-providers:
  sub:
    type: http
    url: https://<ваша-ссылка-подписки>
    path: ./proxy_providers/base64.yaml
    interval: 3600
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 120
      timeout: 3000
      lazy: false
      expected-status: 204

Добавляем блок header (между interval и health-check):

proxy-providers:
  sub:
    type: http
    url: https://<ваша-ссылка-подписки>
    path: ./proxy_providers/base64.yaml
    interval: 3600
    # --- Заголовки запроса подписки (для HWID Device Limit в Remnawave) ---
    header:
      User-Agent:
        - "Mihomo"            # формат конфига; для ядра Mihomo подойдёт Mihomo / Clash-Meta
      x-hwid:
        - "keenetic-4426"     # стабильный уникальный ID этого роутера
    health-check:
      enable: true
      url: https://www.gstatic.com/generate_204
      interval: 120
      timeout: 3000
      lazy: false
      expected-status: 204

Внимание — это главная ошибка новичков. В Mihomo значения заголовков задаются списком (через -), даже если значение одно. Вот так — правильно:

header:
  x-hwid:
    - "keenetic-4426"

А так — конфиг не пройдёт валидацию и Mihomo не стартует:

header:
  x-hwid: "keenetic-4426"   # ❌ строка вместо списка

При желании можно добавить и опциональные заголовки, чтобы устройство красиво подписывалось в панели. Вот полный рабочий пример — именно так настроено у меня:

    header:
      User-Agent:
        - "Mihomo"
      x-hwid:
        - "keenetic-4426"
      x-device-os:
        - "xKeen"
      x-ver-os:
        - "XKeen 2.0 Beta"
      x-device-model:
        - "Keenetic Giga KN-1012"

Заметка. Поля x-device-os / x-ver-os / x-device-model — чисто косметические: они никак не влияют на доступ, а лишь определяют, как устройство подпишется в карточке пользователя Remnawave. Можно подставить что угодно осмысленное — в примере выше роутер отображается как «xKeen · XKeen 2.0 Beta · Keenetic Giga KN-1012».


Шаг 3. Какие значения подставить

x-hwid — самое важное

Это уникальный, постоянный идентификатор роутера. Подойдёт что угодно стабильное:

  • понятное имя — keenetic-4426, home-router-mihomo;
  • MAC-адрес роутера без двоеточий — a1b2c3d4e5f6;
  • сгенерированный UUID — b3f1c2a0-7e44-4c19-9c2a-0f3d8e5a1b22.

Главное правило — не менять его потом. Если поменяете значение, панель посчитает это новым устройством и займёт ещё один слот в лимите.

User-Agent

Влияет на то, в каком формате панель отдаёт конфиг (Clash/Mihomo, sing-box, JSON и т.д.). Для ядра Mihomo берите значение клэш-семейства:

  • Mihomo
  • Clash-Meta
  • mihomo/1.18.0

Если подписка раньше работала без явного User-Agent — Mihomo и так слал свой дефолтный (clash.meta/mihomo), и панель отдавала clash-формат. Указываем явно просто для предсказуемости.


Шаг 4. Применяем изменения

Заголовки начнут отправляться при следующем обновлении провайдера. Чтобы не ждать час (interval: 3600) — перезапускаем Mihomo:

xkeen -restart

Заметка. Файл подписки кэшируется в ./proxy_providers/base64.yaml. Если хотите быть уверены, что Mihomo заново скачал подписку уже с заголовками, удалите кэш и перезапустите:

rm /opt/etc/mihomo/proxy_providers/base64.yaml
xkeen -restart

Тогда при старте провайдер sub подтянется с нуля — с новыми заголовками.

Альтернативно можно дёрнуть обновление провайдера из веб-панели Mihomo (http://<IP-роутера>:9090/ui → Proxy Providers → Update).


Шаг 5. Проверяем, что всё работает

Способ 1. Запрос с заголовками вручную

С роутера (там есть curl из основной статьи) или с ПК выполните запрос, имитируя Mihomo, и посмотрите заголовки ответа:

curl -s -D - -o /dev/null \
  -H "x-hwid: keenetic-4426" \
  -H "user-agent: Mihomo" \
  "https://<ваша-ссылка-подписки>"

Что хотим увидеть в ответе:

  • статус 200 OK (а не 404);
  • заголовок x-hwid-active: true — значит панель приняла HWID.

Для сравнения — запрос без x-hwid при включённой функции вернёт 404:

curl -s -o /dev/null -w "%{http_code}\n" "https://<ваша-ссылка-подписки>"
# 404

Способ 2. Логи Mihomo и веб-панель

  • В логах Mihomo больше нет ошибок загрузки провайдера sub.
  • В веб-панели (:9090/ui) у провайдера обновился список нод и время последнего обновления.

Способ 3. Панель Remnawave

В карточке пользователя в Remnawave должно появиться устройство с вашим x-hwid (и моделью/ОС, если вы их указали). Счётчик устройств — 1/N.


Типичные проблемы

Симптом Причина Решение
Mihomo не стартует после правки x-hwid/User-Agent заданы строкой, а не списком Приведите к виду - "значение" (см. callout в Шаге 2)
По-прежнему 404 Запрос всё ещё без x-hwid (старый кэш) или опечатка в имени заголовка Удалите base64.yaml, перезапустите; имя строго x-hwid
x-hwid-max-devices-reached Достигнут лимит устройств у пользователя Поднимите лимит в панели или сбросьте старые устройства
Каждое обновление «съедает» новое устройство x-hwid меняется (например, генерируется заново) Зафиксируйте постоянное значение x-hwid
Заголовки не уходят Правка не в том провайдере / не перезапущен Mihomo Проверьте отступы YAML, выполните xkeen -restart

Итог

Чтобы XKeen на ядре Mihomo дружил с Remnawave и его HWID Device Limit, достаточно одного блока в proxy-providers:

    header:
      User-Agent:
        - "Mihomo"
      x-hwid:
        - "keenetic-4426"
      x-device-os:
        - "xKeen"
      x-ver-os:
        - "XKeen 2.0 Beta"
      x-device-model:
        - "Keenetic Giga KN-1012"

Минимально обязательны только User-Agent и x-hwid — остальные три заголовка опциональны и нужны лишь для красивого отображения устройства в панели.

Главные правила:

  1. Значения заголовков — списком (- "..."), иначе Mihomo не запустится.
  2. x-hwid должен быть стабильным — роутер тогда занимает ровно один слот в лимите.
  3. После правки — сбросить кэш base64.yaml и xkeen -restart.

Источники