Введение: зачем нужен собственный RTMP-сервер
Собственный сервер стриминга на базе Nginx с модулем RTMP дает полный контроль над видеоинфраструктурой. Вы не зависите от тарифов облачных платформ, не платите лицензионные отчисления за каждый канал и получаете минимальную задержку сигнала, так как трафик не покидает ваш дата-центр. Это легковесное решение принимает RTMP-потоки от энкодеров, ретранслирует их зрителям и конвертирует в HLS или DASH для браузеров.
В этом руководстве разберем полный цикл: установку Nginx с модулем RTMP из репозитория и сборку из исходников, базовую конфигурацию для приема потока, преобразование в HLS и DASH, ограничение доступа по IP и ключам, мониторинг активных стримов через встроенную stat-страницу. В конце соберем итоговый конфиг, готовый к продакшн-эксплуатации.
Материал ориентирован на системных администраторов и DevOps-инженеров, которые хотят развернуть надежную платформу для прямых трансляций без привязки к вендорским сервисам. Все примеры проверены на Ubuntu 24.04 LTS и актуальны на июль 2026 года.
Установка Nginx с модулем RTMP
Модуль RTMP не входит в стандартную сборку Nginx. Установить его можно двумя способами: из предсобранных пакетов (быстрый путь для Ubuntu/Debian) или компиляцией из исходников (универсальный метод для любого дистрибутива).
Установка из репозитория
В Ubuntu 24.04 LTS пакет libnginx-mod-rtmp доступен в официальном репозитории. Установка выполняется одной командой:
sudo apt update
sudo apt install nginx libnginx-mod-rtmp -y
После завершения проверьте, что модуль загружен:
nginx -V 2>&1 | grep -o rtmp
Если вывод содержит rtmp, модуль активен. Для CentOS Stream 10 и RHEL-подобных систем предсобранных пакетов нет, поэтому переходите к сборке из исходников.
Сборка из исходников
Сборка из исходников дает полную свободу в выборе версий Nginx и модуля. Сначала установите зависимости для компиляции:
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev git -y
Загрузите исходники Nginx (версия 1.26.x стабильна на 2026 год) и модуль RTMP:
wget https://nginx.org/download/nginx-1.26.2.tar.gz
tar xzf nginx-1.26.2.tar.gz
git clone https://github.com/arut/nginx-rtmp-module.git
Сконфигурируйте сборку с флагом --add-module:
cd nginx-1.26.2
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid \
--add-module=../nginx-rtmp-module
make
sudo make install
Создайте systemd-юнит для управления сервисом:
sudo tee /etc/systemd/system/nginx.service <<EOF
[Unit]
Description=Nginx with RTMP module
After=network.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s quit
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now nginx
Проверьте статус: sudo systemctl status nginx. Сервер готов к настройке.
Базовая конфигурация: прием и раздача RTMP-потока
Конфигурация RTMP задается в отдельном блоке rtmp {} внутри nginx.conf. Этот блок работает параллельно с http {} и не пересекается с ним на уровне логики.
Создание RTMP-приложения
Откройте /etc/nginx/nginx.conf и добавьте блок RTMP перед блоком HTTP:
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
}
}
}
Директива listen 1935 указывает стандартный порт для RTMP-трафика. chunk_size 4096 задает размер фрагмента данных в байтах - значение 4096 оптимально для большинства сетей. Внутри application live параметр live on включает режим прямой трансляции, а record off отключает запись на диск.
URL для публикации формируется как rtmp://ваш_сервер/live/streamkey, где live - имя приложения, streamkey - произвольный ключ трансляции. Этот же URL используется зрителями для воспроизведения.
После изменения конфига проверьте синтаксис и перезагрузите Nginx:
sudo nginx -t
sudo systemctl reload nginx
Тестирование с OBS и VLC
Откройте OBS Studio, перейдите в «Настройки» → «Вещание». Выберите службу «Custom», в поле «Сервер» укажите rtmp://192.168.1.100/live, в поле «Ключ потока» - test. Нажмите «Начать вещание».
Для проверки откройте VLC Media Player: «Медиа» → «Открыть URL» → rtmp://192.168.1.100/live/test. Если поток отображается, сервер настроен верно.
Типичные ошибки на этом этапе: порт 1935 закрыт файрволом (проверьте sudo ufw status), неправильный IP-адрес сервера, опечатка в ключе потока. Убедитесь, что OBS использует программное кодирование x264 - аппаратные кодеры иногда выдают поток, несовместимый с модулем RTMP без транскодинга.
Конвертация RTMP в HLS и DASH для веб-плееров
RTMP не поддерживается современными браузерами. Чтобы зрители смотрели трансляцию без Flash, нужно на лету конвертировать поток в HLS (HTTP Live Streaming) или DASH (Dynamic Adaptive Streaming over HTTP). Модуль RTMP делает это автоматически при поступлении входящего потока.
Настройка HLS
Добавьте в application live директивы HLS:
application live {
live on;
record off;
hls on;
hls_path /var/www/hls;
hls_fragment 3s;
hls_playlist_length 30s;
}
hls on включает генерацию HLS-сегментов. hls_path задает директорию для файлов - создайте ее и назначьте права:
sudo mkdir -p /var/www/hls
sudo chown -R www-data:www-data /var/www/hls
hls_fragment 3s определяет длительность одного TS-сегмента. Значение 3 секунды - компромисс между задержкой и стабильностью. hls_playlist_length 30s задает длину плейлиста: 30 секунд означают, что в .m3u8 хранится 10 последних сегментов.
Для раздачи HLS через HTTP добавьте location в блок http {}:
http {
server {
listen 80;
location /hls {
alias /var/www/hls;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
}
}
}
Теперь HLS-поток доступен по адресу http://ваш_сервер/hls/test.m3u8. Для встраивания в веб-страницу используйте HTML5-плеер:
<video controls>
<source src="http://192.168.1.100/hls/test.m3u8" type="application/vnd.apple.mpegurl">
</video>
Настройка DASH
DASH добавляется аналогично. Расширьте application:
application live {
live on;
record off;
hls on;
hls_path /var/www/hls;
hls_fragment 3s;
hls_playlist_length 30s;
dash on;
dash_path /var/www/dash;
dash_fragment 3s;
}
Создайте директорию и настройте права:
sudo mkdir -p /var/www/dash
sudo chown -R www-data:www-data /var/www/dash
В HTTP-блоке добавьте location для DASH:
location /dash {
alias /var/www/dash;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
types {
application/dash+xml mpd;
video/mp4 m4v;
}
}
DASH-манифест доступен по http://ваш_сервер/dash/test.mpd. Обратите внимание: DASH требует инициализационный сегмент, который модуль генерирует автоматически. CORS-заголовок Access-Control-Allow-Origin обязателен для кросс-доменных запросов от плееров.
Ограничение доступа к стримам
Открытый RTMP-сервер позволяет любому, кто знает URL, начать вещание или смотреть чужой поток. Базовые механизмы защиты встроены в модуль и не требуют внешних сервисов.
Защита публикации по IP и ключу
Ограничьте круг IP-адресов, которым разрешена публикация:
application live {
live on;
record off;
allow publish 192.168.1.0/24;
allow publish 10.0.0.100;
deny publish all;
}
allow publish разрешает публикацию с указанных адресов или подсетей, deny publish all блокирует все остальные. Аналогично работает allow play / deny play для зрителей.
Дополнительный уровень - уникальный ключ потока. Используйте сложные, непредсказуемые значения: rtmp://server/live/a7f3b9c2e1d4_studio1. Без знания ключа публикация невозможна.
Аутентификация через внешний скрипт
Директива on_publish отправляет HTTP-запрос к вашему бэкенду при каждой попытке начать вещание. Бэкенд возвращает HTTP 200 для разрешения или 403 для запрета:
application live {
live on;
record off;
on_publish http://127.0.0.1:5000/auth;
}
Модуль передает параметры в URL: ?call=publish&name=test&addr=192.168.1.50. Простейший обработчик на Python/Flask:
from flask import Flask, request
app = Flask(__name__)
@app.route('/auth')
def auth():
key = request.args.get('name')
if key == 'valid_key':
return '', 200
return '', 403
Этот механизм интегрируется с любой системой авторизации: проверяйте ключи в базе данных, валидируйте JWT-токены, логируйте попытки подключения.
Мониторинг активных стримов
Модуль RTMP предоставляет встроенную страницу статистики в формате XML. Она показывает активные публикации, количество зрителей, битрейт и время работы каждого потока.
Включение и настройка stat-страницы
Добавьте в HTTP-блок location с директивой rtmp_stat:
http {
server {
listen 80;
location /stat {
rtmp_stat all;
allow 192.168.1.0/24;
deny all;
}
}
}
Откройте http://ваш_сервер/stat в браузере. Вы увидите XML с секциями <server>, <application>, <live>, <stream> и <client>. Для каждого потока указаны: имя, время запуска, входящий битрейт, количество подключенных зрителей.
Для быстрой проверки из командной строки используйте curl:
curl -s http://127.0.0.1/stat | grep -oP '(?<=name=")([^"]+)' | head -5
Интеграция с внешними системами мониторинга
XML-статистику легко парсить скриптами для передачи в Prometheus или Zabbix. Пример парсера на Python, который отдает метрики в формате Prometheus:
import xml.etree.ElementTree as ET
import requests
resp = requests.get('http://127.0.0.1/stat')
root = ET.fromstring(resp.text)
for stream in root.iter('stream'):
name = stream.find('name').text
bw_in = stream.find('bw_in').text
print(f'rtmp_bw_in{{stream="{name}"}} {bw_in}')
На основе этих данных настройте алерты: отсутствие ожидаемого потока более 60 секунд, падение входящего битрейта ниже порога, аномальный рост числа зрителей. Подробнее о настройке мониторинга Nginx читайте в руководстве по мониторингу с Prometheus и Grafana.
Продвинутые возможности: запись, ретрансляция и exec
Модуль RTMP не ограничивается приемом и раздачей. Три функции закрывают большинство потребностей продакшн-среды: автоматическая запись эфиров, ретрансляция на другие серверы и запуск внешних скриптов по событиям.
Запись прямых эфиров
Включите запись всех входящих потоков:
application live {
live on;
record all;
record_path /var/recordings;
record_unique on;
}
record all сохраняет каждый поток. record_path задает директорию. record_unique on добавляет временную метку к имени файла, предотвращая перезапись. Файлы сохраняются в формате FLV. Для ротации старых записей добавьте cron-задачу: find /var/recordings -name "*.flv" -mtime +7 -delete удаляет файлы старше 7 дней.
Ретрансляция на другие серверы
Директива push отправляет копию потока на удаленный RTMP-сервер. Это основа распределенной доставки:
application live {
live on;
push rtmp://cdn-server.example.com/live;
}
Для приема потока с другого сервера используйте pull:
application relay {
live on;
pull rtmp://origin-server.example.com/live key=streamkey;
}
В связке push/pull строится иерархия: origin-сервер принимает поток от энкодера, edge-серверы забирают его через pull и раздают зрителям. Это снижает нагрузку на origin и уменьшает задержку для географически распределенной аудитории.
Типичные проблемы и их решение
При настройке RTMP-сервера администраторы сталкиваются с повторяющимся набором ошибок. Разберем их с готовыми решениями.
Проблемы с сетью и файрволом
Порт 1935 не отвечает. Самая частая причина - файрвол. Проверьте правила:
sudo ufw allow 1935/tcp
sudo ufw reload
Для iptables: sudo iptables -A INPUT -p tcp --dport 1935 -j ACCEPT. Если сервер за NAT, настройте проброс порта на маршрутизаторе.
Ошибка 403 при публикации. Проверьте директивы allow publish / deny publish. Убедитесь, что IP энкодера попадает в разрешенную подсеть. Если используется on_publish, проверьте доступность бэкенда: curl http://127.0.0.1:5000/auth?call=publish&name=test должен вернуть 200.
HLS не проигрывается в браузере. Проверьте права на директорию hls_path: владелец должен быть www-data. Убедитесь, что MIME-типы .m3u8 и .ts прописаны в location. Проверьте CORS-заголовки - без Access-Control-Allow-Origin плеер на другом домене не загрузит поток.
Ошибки конфигурации и кодирования
Синтаксические ошибки в nginx.conf. Перед перезагрузкой всегда выполняйте sudo nginx -t. Вывод укажет строку с ошибкой.
Высокая задержка HLS. Уменьшите hls_fragment до 2 секунд и hls_playlist_length до 10 секунд. Учтите, что слишком короткие фрагменты увеличивают накладные расходы на HTTP-запросы.
Поток не стартует в плеере. Модуль RTMP требует ключевые кадры (I-frames) не реже чем раз в 2 секунды. В OBS настройте «Интервал ключевых кадров» на 2 секунды. Без этого HLS-плейлист не сформируется корректно.
Для углубленного анализа логов и отладки ошибок рекомендуем практическое руководство по анализу логов Nginx.
Заключение: итоговый конфиг и дальнейшие шаги
Ниже приведен полный nginx.conf, объединяющий все рассмотренные функции: прием RTMP, генерацию HLS и DASH, ограничение доступа, мониторинг и запись. Скопируйте его, замените IP-адреса на свои и запускайте в продакшн.
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record all;
record_path /var/recordings;
record_unique on;
allow publish 192.168.1.0/24;
deny publish all;
hls on;
hls_path /var/www/hls;
hls_fragment 3s;
hls_playlist_length 30s;
dash on;
dash_path /var/www/dash;
dash_fragment 3s;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 80;
server_name _;
location /hls {
alias /var/www/hls;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
}
location /dash {
alias /var/www/dash;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
types {
application/dash+xml mpd;
video/mp4 m4v;
}
}
location /stat {
rtmp_stat all;
allow 192.168.1.0/24;
deny all;
}
}
}
Куда двигаться дальше. Добавьте транскодинг через FFmpeg: модуль RTMP передает поток на вход FFmpeg, тот перекодирует его в несколько битрейтов и возвращает обратно в другое приложение. Это даст адаптивный битрейт для HLS и DASH. Настройте CDN на основе edge-серверов с pull-ретрансляцией для масштабирования на тысячи зрителей. Интегрируйте on_publish с корпоративной SSO-системой для сквозной аутентификации стримеров.
Для защиты сервера от сетевых атак на уровне HTTP изучите руководство по защите Nginx от DDoS. Если вы используете Nginx как балансировщик нагрузки для веб-приложений, пригодится практическое руководство по reverse proxy и балансировке.