Получение потока RTMPS на NGINX-RTMP

Стандартной практикой для RTMP по-прежнему является наличие ключа потока обычного текста по проводам.

Я хочу принимать потоки RTMPS от кодировщиков к NGINX, однако модуль RTMP еще не имеет RTMPS .

Меня не интересуют все решения для ретрансляции, позволяющие принимать поток RTMP и отправлять его в такое место, как facebook через RTMPS, потому что та же проблема безопасности все еще существует, потому что в какой-то момент вы передаете ключи по обычному тексту.

У меня вопрос: где мне найти справочные спецификации RTMPS? Я хотел бы знать, какие ключи необходимы для правильного рукопожатия между источником RTMPS, таким как OBS и NGINX, а затем я буду использовать соединение с модулем RTMP. Можно ли использовать на сервере обычные ключи и такой авторитет, как Let's Encrypt, чтобы он мог установить связь с кодировщиком RTMPS?

Я видел stunnel, используемый для обертывания RTMP в TLS. Можно ли сделать обратное - использовать stunnel для получения RTMPS и обратного преобразования в RTMP для модуля RTMP?

4
задан 30 May 2020 в 14:47
4 ответа

ОБНОВЛЕНИЕ: Это мой исходный ответ, который довольно хорошо описывает проблемы, с которыми можно столкнуться при реализации 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

Здесь:

  • Nginx должен прослушивать RTMP на локальном шлейфе , порт 1936 / tcp .
  • Поскольку вы не можете обновить сертификат Let's Encrypt с помощью RTMP, вам также может потребоваться блок HTTP-сервера для запроса HTTP-01.
  • Поскольку соединение с 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;
        }
    }
}

Однако это всего лишь пример, поэтому вы можете и должны изменить его в соответствии с вашими конкретными потребностями. (Кроме того, я не тестировал эту конфигурацию, но написал ее исключительно на основе документации, поэтому, пожалуйста, не стесняйтесь исправлять, если у меня что-то не так.)

5
ответ дан 4 January 2021 в 07:30

Поскольку 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;
        }
    }
}
7
ответ дан 4 January 2021 в 07:30

Nginx RTMPS + секретный ключ публикации + управление доступом на основе IP-адреса

Я решил опубликовать это как еще один ответ, так как мой Первый ответ по-прежнему является хорошим объяснительным ответом, и я также хотел бы поблагодарить Данила Вершинин за указание на использование потока Nginx {} . Однако, хотя оба эти ответа повышают безопасность за счет шифрования содержимого, включая ключ, они также исключают возможность из управления доступом с использованием allow / deny [play | publish] address | subnet | all из rtmp {} [ Модуль 1177466].

Поток {} т.е. прокси TCP имеет собственный контроль доступа , но (в отличие от rtmp {} ) он не может отличить публикацию от воспроизведения: с одним прокси-сервером stream {} каждый может как публиковать, так и воспроизводить - или не может делать ни одного из них. Следовательно,управление доступом с использованием как ключей , так и ограничений IP требует структуры с отдельными прокси-серверами как для публикации, так и для потоковой передачи: отдельный порт TCP для проксирования публикации с помощью ключа. Следующая диаграмма демонстрирует эту схему:

enter image description here

Здесь я использую стандартный порт 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.

3
ответ дан 4 January 2021 в 07:30

Не уверен, действительно ли это здесь, но я используется как простое завершение 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 , в данный момент не нужны игры или что-то еще.

0
ответ дан 4 January 2021 в 07:30

Теги

Похожие вопросы