Hub stage 2: install, update and uninstall apps on several servers
Writes use only <ID>_ADMIN_TOKEN and need the apps.write capability. Store URLs are resolved from each server's own listing. The config is saved to history before an uninstall. Zip uploads are fanned out to the servers. Every target's result is audited. The console gets a row menu on the matrix, a target picker, a results dialog with Retry failed, the store and install from file in All servers mode, and single-server actions for writers. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
3d8df08fa0
commit
6acd2d656d
27 files changed
+1991
-71
No files matched your search
@@ -11,6 +11,8 @@ version: "3.8"
|
||||
# Токены кладутся в .env рядом с этим файлом (не в git):
|
||||
# MDNS_TOKEN=...
|
||||
# NDNS_TOKEN=...
|
||||
# MDNS_ADMIN_TOKEN=... # токены hub-admin (Modify и Delete только на Apps): нужны, чтобы хаб менял приложения
|
||||
# NDNS_ADMIN_TOKEN=...
|
||||
# HUB_USER=... # логин в сам хаб
|
||||
# HUB_PASSWORD=... # первый вход; затем пользователи в /data/users.json (docs/hub-deploy.md, шаг 4a)
|
||||
#
|
||||
@@ -30,6 +32,8 @@ services:
|
||||
- HUB_SERVERS=mdns=https://mdns.shnt.top,ndns=https://ndns.shnt.top
|
||||
- MDNS_TOKEN=${MDNS_TOKEN}
|
||||
- NDNS_TOKEN=${NDNS_TOKEN}
|
||||
- MDNS_ADMIN_TOKEN=${MDNS_ADMIN_TOKEN}
|
||||
- NDNS_ADMIN_TOKEN=${NDNS_ADMIN_TOKEN}
|
||||
# Только пока нет /data/users.json; потом пользователи создаются через users-cli (docs/hub-deploy.md)
|
||||
- HUB_USER=${HUB_USER}
|
||||
- HUB_PASSWORD=${HUB_PASSWORD}
|
||||
|
||||
@@ -189,6 +189,9 @@ services:
|
||||
- HUB_SERVERS=mdns=https://mdns.shnt.top,ndns=https://ndns.shnt.top
|
||||
- MDNS_TOKEN=${MDNS_TOKEN}
|
||||
- NDNS_TOKEN=${NDNS_TOKEN}
|
||||
# Токены hub-admin: без них хаб только читает. Нужны для установки и обновления приложений
|
||||
- MDNS_ADMIN_TOKEN=${MDNS_ADMIN_TOKEN}
|
||||
- NDNS_ADMIN_TOKEN=${NDNS_ADMIN_TOKEN}
|
||||
# Только пока нет /data/users.json; потом пользователи создаются через users-cli (docs/hub-deploy.md)
|
||||
- HUB_USER=${HUB_USER}
|
||||
- HUB_PASSWORD=${HUB_PASSWORD}
|
||||
|
||||
+42
-5
@@ -4,7 +4,7 @@
|
||||
|
||||
- запрос «All servers» хаб отправляет на оба сервера и складывает ответы;
|
||||
- запрос к одному серверу хаб пересылает только ему;
|
||||
- запись хаб пока не выполняет: любой запрос на изменение получает отказ и попадает в журнал.
|
||||
- менять хаб умеет только приложения (установка, обновление, удаление), и только для пользователей с ролью `apps-admin` или `admin`. Остальные запросы на изменение получают отказ и попадают в журнал.
|
||||
|
||||
Серверы Technitium не меняются, кластер не нужен. В инструкции хаб ставится на хост, где уже работают Traefik и `technitium-smart` (`docs/compose.shnt.example.yaml`). Адрес хаба: `https://dnss.shnt.top`.
|
||||
|
||||
@@ -72,6 +72,19 @@ git tag hub-v1.0.0 && git push origin hub-v1.0.0
|
||||
|
||||
Результат шага: два токена, `MDNS_TOKEN` (с `mdns.shnt.top`) и `NDNS_TOKEN` (с `ndns.shnt.top`).
|
||||
|
||||
### Шаг 1а. Пользователь для записи (нужен, чтобы менять приложения)
|
||||
|
||||
Без этого шага хаб только читает. Токены записи отдельные, у отдельного пользователя. Сделайте это **на обоих серверах**:
|
||||
|
||||
1. **Группа** `hub-admins`. Права группы (Administration › Permissions):
|
||||
- **Apps**: View, Modify и Delete;
|
||||
- **Dashboard**, **Logs**, **Settings**: только View, и то лишь если хотите, чтобы этот токен мог читать то же, что `hub-reader`. Для записи приложений достаточно Apps.
|
||||
- остальные разделы без прав.
|
||||
2. **Пользователь** `hub-admin` в этой группе, длинный случайный пароль.
|
||||
3. **API-токен** для `hub-admin` (так же, как в шаге 1.4). Это `MDNS_ADMIN_TOKEN` и `NDNS_ADMIN_TOKEN`.
|
||||
|
||||
Хаб использует эти токены только для записи приложений и для чтения конфига приложения перед удалением. Если для сервера токена нет, хаб показывает его «только для чтения» и не вызывает для записи.
|
||||
|
||||
---
|
||||
|
||||
## Шаг 2. DNS-запись для dnss.shnt.top
|
||||
@@ -91,6 +104,10 @@ git tag hub-v1.0.0 && git push origin hub-v1.0.0
|
||||
MDNS_TOKEN=вставьте_токен_mdns
|
||||
NDNS_TOKEN=вставьте_токен_ndns
|
||||
|
||||
# Токены hub-admin с шага 1а (без них хаб не меняет приложения)
|
||||
MDNS_ADMIN_TOKEN=вставьте_токен_записи_mdns
|
||||
NDNS_ADMIN_TOKEN=вставьте_токен_записи_ndns
|
||||
|
||||
# Первый вход в хаб (это НЕ логин Technitium). Нужен, пока не создан файл пользователей (шаг 4a)
|
||||
HUB_USER=admin
|
||||
HUB_PASSWORD=длинный_случайный_пароль
|
||||
@@ -124,6 +141,8 @@ chmod 600 .env
|
||||
- HUB_SERVERS=mdns=https://mdns.shnt.top,ndns=https://ndns.shnt.top
|
||||
- MDNS_TOKEN=${MDNS_TOKEN}
|
||||
- NDNS_TOKEN=${NDNS_TOKEN}
|
||||
- MDNS_ADMIN_TOKEN=${MDNS_ADMIN_TOKEN}
|
||||
- NDNS_ADMIN_TOKEN=${NDNS_ADMIN_TOKEN}
|
||||
- HUB_USER=${HUB_USER}
|
||||
- HUB_PASSWORD=${HUB_PASSWORD}
|
||||
- HUB_DATA=/data
|
||||
@@ -168,7 +187,7 @@ volumes:
|
||||
|---|---|
|
||||
| `viewer` | смотреть |
|
||||
| `operator` | смотреть, блокировка и кеш (после появления записи) |
|
||||
| `apps-admin` | смотреть, управлять приложениями (после появления записи) |
|
||||
| `apps-admin` | смотреть, устанавливать, обновлять и удалять приложения на выбранных серверах |
|
||||
| `admin` | всё, включая журнал действий |
|
||||
|
||||
Пока файла нет, в хаб входит один `admin` из `HUB_USER` / `HUB_PASSWORD`. Когда файл появился, эти две переменные игнорируются (в логе будет строка об этом). Если нет ни файла, ни переменных, хаб не запустится.
|
||||
@@ -258,7 +277,7 @@ docker compose rm -f technitium-hub # удалить контейнер
|
||||
| `HUB_USER`, `HUB_PASSWORD` | нужны, пока нет `users.json` | Первый `admin`; при наличии файла игнорируются |
|
||||
| `HUB_DATA` | `/data` | Папка `users.json` и `audit.log` (на ней том) |
|
||||
| `HUB_TRUST_PROXY` | выключено | `1`: адрес клиента из `X-Forwarded-For` (только за Traefik) |
|
||||
| `<ID>_ADMIN_TOKEN` | нет | Токен записи сервера (`MDNS_ADMIN_TOKEN`). Пока не используется, в логи не пишется |
|
||||
| `<ID>_ADMIN_TOKEN` | нет | Токен записи сервера (`MDNS_ADMIN_TOKEN`). Им хаб меняет приложения; без него сервер только для чтения. В логи не пишется |
|
||||
| `HUB_DOMAIN` | `hub` | Имя, которое консоль показывает как имя сервера |
|
||||
| `HUB_CACHE_SECONDS` | `15` | Сколько секунд хранить ответы серверов (0 выключает кеш) |
|
||||
| `HUB_TIMEOUT_MS` | `8000` | Сколько ждать ответа сервера, мс |
|
||||
@@ -288,10 +307,28 @@ docker compose rm -f technitium-hub # удалить контейнер
|
||||
| В подсказке `ndns: ...` с сообщением об отказе в доступе | У группы `hub-readers` на этом сервере не хватает View в каком-то разделе (шаг 1.2). |
|
||||
| Query Logs пустой или «нет приложения» | На сервере не установлено приложение логирования (Query Logs (Sqlite) и подобные) или нет права View на Apps. |
|
||||
| Цифры «All servers» больше суммы на 1-2 клиента | Clients считается по каждому серверу отдельно: клиент, который ходит на оба сервера, учтён дважды. Это ожидаемо. |
|
||||
| Нажатие на что-то пишет «The hub is read-only.» | Хаб только читает. Изменения делаются в консоли нужного сервера. |
|
||||
| Нажатие на что-то пишет «The hub is read-only.» | Хаб меняет только приложения. Остальные изменения делаются в консоли нужного сервера. |
|
||||
|
||||
## Приложения: установка, обновление, удаление
|
||||
|
||||
Роль `apps-admin` (или `admin`) видит в разделе Apps при «All servers» меню действий в каждой строке и кнопки **App Store** и **Install from file**:
|
||||
|
||||
- **Update on all**: обновить с сервера, где есть обновление;
|
||||
- **Install on missing servers**: поставить из магазина там, где приложения нет;
|
||||
- **Align versions**: подтянуть отстающие серверы до самой новой установленной версии (если магазин её предлагает);
|
||||
- **Uninstall from…**: удалить с выбранных серверов.
|
||||
|
||||
Каждое действие сначала открывает выбор серверов (сервер без токена записи недоступен, с причиной), потом показывает итог по каждому серверу. Если на каком-то сервере не вышло, кнопка **Retry failed** повторит только его.
|
||||
|
||||
Что хаб делает для безопасности:
|
||||
- ссылку на скачивание берёт из магазина самого сервера, произвольный адрес не принимает;
|
||||
- перед удалением сохраняет конфиг приложения в `/data/apps/<имя>/history/` (50 последних на приложение) и не удаляет, если сохранить не удалось. Откат: вставить сохранённый текст в Config приложения на сервере;
|
||||
- каждое действие по каждому серверу пишется в журнал (`apps.update-store`, `apps.uninstall` и т. д.).
|
||||
|
||||
Права на запись у `viewer` и `operator` нет: они получают «Your role does not allow this.».
|
||||
|
||||
## Безопасность
|
||||
|
||||
- Хаб только читает: любая запись получает отказ ещё в хабе (и запись в журнале), а токены выданы пользователю с одними правами View.
|
||||
- Читает хаб токенами с одними правами View. Менять он умеет только приложения, и только токенами `*_ADMIN_TOKEN` (права Apps) по запросу пользователя с ролью `apps-admin` или `admin`. Всё остальное получает отказ в хабе и запись в журнале.
|
||||
- Токены лежат только в `.env` на хосте и в памяти контейнера. В браузер они не попадают, в ответы и логи хаба не пишутся.
|
||||
- У каждого человека свой логин и роль. Вход защищён блокировкой после 5 неудач. Нужны длинные пароли, а если хаб не должен быть виден из интернета, добавьте к роутеру `hub` в Traefik `ipallowlist` или `basicAuth`.
|
||||
Reference in new issue
Block a user