◆ ForgeVis
Skip to content

Безопасность и авторизация ​

ForgeVis использует внутреннюю Basic-авторизацию через блок security.users.

Как работает проверка ​

Если security.users пустой — запросы разрешены (режим обратной совместимости). Если есть хотя бы один пользователь, проверка идет по шагам:

  1. IP/CIDR список (ips)
  2. Разрешение (action, опционально path)
  3. Учетные данные (user / pass)

path у HLS, WebSocket и WebRTC — идентификатор камеры: пользователь с path: cam1 видит только cam1 по любому из них. Просмотр (WHEP) требует read, публикация (WHIP) — publish.

Изменения security.users применяются без перезапуска, вместе с остальной конфигурацией: удалённый пользователь и сменённый пароль перестают действовать сразу.

Подбор пароля. После security.lockout.attempts неудачных входов подряд (по умолчанию 10) пользователь блокируется с этого адреса на duration_sec секунд (по умолчанию 300) — на всех серверах сразу, включая RTSP. Считается пара «адрес + имя пользователя»: оператор, ошибившийся паролем за общим NAT, не блокирует остальных. Не считаются запросы без пароля (так начинает любой клиент) и верный пароль, которому не разрешена камера или действие. Блокировка видна в журнале строкой WARN и в метрике auth_lockouts_total.

Форматы учётных данных ​

Каждое значение user / pass должно иметь явный префикс метода. Значения без известного префикса отклоняются (fail-closed) — это исключает ситуацию, когда опечатка в префиксе молча превращает хеш в plaintext-строку.

Поддерживаемые префиксы:

ПрефиксФорматКогда использовать
argon2:PHC-строка: $argon2id$v=19$m=…,t=…,p=…$<salt>$<hash>Рекомендуется — соль + медленный хеш
sha256:<base64-сырого-sha256-дайджеста>Совместимость со старыми тулами
plain:<plaintext>Только разработка / закрытая сеть

Все сравнения учётных данных выполняются за константное время — по результату проверки нельзя понять, сколько символов неверного пароля совпало с настоящим.

Пример Argon2id (рекомендуется) ​

Сгенерируйте хеш стандартным argon2-CLI (argon2/argon2-cli):

bash
echo -n "mypass" | argon2 "$(openssl rand -hex 16)" -id -t 2 -m 16 -p 1 -e
# → $argon2id$v=19$m=65536,t=2,p=1$<salt>$<hash>
yaml
security:
  auth_method: internal
  users:
    - user: viewer
      pass: "argon2:$argon2id$v=19$m=65536,t=2,p=1$c2FsdHNhbHQ$<hash>"
      ips: []
      permissions:
        - action: read

Пример SHA256 (legacy) ​

bash
echo -n "mypass" | openssl dgst -binary -sha256 | openssl base64
yaml
security:
  auth_method: internal
  users:
    - user: viewer
      pass: sha256:6nHCWnpgIka0w5gkuFVniJSpb0O7m3ExnDlwCh4EUiI=
      ips: []
      permissions:
        - action: read

Замечание: SHA256 здесь без соли и быстрый — защищает от случайной утечки в логи, но слаб против offline-перебора. Для новых развёртываний лучше argon2:.

Пример Plain (только разработка) ​

yaml
security:
  users:
    - user: viewer
      pass: "plain:change-me"
      ips: []
      permissions:
        - action: read

Миграция ​

В предыдущих релизах значения без префикса принимались как plaintext (тихий catch-all). Этот fallback убран; перехеширование обязательно:

  1. Сгенерировать argon2: (или sha256:) значения для всех пользователей.
  2. Обновить конфиг, перезапустить.
  3. На большом флоте — выкатывать по одному пользователю, проверяя доступ.

Пользователь и изоляция службы ​

Служба из пакета работает от системного пользователя forgevis, а не от root, и в изоляции systemd: /usr, /boot и /etc для неё только для чтения (кроме /etc/forgevis), домашние каталоги недоступны, возможностей root нет. Уязвимость в разборе того, что присылает камера, не даёт root на хосте.

Что из этого следует:

  • Каталог архива (record_path) должен принадлежать forgevis: chown forgevis:forgevis <каталог>. Каталог по умолчанию, /var/lib/forgevis/recordings, уже его.
  • Хуки (runOnSegmentCreate, runOnSegmentComplete, runPeriodically) выполняются от forgevis в той же изоляции: писать в /etc, /usr, /boot и в домашние каталоги они не могут.
  • Ключи TLS в /etc/forgevis/tls/ должны читаться группой forgevis: chown root:forgevis node.key && chmod 640 node.key.
  • forgevis --retention из cron по-прежнему запускается от root.

Установка, работавшая от root ​

При обновлении установки, которая работала от root, пакет оставляет её на root: архив, состояние и журналы принадлежат root, а передать терабайты другому владельцу — отдельная работа, а не обновление пакета. Для этого он кладёт /etc/systemd/system/forgevis.service.d/10-run-as-root.conf. Изоляция при этом действует.

Перевести такую установку на forgevis можно в окно обслуживания:

bash
sudo systemctl stop forgevis
sudo chown -R forgevis:forgevis <каталог архива> /var/lib/forgevis /var/log/forgevis
sudo chown forgevis:forgevis /etc/forgevis/instance_id
sudo chown forgevis:forgevis /etc/forgevis/forgevis.lic   # если лицензия установлена
sudo rm /etc/systemd/system/forgevis.service.d/10-run-as-root.conf
sudo systemctl daemon-reload && sudo systemctl start forgevis

TLS для HTTP-серверов ​

Учётные данные передаются схемой Basic, то есть в открытом виде. Без TLS их видит любой, кто слушает сеть между клиентом и узлом.

Включается одной настройкой на весь узел:

yaml
tls:
  enabled: true
  cert: /etc/forgevis/tls/node.pem
  key:  /etc/forgevis/tls/node.key

Это покрывает все HTTP-слушатели сразу: управляющий API, HLS, сигнализацию WebRTC, воспроизведение архива и метрики.

Переключатель один намеренно. Браузер, открывший интерфейс по https, не загрузит плейлист HLS или эндпоинт WHEP по http — это правило смешанного содержимого, и запрос блокируется. Раздельные настройки позволяли бы собрать заведомо нерабочую комбинацию, а выглядело бы это как поломка HLS, а не как ошибка в конфигурации.

enabled задаётся явно, а не выводится из наличия путей: так пути можно оставить в файле и выключить TLS на время разбирательства. Значение true без читаемого сертификата и ключа — отказ стартовать, а не тихий откат на открытый HTTP.

Сертификат читается при запуске, поэтому его замена требует перезапуска.

Что это даёт и чего не даёт ​

Трафик шифруется — учётные данные перестают ходить открытым текстом. Это то, ради чего настройка существует.

Аутентификация сервера — отдельный вопрос, и зависит она от сертификата. Самоподписанный или выпущенный вашим внутренним центром сертификации браузер не знает: он покажет предупреждение, а curl потребует -k. Чтобы клиент мог проверить, с кем говорит, ваш удостоверяющий центр нужно раздать клиентам — это задача установки.

Самоподписанный сертификат для локальной сети:

bash
openssl req -x509 -newkey rsa:2048 -nodes -days 825 \
    -keyout node.key -out node.pem -subj "/CN=fv1.example.local" \
    -addext "subjectAltName = DNS:fv1.example.local, IP:192.168.1.10"

chmod 600 node.key

В SAN должно быть то имя или адрес, по которому к узлу обращаются, — то, что вводят в адресную строку.

Не путать с cluster.tls

Это разные вещи. tls — как клиент проверяет узел, и это можно выключить. cluster.tls — как узлы проверяют друг друга: там нужен ещё и clientAuth, а выключить нельзя. См. Кластеризация.

Медиа WebRTC шифруется всегда

Настройка управляет только HTTP сигнализации (WHEP/WHIP). Сам поток защищён DTLS-SRTP, это обязательное требование протокола.

Практики безопасности ​

  • Включайте tls либо выносите узлы в приватную сеть или VPN.
  • Предпочитайте argon2: для хранения паролей.
  • Разделяйте пользователей по действиям: read, api, metrics.
  • Для привилегированных пользователей ограничивайте доступ через ips CIDR.

Proprietary software.