Стандартной практикой для RTMP по-прежнему является наличие ключа потока обычного текста по проводам.
Я хочу принимать потоки RTMPS от кодировщиков к NGINX, однако модуль RTMP еще не имеет RTMPS .
Меня не интересуют все решения для ретрансляции, позволяющие принимать поток RTMP и отправлять его в такое место, как facebook через RTMPS, потому что та же проблема безопасности все еще существует, потому что в какой-то момент вы передаете ключи по обычному тексту.
У меня вопрос: где мне найти справочные спецификации RTMPS? Я хотел бы знать, какие ключи необходимы для правильного рукопожатия между источником RTMPS, таким как OBS и NGINX, а затем я буду использовать соединение с модулем RTMP. Можно ли использовать на сервере обычные ключи и такой авторитет, как Let's Encrypt, чтобы он мог установить связь с кодировщиком RTMPS?
Я видел stunnel, используемый для обертывания RTMP в TLS. Можно ли сделать обратное - использовать stunnel для получения RTMPS и обратного преобразования в RTMP для модуля RTMP?
ОБНОВЛЕНИЕ: Это мой исходный ответ, который довольно хорошо описывает проблемы, с которыми можно столкнуться при реализации RTMPS с Nginx. Однако я добавил улучшенную версию для более точной настройки контроля доступа и рекомендую вместо этого использовать конфигурацию из нее.
Да, это возможно с stunnel, поскольку RTMPS - это просто Сеанс RTMP заключен в стандартный сеанс TLS. Примеры в Интернете - это в основном RTMP → RTMPS, то есть stunnel работает как текстовый сервер и TLS-клиент, который настроен с client = yes
. Без этого клиент
по умолчанию использует нет
, что является режимом сервера .
Конфигурация stunnel может выглядеть так:
[rtmps]
accept = 1935
connect = 127.0.0.1:1936
cert=/etc/letsencrypt/live/rtmp.example.com/fullchain.pem
key=/etc/letsencrypt/live/rtmp.example.com/privkey.pem
Здесь:
1936 / tcp
. Поскольку соединение с Nginx всегда происходит из stunnel, то есть из 127.0.0.1
, вы не можете использовать директивы allow
/ deny
для ограничения подключение на основе IP-адресов больше. Это означает, что ваш контроль доступа будет ограничен одним ключом, но в то же время это меньшая проблема, поскольку он передается в зашифрованном виде.
Тем не менее, это все еще вызывает проблемы, поскольку вы отправляете поток из того же IP, чем клиенты, которые его используют, но вы не можете разрешить им публиковать в своем потоке. К счастью, вам не нужно отправлять
поток из приложения с помощью ключа, но вы также можете вытащить
его из общедоступного приложения ( / live
) .
Следующий пример конфигурации Nginx учитывает эти соображения:
rtmp {
server {
listen 127.0.0.1:1936;
chunk_size 4096;
application app-secret-stream-key {
live on;
record off;
allow publish 127.0.0.1; # for streaming through stunnel
allow play 127.0.0.1; # for the pull from /live
}
application live {
live on;
record off;
deny publish all; # no need to publish on /live
allow play all; # playing allowed
pull rtmp://127.0.0.1:1936/app-secret-stream-key;
}
}
}
http {
server {
listen 80;
server_name rtmp.example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 404;
}
}
}
Однако это всего лишь пример, поэтому вы можете и должны изменить его в соответствии с вашими конкретными потребностями. (Кроме того, я не тестировал эту конфигурацию, но написал ее исключительно на основе документации, поэтому, пожалуйста, не стесняйтесь исправлять, если у меня что-то не так.)
Поскольку NGINX может завершать TLS для восходящих TCP-серверов, это должно позаботиться об этом, используя только NGINX (просто добавлен раздел stream
для настройки из @ Эса Йокинен):
stream {
upstream backend {
server 127.0.0.1:1936;
}
server {
listen 1935 ssl;
proxy_pass backend;
ssl_certificate /etc/letsencrypt/live/rtmp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rtmp.example.com/privkey.pem;
}
}
rtmp {
server {
listen 127.0.0.1:1936;
chunk_size 4096;
application app-secret-stream-key {
live on;
record off;
allow publish 127.0.0.1; # for streaming through stunnel
allow play 127.0.0.1; # for the pull from /live
}
application live {
live on;
record off;
deny publish all; # no need to publish on /live
allow play all; # playing allowed
pull rtmp://127.0.0.1:1936/app-secret-stream-key;
}
}
}
http {
server {
listen 80;
server_name rtmp.example.com;
location ^~ /.well-known/acme-challenge/ {
root /var/www/letsencrypt;
}
location / {
return 404;
}
}
}
Я решил опубликовать это как еще один ответ, так как мой Первый ответ по-прежнему является хорошим объяснительным ответом, и я также хотел бы поблагодарить Данила Вершинин за указание на использование потока Nginx {}
. Однако, хотя оба эти ответа повышают безопасность за счет шифрования содержимого, включая ключ, они также исключают возможность из управления доступом с использованием allow
/ deny
[play | publish] address | subnet | all
из rtmp {} [ Модуль 1177466].
Поток {}
т.е. прокси TCP имеет собственный контроль доступа , но (в отличие от rtmp {}
) он не может отличить публикацию от воспроизведения: с одним прокси-сервером stream {}
каждый может как публиковать, так и воспроизводить - или не может делать ни одного из них. Следовательно,управление доступом с использованием как ключей , так и ограничений IP требует структуры с отдельными прокси-серверами как для публикации, так и для потоковой передачи: отдельный порт TCP для проксирования публикации с помощью ключа. Следующая диаграмма демонстрирует эту схему:
Здесь я использую стандартный порт 1935 / tcp
для RTMPS-play и дополнительный 1936 / tcp
для RTMPS-publish. Для внутренних незашифрованных соединений RTMP я использую аналогичные порты 19351
и 19361
. Красный цвет представляет незашифрованные соединения и ненадежные сети, тогда как зеленый цвет представляет зашифрованные соединения и доверенные сети.
Прокси-сервер TCP теперь имеет две ( RTMPS ) конфигурации, но обе могут использовать один и тот же сертификат:
stream {
upstream publish {
server 127.0.0.1:19361;
}
server {
listen 1936 ssl; # additional port for publishing
proxy_pass publish;
ssl_certificate /etc/letsencrypt/live/rtmp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rtmp.example.com/privkey.pem;
allow 192.0.2.1; # allow publish from this IP
allow 192.0.2.0/24; # -- also supports CIDR notation!
deny all; # deny publish from the rest
}
upstream live {
server 127.0.0.1:19351;
}
server {
listen 1935 ssl; # standard RTMP(S) port
proxy_pass live;
ssl_certificate /etc/letsencrypt/live/rtmp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rtmp.example.com/privkey.pem;
allow all; # this is public (this is also the default)
}
}
Аналогичным образом, теперь нам нужны два отдельных (локальных петлевых) сервера RTMP для каждого приложения:
rtmp {
server {
listen 127.0.0.1:19361;
chunk_size 4096;
application secret-key {
live on;
record off;
allow publish 127.0.0.1; # publishing through rtmps://rtmp.example.com:1936
allow play 127.0.0.1; # for the pull from rtmp://localhost:19351/live
}
}
server {
listen 127.0.0.1:19351;
chunk_size 4096;
application live {
live on;
record off;
deny publish all; # no need to publish on /live -- IMPORTANT!!!
allow play 127.0.0.1; # playing through rtmps://rtmp.example.com:1935/live
pull rtmp://127.0.0.1:19361/secret-key;
}
}
}
Фактическое управление доступом на основе IP осуществляется в разделе потока {}
, поэтому только запретить публикацию всех;
является обязательным для предотвращения прямой публикации с использованием приложения / live
. Я добавил директивы allow
в раздел rtmp {}
, чтобы прояснить (и прокомментировать) поведение по умолчанию для управления доступом RTMP.
Не уверен, действительно ли это здесь, но я используется как простое завершение SSL, как указано выше, с протоколом прокси для сохранения IP-адресов клиентов. Модуль RTMP поддерживает протокол прокси, поэтому вы все равно можете разрешить отказ по IP-адресу. Провел несколько базовых тестов, и он, похоже, работает нормально, исправлены сообщения в журнале и отказано по IP-адресу.
Возможно, я не понял, но похоже, что он делает то, что я думаю, он должен быть, то есть разрешает SSL-соединения через RTMPS и сохраняя IP-адреса клиентов для управления доступом в модуле RTMP.
Мой блок потока выглядит так:
stream {
upstream backend {
server 127.0.0.1:1935;
}
server {
listen 1936 ssl;
proxy_pass backend;
proxy_protocol on;
ssl_certificate /etc/..../fullchain.pem;
ssl_certificate_key /etc/.../privkey.pem;
}
}
И соответствующие биты моего раздела RTMP: (Примечание: прямые подключения, вероятно, не будут работать, но я не пробовал ... предлагает это в блоге (см. Ниже), но мне не нужны прямые подключения).
rtmp {
server {
listen 1935 proxy_protocol;
chunk_size 4000;
application stream_app{
live on;
.....
.....
.....
}
}
}
}
Вы можете прочитать об этом в блоге RTMP http : //nginx-rtmp.blogspot.com .
Надеюсь, это поможет кому-то, и спасибо за ответы, приведенные выше, поскольку они указали мне правильное направление.
К вашему сведению, я отрицаю все, поскольку я выталкиваю HLS , в данный момент не нужны игры или что-то еще.