SIRINVIDEO Документация администратора и интегратора На сайт 2026.08

Авторизация публикации

Как закрыть приём видео по RTMP(S) и WHIP: действие publish, учётные данные в строке запроса RTMP-URL и коды отказа, которые увидит кодировщик.

Завести видео в SirinVideo можно двумя принципиально разными способами, и авторизуются они по-разному.

Способ Кто инициирует соединение Авторизация
Публикация: RTMP, RTMPS, WHIP внешний кодировщик или браузер да — действие publish через auth_backend
Активный забор: input rtsp://…, input https://…m3u8, input udp://… сам сервер неприменима — учётные данные источника едут в URL источника

Эта страница — про первый случай.

Общее правило: действие publish#

Публикация авторизуется отдельным действием, а не «правом на поток». Токен на просмотр публиковать не даёт, и наоборот — проверено на стенде для обоих протоколов.

{"sub":"encoder-1","exp":1787200000,
 "grants":[{"action":"publish","path":"ingest/cam1","protocols":["rtmp"]}]}
Поле Значение для публикации
action publishне read и не playback
path путь потока, для которого в конфигурации объявлен источник publish://
protocols rtmp для RTMP и RTMPS, whip для WHIP; пусто = любой

Привилегии (live, dvr, export, preview) описывают просмотр и к публикации отношения не имеют: маска привилегий никогда не может случайно стать правом публиковать. Поэтому компактный грант по метке (<метка>.<маска>) публикацию не открывает — нужно обычное разрешение с action: publish.

Право на публикацию по RTMP выдаётся только путём

Решение по RTMP-публикатору принимается по реестру шлюзов приёма, в котором меток потоков нет: в проверку приходит пустой список меток (это видно в теле запроса к внешней службе авторизации — "labels":[]). Значит, разрешение вида {"action":"publish","labels":["site-north"]} RTMP-push не авторизует — нужен path, точный или *-глоб. Для WHIP ограничение не действует: там метки потока доступны, и правило по меткам работает как обычно.

Без auth_backend публикация открыта всем, кто знает путь

Как и просмотр: если блока auth_backend нет, публиковать может любой, кто дотянулся до порта и угадал путь потока. Порт приёма никогда не должен смотреть в интернет без настроенной авторизации.

RTMP и RTMPS#

Конфигурация#

rtmp  1935;
rtmps 1936;

auth_backend {
    type   hs256;
    secret "секрет-подписи-токенов-публикаторов";
}

stream ingest/cam1 { input publish://rtmp; }
Параметр Тип и допустимые значения По умолчанию Применение
rtmp номер порта, 0 = выключено 0 рестарт
rtmps номер порта, 0 = выключено 0 рестарт

Поток без объявленного publish://-источника публикацию не принимает вовсе. Если ни один порт приёма не поднят, конфигурация не пройдёт проверку:

stream "ingest/cam1": a publish:// source needs an `rtmp`/`rtmps` listener (RTMP publish) or a `webrtc_udp_port` (WHIP)

Как адресуется публикатор#

Кодировщик идёт на rtmp://media.example.com:1935/<приложение>/<поток>. Сервер разрешает ключ так:

  1. сначала ищет поток с путём <приложение>/<поток> — например ingest/cam1;
  2. если не нашёл — ищет поток с голым именем <поток>.

Совпавший ключ и становится путём потока. Благодаря второму шагу поток с плоским именем (stream cam1) принимает публикатора, пушащего в любое приложение (rtmp://host/live/cam1).

Учётные данные едут только в строке запроса URL#

У RTMP нет заголовков — предъявить Authorization: Bearer физически негде. Единственный носитель — строка запроса:

rtmp://media.example.com:1935/ingest/cam1?token=$TOKEN

Хвост ?… срезается с обеих половин адреса — и с приложения (оно приезжает в составе tcUrl), и с ключа потока — до любого поиска потока. Это важно практически: без такой обрезки имя с хвостом просто не находилось бы, и включение авторизации выглядело бы как поломка совместимости.

Обе распространённые формы настройки кодировщика работают, обе проверены на стенде:

Как настроен кодировщик Что получается Результат
«Сервер» rtmp://media.example.com:1935/ingest, «Ключ потока» cam1?token=$TOKEN хвост на ключе принято
«Сервер» rtmp://media.example.com:1935/ingest?token=$TOKEN, «Ключ потока» cam1 хвост на приложении принято

Если хвост стоит на обеих половинах, побеждает тот, что на ключе потока.

Ключ потока — естественное место для токена

Поле «Ключ потока» есть у любого кодировщика, и именно оно обычно хранится в его настройках как секрет. Выдавайте кодировщику строку вида cam1?token=… целиком — менять «адрес сервера» при ротации токена не придётся.

Проверка идёт до захвата шлюза потока#

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

Что увидит кодировщик при отказе#

Ситуация Статус RTMP Текст причины
учётных данных нет NetStream.Publish.Denied unauthorized
токен есть, но прав на публикацию в этот поток нет NetStream.Publish.Denied forbidden
для этого пути нет потока с publish:// NetStream.Publish.BadName no publish gate on this node — a publisher must target the stream's host node
слот уже занят другим публикатором NetStream.Publish.BadName already publishing

Проверенная матрица (сервер с auth_backend { type hs256; }, поток ingest/cam1 с источником publish://rtmp):

Что предъявлено Результат
ничего Server error: unauthorized
токен {"action":"read","path":"ingest/cam1"} Server error: forbidden
токен {"action":"publish",…,"protocols":["whip"]} Server error: forbidden
токен {"action":"publish",…,"protocols":["rtmp"]} принято

В журнале сервера отказ виден одной строкой; успешный приём — тоже:

[ingest/cam1] rtmp publish denied — unauthorized
[ingest/cam1] rtmp publish denied — forbidden
[ingest/cam1] rtmp publisher connected
RTMPS шифрует канал, но не аутентифицирует

rtmps — это тот же RTMP поверх TLS. Он защищает токен в пути (в открытом RTMP строка запроса идёт по сети как есть), но сам по себе не является учётными данными. Для публикации из недоверенной сети используйте rtmps и токен.

Выдача по RTMP авторизуется тоже#

Забрать поток по RTMP (rtmp://media.example.com:1935/ingest/cam1) — это отдельный гейт с действием read и привилегией live, полный аналог DESCRIBE в RTSP. Учётные данные передаются так же, строкой запроса; отказ приходит как NetStream.Play.Failed с той же парой причин (unauthorized / forbidden). Проверено:

Что предъявлено Результат
ничего Server error: unauthorized
токен {"action":"read",…,"protocols":["rtmp"]} видео идёт
токен {"action":"read",…,"protocols":["hls"]} Server error: forbidden
токен {"action":"publish",…} Server error: forbidden

Подробнее о просмотре — Авторизация просмотра.

Проверьте это после обновления

Раньше RTMP обходил авторизацию: при полностью настроенном auth_backend HTTP отвечал 401, а RTMP в тот же момент отдавал видео и принимал публикацию. Сейчас оба направления закрыты.

Практически это значит, что после обновления кодировщик или потребитель без токена перестанет работать. Заранее раздайте токены публикаторам и всем, кто забирает поток по RTMP, — иначе приём встанет молча, с одной строкой в журнале. Сервер без настроенного auth_backend не изменился: там RTMP по-прежнему открыт, как и всё остальное.

WHIP (публикация WebRTC из браузера)#

Конфигурация#

webrtc 40000;

auth_backend {
    type   hs256;
    secret "секрет-подписи-токенов-публикаторов";
}

stream ingest/studio { input publish://whip; }
Параметр Тип и допустимые значения По умолчанию Применение
webrtc номер UDP-порта; необязательный суффикс public_ip=<адрес> 0 = выключено рестарт

Точка входа — POST /s/{поток}/whip. В отличие от RTMP, здесь есть заголовки, поэтому токен можно передать и заголовком Authorization: Bearer, и как ?token=.

{"sub":"studio-1","exp":1787200000,
 "grants":[{"action":"publish","path":"ingest/studio","protocols":["whip"]}]}

Решение принимается до разбора SDP и до занятия слота публикатора — по той же причине, что и в RTMP.

Что предъявлено Ответ
ничего 401
токен на просмотр того же потока 403
токен publish (заголовком или ?token=) авторизация пройдена, дальше — обычный обмен SDP
токен publish, отправленный на …/whep 403

Адрес сессии, который сервер возвращает в заголовке Location, — одноразовый идентификатор, привязанный к пути и роли. DELETE по чужому пути, неизвестный и уже удалённый идентификатор неотличимы: все три отвечают 404.

Активный забор источника#

Для input rtsp://…, input https://…m3u8, input udp://… соединение инициирует сам сервер — авторизовывать входящего некого. Учётные данные источника передаются в самом URL и являются исходящими:

stream cam1 { input rtsp://admin:пароль@10.0.0.10:554/Streaming/Channels/101; }

Подробнее — Приём видео: обзор.

Сводная таблица#

Способ Аутентификация Носитель учётных данных Если auth_backend не настроен
RTMP / RTMPS публикация да, action: publish, protocols: ["rtmp"] только строка запроса URL открыто всем, кто знает путь
RTMP выдача да, action: read, protocols: ["rtmp"] только строка запроса URL открыто
WHIP да, action: publish, protocols: ["whip"] заголовок либо строка запроса открыто всем, кто знает путь
Активный забор неприменима учётные данные источника в его URL неприменима

Проверка#

Публикация закрыта, а законный кодировщик проходит

Токен выпускается тем же генератором, что и для просмотра, — достаточно поменять действие на publish (см. Генераторы токенов).

# 1. без токена — должно быть отказано
ffmpeg -re -f lavfi -i testsrc -c:v libx264 -t 3 -f flv \
  rtmp://media.example.com:1935/ingest/cam1
# 2. с токеном публикации — должно быть принято
ffmpeg -re -f lavfi -i testsrc -c:v libx264 -t 3 -f flv \
  "rtmp://media.example.com:1935/ingest/cam1?token=$TOKEN"
[rtmp @ 0x…] Server error: unauthorized
Error opening output rtmp://media.example.com:1935/ingest/cam1: Operation not permitted

Второй запуск завершается без сообщений об ошибке, а в журнале сервера появляется [ingest/cam1] rtmp publisher connected.

После отключения публикатора шлюз освобождается не мгновенно

Между разрывом соединения и готовностью принять следующего публикатора проходит несколько секунд: поток фиксирует уход источника и переподключается. Повторная публикация в этом окне получает already publishing либо no publish gate on this node — это не отказ авторизации. Подождите и повторите.