web-dev-qa-db-ja.com

NGINX-RTMPでRTMPSストリームを受信する

RTMPの標準的な方法は、プレーンテキストストリームをキーにキーアウトすることです。

エンコーダからNGINXへのRTMPSストリームを受け入れたいのですが、RTMPモジュールにはまだRTMPSがありません。

RTMPストリームを取得し、RTMPSを介してFacebookのような場所に送信できるようにするすべてのリレーソリューションに興味があるわけではありません。ある時点で、プレーンテキストでキーを渡すため、同じセキュリティ上の欠陥が依然として存在するためです。

RTMPSの参照仕様はどこにありますか? OBSとNGINXなどのRTMPSソース間で適切なハンドシェイクを行うために必要なキーを知りたいので、RTMPモジュールとの接続を使用します。 RTMPSエンコーダーでハンドシェイクできるように、通常のキーとLet's Encryptなどの権限をサーバーで使用できますか?

RTMPをTLSでラップするために使用されるstunnelを見てきました。逆を行うことは可能ですか?stunnelを使用してRTMPSを受信し、RTMPモジュールのRTMPに変換しますか?

3
johnsonjp34

更新:これは、NginxでRTMPSを実装するときに直面する可能性がある問題をかなりうまく説明する私の元の回答です。ただし、改良版を追加してアクセス制御をさらに微調整し、そこからの構成を使用することをお勧めします代わりに。


はい、RTMPSは標準のTLSセッション内にラップされた単なるRTMPセッションであるため、これはstunnelで可能です。インターネット上の例は主にRTMP→RTMPSです。つまり、stunnelはプレーンテキストサーバーおよびclient = yesで構成されたTLSクライアントとして機能しています。それがなければ、 client はデフォルトでnoになり、これはサーバーモードです。

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はローカルループバック、ポート1936/tcpでRTMPをリッスンする必要があります。
  • RTMPを使用してLet's Encrypt証明書を更新できないため、HTTP-01チャレンジ用のHTTPサーバーブロックも必要になる場合があります。
  • Nginxへの接続は常にstunnelから、つまり127.0.0.1から行われるため、allow/denyディレクティブを使用してIPアドレスに基づいて接続を制限することはできなくなりました。つまり、アクセス制御はキーのみに制限されますが、暗号化されて送信されるため、問題が少なくなります。

    ただし、それを使用しているクライアントと同じIPからストリームをプッシュするため、これでも問題が発生しますが、ストリームへの公開を許可することはできません。幸い、キーを使用してアプリケーションからのストリームを Push する必要はありませんが、 pull 公開アプリケーション(/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;
        }
    }
}

ただし、これは単なる例であるため、ニーズに合わせて変更することができます。 (また、私はこの構成をテストしていませんが、ドキュメントにのみ基づいて記述しているため、何か問題が発生した場合は、自由に修正してください。)

3
Esa Jokinen

NGINXはアップストリームTCPサーバーのTLSを終了できるため、これはNGINXのみを使用して処理する必要があります(@Esa Jokinenの構成に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;
        }
    }
}
6

Nginx RTMPS +秘密公開鍵+ IPアドレスベースのアクセス制御

これを別の回答として投稿することにしました。これは 私の最初の回答 が適切な説明回答であり、クレジットも付与したかったためです Danila Vershinin Nginxのstream{}を使用して指摘するため。ただし、これらの両方の回答は、キーを含むコンテンツを暗号化することでセキュリティを向上させますが、 アクセス制御 の機能も削除します[play|publish] address|subnet|allモジュールのallow/denyrtmp{}を使用します。

stream{} ieプロキシされたTCPには独自の アクセス制御 がありますが、(rtmp{}とは異なり)公開と再生を区別できません:単一のstream{}プロキシを使用すると、誰もが公開と再生の両方を行うことができます。またはどちらも実行できません。したがって、キーとIP制限の両方を使用したアクセス制御には、公開とストリーミングの両方に個別のプロキシを使用する構造が必要です。別個のTCPプロキシ用のポート次の図は、この設計を示しています。

enter image description here

ここでは、RTMPS-playに標準ポート1935/tcpを使用し、RTMPS-publishに追加の1936/tcpを使用しています。暗号化されていない内部RTMP接続では、同様のポート19351および19361を使用します。赤色は暗号化されていない接続と信頼できないネットワークを表し、緑色は暗号化された接続と信頼できるネットワークを表します。

プロキシ化されたTCPには2つの( [〜#〜] rtmps [〜#〜] )構成がありますが、どちらも同じ証明書を使用できます:

stream {
    upstream publish {
        server 127.0.0.1:19361;
    }
    server {
        listen 1936 ssl;        # additional port for publishing
        proxy_pass backend;
        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)
    }
}

同様に、アプリケーションごとに2つの個別の(ローカルループバック) [〜#〜] 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ベースのアクセス制御はstream{}セクションで行われるため、deny publish all;アプリケーションを使用した直接公開を防止するには、/liveのみが必須です。 RTMPアクセス制御のデフォルトの動作を明確にする(そしてコメントする)ために、allowディレクティブをrtmp{}セクションに追加しました。

0
Esa Jokinen