Files
Bridge-and-Join-s/docs/license-server-api.md
T
zuevav 86aa452ed6 feat(license): сервер лицензий lic.zetit.ru — кабинет, онлайн-активация и защита
- bj-license-server: активация по коду и продление токенов (API /v1), кабинет
  администратора (клиенты, лицензии, установки, журнал, администраторы)
- защита: доверенные IP установок, jail fail2ban api/admin, раздел «Защита»
  с режимом обороны, белым списком и сроками блокировок (root-помощник fw-apply)
- доступ к кабинету: свой адрес вместо /admin, вход только из белого списка,
  второй фактор — TOTP или подтверждение в «ЗЕТИТ Ключ» (push/код)
- deploy/license: unit-файлы, fail2ban, path/timer помощника; контракт API в docs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 19:41:11 +03:00

83 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Сервер лицензирования и обновлений bj — контракт API
Сервер: **https://lic.zetit.ru** (ВМ 46.173.19.220, Ubuntu 26.04). Адрес зашит в bj
(`internal/lkgateway`, константа), в интерфейсе не меняется. С этого же сервера bj
получает обновления.
## Модель
- Лицензия — прежний токен `internal/license`: подписанный Ed25519 JSON `License`,
строка `base64(payload).base64(sig).keyid`. Ключ подписи — `~/keys/license.priv`
(keyid `main`); открытый ключ зашит в bj.
- Клиенту выдаётся **код активации** (`BJ-XXXX-XXXX-XXXX`), один на лицензию; им
активируется до `max_nodes` установок (0 — без лимита).
- При активации сервер выдаёт токен **на 60 дней** (`expires_at`), но не дольше
`contract_until`; в токене `install_id` установки и `contract_until` договора.
- bj продлевает токен **раз в сутки**. Отзыв = сервер больше не продлевает; уже
выданный токен доживает свой срок (запас на недоступность сервера).
- Офлайн-ключи (`bj-license issue`, без `install_id`) продолжают работать — для
закрытых контуров без интернета.
## Идентификатор установки
`install_id` — UUID v4, создаётся bj при первом запуске и хранится в
`/var/lib/bj/.bj/setup.json` (`license.install_id`). Вместе с ним bj передаёт
`machine` — sha256(`/etc/machine-id`) в hex (для учёта и обнаружения клонов, не для
отказа).
## Запросы
Все тела — JSON, `Content-Type: application/json`. Ошибки — HTTP 4xx/5xx и
`{"error": "<код>", "message": "<текст по-русски>"}`.
### POST /v1/activate
```json
{"code": "BJ-7K3M-Q9XP-2HDA", "install_id": "…uuid…", "machine": "…sha256…",
"hostname": "bj-server-01", "version": "0.1.0"}
```
200:
```json
{"token": "<payload.sig.main>", "license_id": "…uuid…", "tenant": "ИК Фонтвьель",
"expires_at": "2026-11-14T10:00:00Z", "contract_until": "2027-09-14T00:00:00Z",
"renew_after_sec": 86400}
```
Коды ошибок: `bad_request`, `unknown_code`, `revoked`, `contract_expired`,
`max_nodes` (лимит установок исчерпан). Повторная активация той же `install_id` —
не новая установка, просто новый токен.
### POST /v1/renew
```json
{"token": "<текущий токен>", "install_id": "…", "machine": "…", "hostname": "…", "version": "…"}
```
Сервер проверяет подпись токена (срок **не** проверяет — продлить можно и
истёкший), совпадение `install_id` с токеном, что установка известна и лицензия не
отозвана. 200 — тот же формат, что у activate. Ошибки: `bad_token`,
`install_mismatch`, `unknown_install`, `revoked`, `contract_expired`.
Каждый успешный renew обновляет `last_seen`, `version`, `hostname`, IP установки.
### Обновления
- `GET /v1/{channel}/manifest.json` — подписанный манифест (`internal/release`),
без авторизации.
- `GET /v1/{channel}/files/{file}` — только с заголовком
`Authorization: License <token>`: подпись верна, срок не истёк, лицензия не
отозвана, в признаках есть `updates` (или план `enterprise`). Иначе 401/403 с
JSON-ошибкой. Ключ подписи манифестов отдельный от лицензионного.
### GET /healthz
`ok`.
## Кабинет администратора
`https://lic.zetit.ru/admin/` — вход по логину и паролю (bcrypt), только для нас:
клиенты (название, ИНН), лицензии (план, признаки, max_nodes, contract_until, код
активации, отзыв/восстановление), установки (install_id, hostname, версия, IP,
последнее продление, срок токена), журнал событий, выпуск офлайн-ключа для
закрытого контура.