Skip to content

Latest commit

 

History

History
274 lines (212 loc) · 16.9 KB

web-server.ru.md

File metadata and controls

274 lines (212 loc) · 16.9 KB

Веб-сервер OpenIPC Viewer (self-host)

English · Русский

У десктоп-приложения есть headless-режим веб-сервера: тот же самый бинарник, запущенный с флагом --server-only, отдаёт браузерную консоль к вашим OpenIPC-камерам по локальной сети. Без облака и лишних сервисов — один пароль администратора и порт.

  • Живой грид (1 / 4 / 9 / 16 / 25) с сохранёнными раскладками и страницами, просмотр отдельной камеры, полноэкранные тайлы. Видео не перезапускается при переходах между страницами.
  • Управление камерами — добавить / изменить / удалить, группы, экспорт/импорт бэкапа конфигурации.
  • Поиск камер в сети — ONVIF, mDNS и опциональный обход подсети, с добавлением найденного прямо из браузера.
  • PTZ — поворот, наклон, зум и пресеты для камер, которые это умеют. Короткое нажатие на пульт сдвигает камеру на один шаг, удержание — плавно ведёт; «домой» и шаговые кнопки появляются, только если камера их поддерживает.
  • Снимки — кадр с любой камеры, с возможностью скачать.
  • Архив — запись камеры прямо из браузера, затем календарь, просмотр, скачивание и экспорт отмеченного фрагмента; перемотка работает, потому что файл отдаётся по диапазонам. Обе морды пишут в одни и те же папки и индекс, так что записанное здесь видно и в десктопе.
  • Пользователи и права — учётные записи с флагами прав и, при желании, подмножеством камер на каждого.
  • H.264 по WebSocket (fMP4 + MSE); H.265 транскодируется на лету. Одна ffmpeg-сессия раздаётся всем зрителям одной камеры.
  • Работает из любого браузера в сети — телефон, планшет, другой ПК.
  • Английский / русский, тёмный скин Console как у десктопа.

Читает и пишет ту же базу, что и десктоп-приложение, — камеры, добавленные в одном, видны в другом.


Быстрый старт (LAN)

  1. Скачайте релиз-архив под свою ОС и распакуйте (openipc-viewer-win-x64.zip, -linux-x64.tar.gz, -osx-arm64.tar.gz) или соберите из исходников.

  2. Задайте пароль администратора (иначе на каждом старте генерируется случайный и печатается в лог — годится для быстрой пробы, но не для постоянного развёртывания).

  3. Запустите с биндом на локальную сеть:

    Linux / macOS

    export OPENIPC_WEB_ADMIN_PASSWORD='придумайте-надёжный'
    ./OpenIPC.Viewer.Desktop --server-only --lan --port 8787

    Windows (PowerShell)

    $env:OPENIPC_WEB_ADMIN_PASSWORD = 'придумайте-надёжный'
    .\OpenIPC.Viewer.Desktop.exe --server-only --lan --port 8787
  4. Откройте http://<ip-этой-машины>:8787 с любого устройства в сети и войдите как admin с заданным паролем.

Без --lan сервер слушает только 127.0.0.1 (доступен лишь с этой машины) — это безопасный дефолт. --lan биндит 0.0.0.0 и печатает предупреждение, потому что на этом уровне нет TLS; для всего, что за пределами доверенной локалки, поставьте его за reverse-proxy.

Флаги

Флаг Значение По умолчанию
--server-only Запуск headless как веб-сервер (без десктоп-GUI) —
--port <n> TCP-порт для прослушивания 8787
--lan Бинд 0.0.0.0 (доступен из локальной сети) выкл. (только localhost)
Переменная окружения Значение
OPENIPC_WEB_ADMIN_PASSWORD Пароль встроенного админа. Не задан → случайный, печатается в лог.
OPENIPC_WEB_SEGMENT_SECONDS Длина одного сегмента записи. По умолчанию 600 (10 мин).

Добавление камер

Четыре способа, все пишут в одну и ту же базу:

  • Найти в сети — Поиск → Искать. Пассивные источники (ONVIF WS-Discovery, mDNS) работают всегда; глубокий скан дополнительно обходит подсеть — находит камеры, которые о себе не заявляют, но со стороны выглядит как сканирование портов. Выберите устройство, введите логин, Опросить — сервер прочитает с камеры настоящий RTSP-адрес и возможности, затем Добавить.

  • Через веб-интерфейс — Камеры → + Добавить камеру.

  • Импорт бэкапа — Система → Импорт JSON-файла, экспортированного из десктоп-приложения или другого инстанса (Система → Экспорт конфига его создаёт; пароли камер в экспорт никогда не попадают).

  • Использовать данные десктопа — запустите сервер на машине, где десктоп уже настроен; он использует ту же локальную базу:

    ОС Путь к базе
    Windows %LOCALAPPDATA%\OpenIPC.Viewer\openipc-viewer.db
    Linux ~/.local/share/openipc-viewer/openipc-viewer.db ($XDG_DATA_HOME)
    macOS ~/Library/Application Support/OpenIPC.Viewer/openipc-viewer.db

    Учётные данные камер лежат в хранилище секретов ОС, а не в этом файле.


Пользователи и права

Из коробки есть одна учётная запись — встроенный администратор с паролем из OPENIPC_WEB_ADMIN_PASSWORD. Пользователи → + Добавить пользователя заводит остальных, у каждого свои права:

Право Что даёт
смотреть эфир видеть список камер и живое видео
PTZ двигать камеру и управлять её пресетами
экспорт вырезать и скачать фрагмент записи
управление всё, что меняет установку: камеры, группы, раскладки, поиск, бэкапы, сессии, пользователи

и, при желании, подмножество камер: оставьте «Все камеры» для полного доступа или отметьте те, которые пользователю можно. Остальные для него не существуют — их нет ни в списке, ни в сетке, ни в API.

Список пользователей лежит рядом с базой в web-users.json (пароли — PBKDF2-хеши, в открытом виде не хранятся). Встроенный администратор продолжает работать и после добавления пользователей: это способ вернуться, если последний аккаунт с правом «управление» потерян, — берегите его пароль.

Изменения прав применяются со следующего входа пользователя.


ffmpeg

Живому видео нужен ffmpeg. Порядок поиска: сначала бандл рядом с приложением (runtimes/<rid>/native/ffmpeg), затем (macOS) префиксы Homebrew, затем ffmpeg в PATH.

  • Windows — в комплекте с релиз-архивом. Ничего ставить не нужно.
  • Linux — в комплекте с релиз-архивом; либо sudo apt install ffmpeg.
  • macOS — в комплект не входит. Поставьте brew install ffmpeg@7; приложение само найдёт его в префиксе Homebrew (keg-only, PATH править не нужно).

Публикация на домене (HTTPS)

Сервер говорит по обычному HTTP. Чтобы открыть его в интернет или из недоверенной сети, терминируйте TLS на reverse-proxy и проксируйте на локальный порт. Сервер уже учитывает X-Forwarded-* от loopback-прокси, а сессионная cookie автоматически становится Secure, как только запросы приходят по HTTPS.

Caddy (автоматические сертификаты Let's Encrypt, WebSocket проходит как есть):

cameras.example.com {
    reverse_proxy 127.0.0.1:8787
}

Запускайте приложение без --lan (бинд на localhost), когда прокси на том же хосте — больше ничего в сеть выставлять не нужно. Если прокси на другом хосте, биндите с --lan и укажите IP прокси, чтобы его forwarded-заголовки считались доверенными (иначе проверки Origin/CSRF отклонят проксированные запросы):

./OpenIPC.Viewer.Desktop --server-only --lan --port 8787
# и задайте доверенные IP прокси — см. WebServerOptions.TrustedProxies

nginx — эквивалент, нужны заголовки WebSocket-апгрейда:

location / {
    proxy_pass         http://127.0.0.1:8787;
    proxy_set_header   Host $host;
    proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header   X-Forwarded-Proto $scheme;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade    $http_upgrade;   # WebSocket живого видео
    proxy_set_header   Connection "upgrade";
}

Запуск как сервис

Linux (systemd) — /etc/systemd/system/openipc-web.service:

[Unit]
Description=OpenIPC Viewer web server
After=network.target

[Service]
Environment=OPENIPC_WEB_ADMIN_PASSWORD=придумайте-надёжный
ExecStart=/opt/openipc-viewer/OpenIPC.Viewer.Desktop --server-only --lan --port 8787
Restart=on-failure
User=openipc

[Install]
WantedBy=multi-user.target
sudo systemctl enable --now openipc-web

Windows — запуск при входе через «Планировщик заданий» или обёртка в сервис через NSSM. Задайте OPENIPC_WEB_ADMIN_PASSWORD как машинную переменную окружения, чтобы сервис её подхватил.


Безопасность

  • По умолчанию localhost. Выставление в сеть (--lan) — опциональный шаг с предупреждением.
  • Своего TLS нет — используйте reverse-proxy для HTTPS (выше).
  • Учётные записи и права. Логин ограничен по частоте (5/мин/IP); сессии — непрозрачные токены в cookie HttpOnly, SameSite=Strict со скользящим TTL 12 часов. Каждый запрос проверяется на сервере: интерфейс прячет недоступное, но защита — не в сокрытии.
  • Веб-сервер — отдельная дверь к вашим камерам. Кто дотянулся до порта и имеет учётную запись, получает всё, что позволяют его права, — с любой машины. Выставляйте сервер в сеть осознанно и давайте каждому только нужные ему камеры.
  • Экспорт конфига никогда не содержит паролей камер.
  • Health-check: GET /healthz (без авторизации) возвращает {"status":"ok","version":"…"}.

Сборка из исходников

dotnet publish src/OpenIPC.Viewer.Desktop -c Release -r linux-x64 \
  --self-contained true -o publish
# Нужен Node — сборка компилирует React-морду и вшивает её.
./publish/OpenIPC.Viewer.Desktop --server-only --lan --port 8787

Замените linux-x64 на win-x64 / osx-arm64 при необходимости.


Как это устроено — куда девается React

Отдельного фронтенда в деплое нет. Браузерная морда — это SPA на React + Vite, чей скомпилированный вывод вшивается внутрь серверного бинарника на этапе сборки, так что в рантайме нет ни Node, ни dist/ для копирования, ни отдельного сервера статики — только один исполняемый файл.

src/OpenIPC.Viewer.Web.Client   React + TypeScript + Vite  (исходники)
          │  dotnet build / publish запускает MSBuild-таргет →
          ▼  npm run build   (Vite выдаёт index.html + хешированные ассеты)
   OpenIPC.Viewer.Web/wwwroot   вывод сборки
          │  вшивается как ресурсы в сборку →
          ▼
   OpenIPC.Viewer.Web.dll       скомпилированная SPA лежит *внутри* этой DLL
          │  в рантайме Kestrel отдаёт её из памяти →
          ▼
   GET /            → встроенный index.html
   GET /assets/*    → встроенные JS / CSS
   GET /grid, …     → клиентские роуты SPA (fallback на index.html)

Node — зависимость только этапа сборки (CI его ставит; сборка из исходников его требует). В скачанном релиз-архиве React-приложение уже впечено в бинарник. Такой подход (эмбед в DLL) ещё и означает, что веб-морда едет вместе со сборкой сервера независимо от того, какой хост её загружает, — а не зависит от специфичного для фреймворка пайплайна статических ассетов.