S3 から HLS ストリームを安全に配信する方法 (承認済みおよび認証済み) 質問する

S3 から HLS ストリームを安全に配信する方法 (承認済みおよび認証済み) 質問する

問題:

私は保管していますHLS流れ込むS3指定されたファイル構造の場合:

Video1
  ├──hls3
      ├──hlsv3-master.m3u8
      ├──media-1
      ├──media-2
      ├──media-3
      ├──media-4
      ├──media-5
  ├──hls4
      ├──hlsv4-master.m3u8
      ├──media-1
      ├──media-2
      ├──media-3
      ├──media-4
      ├──media-5

私のユーザーAPIどのユーザーがどのビデオ コンテンツにアクセスできるかを正確に把握していますが、ビデオ リンクは共有不可であり、適切な権限を持つユーザーのみがアクセス可能であることも確認する必要があります。

解決策:

1) 署名付き/一時ファイルを使用するS3プライベート用のURLS3コンテンツ。クライアントが特定のビデオを再生したいときはいつでも、リクエストが送信されます。APIユーザーが適切な権限を持っている場合、API署名された URL を生成し、それをクライアントに返してプレーヤーに渡します。

ここで問題になるのは、実際のビデオコンテンツが数十のセグメントファイルに保存されていることです。メディア-*ディレクトリがあり、それらすべてを保護する方法がわかりません。各セグメント ファイルの URL を個別に署名する必要があるのでしょうか?

2)S3コンテンツは非公開です。プレイヤーからのビデオストリームリクエストは私のAPIまたは別々リバースプロキシ. クライアントが特定のビデオを再生することを決定するたびに、API/リバースプロキシリクエストを取得し、認証と承認を行い、適切なコンテンツ (マスター プレイ リスト ファイルとセグメント) を渡します。

この場合、私はまだS3コンテンツは非公開で、私のAPI/リバースプロキシここで推奨される方法は何でしょうか?トークンによる S3 REST 認証?

3) 保護されたキーで暗号化する。この場合、すべてのビデオセグメントは暗号化され、公開されます。キーはS3公開されていません。プレイヤーによるすべてのキーリクエストは、私のAPI/リバースプロキシ

これらは私が今考えている 3 つの解決策です。すべてに納得しているわけではありません。シンプルで、絶対に安全なものを探しています。何か推奨事項や提案はありますか?

使用される技術:

  • ffmpeg異なるビットレートへのビデオエンコード用

  • 弁当4ビデオセグメンテーション用

ベストアンサー1

各セグメント ファイルの URL を個別に署名する必要がありますか?

プレイヤーが S3 から直接リクエストしている場合は、その通りです。したがって、これはおそらく理想的なアプローチではないでしょう。

1つの選択肢は、バケットの前にCloudFrontを置くことです。CloudFrontはオリジンアクセスアイデンティティを使用して設定することができ、これによりリクエストに署名してS3に送信し、承認されたユーザーに代わってプライベートS3オブジェクトを取得できます。また、CloudFrontは署名付きURL(S3とは異なるアルゴリズムを使用、2つの重要な違いについては後述)と署名付きURLの両方をサポートしています。署名付きクッキーCloudFront の署名付きリクエストと Cookie は互いに非常によく似た動作をしますが、重要な違いは、Cookie を一度設定すると、その後の各リクエストでブラウザによって自動的に使用されるため、個々の URL に署名する必要がなくなることです。(なるほど。)

CloudFront の署名付き URL と署名付き Cookie の両方で、カスタム ポリシーを使用すると、S3 では簡単に実行できない 2 つの追加機能が利用できるようになります。

  • CloudFront署名に関連付けられたポリシーにより、パス内のワイルドカード、つまり、/media/Video1/*署名の有効期限が切れるまで、任意のファイルへのアクセスを許可することができます。S3 署名付き URL は、いかなる形式のワイルドカードもサポートしていません。S3 URL は、単一のオブジェクトに対してのみ有効です。

  • CloudFront ディストリビューションが IPv4 のみに設定されている限り、署名を特定のクライアント IP アドレスに結び付けて、その署名を使用したアクセスを単一の IP アドレスからのみ許可することができます (CloudFront はオプション機能として IPv6 をサポートするようになりましたが、現在このオプションと互換性はありません)。これは少し強引で、モバイル ユーザー ベースではおそらく望ましくありません。モバイル ユーザー ベースでは、プロバイダー ネットワークから Wi-Fi に切り替えたり戻ったりするときにソース アドレスが切り替わります。

署名付き URL は、すべてのコンテンツ リンクに対して生成する必要がありますが、URL を 1 回だけ生成して署名し、署名を再利用することができます。各ファイルの URL を文字列で書き換えるだけで、このオプションの計算コストは​​低くなりますが、それでも面倒です。一方、署名付き Cookie は、一致するオブジェクトに対して「そのまま機能」するはずです。

もちろん、CloudFront を追加すると、リクエストが S3 に直接送信される通常のリクエストよりもブラウザに近いマネージド AWS ネットワークにホップするため、キャッシュとインターネット パスの短縮によってパフォーマンスも向上します。CloudFront を使用すると、ブラウザからのリクエストは、リクエストを発行したブラウザに最も近いと想定される 60 を超えるグローバル「エッジ ロケーション」のいずれかに送信されます。もちろん、署名または Cookie が有効である限り、CloudFront は、異なる URL または Cookie を使用して、同じキャッシュ オブジェクトを異なるユーザーに提供できます。

CloudFront 署名付き Cookie を使用するには、少なくともアプリケーションの一部 (Cookie を設定する部分) が、バケットを指す同じ CloudFront ディストリビューションの「背後」にある必要があります。これは、アプリケーションをディストリビューションの追加オリジンとして宣言し、特定のパス パターンのキャッシュ動作を作成することで実現します。このキャッシュ動作は、リクエストされると CloudFront によってアプリケーションに転送され、アプリケーションは適切なSet-Cookie:ヘッダーで応答できます。

私は AWS と提携していないので、以下を「売り込み」と誤解しないでください。次の質問を予測しているだけです。CloudFront + S3 は、S3 のみを使用する場合と比較してコストの差が通常は無視できるほどの価格設定になっています。オブジェクトが CloudFront 経由で要求された場合、S3 は帯域幅に対して課金しません。また、CloudFront の帯域幅料金は、S3 を直接使用する場合の料金よりもわずかに低い場合があります。これは直感に反しているように思えますが、AWS が、すべての要求を単一の S3 リージョンに集中させるのではなく、ネットワーク全体に要求を分散させるように価格設定を構成するのは理にかなっています。


認証情報はブラウザで、そしてユーザーの専門知識に応じてユーザーに必ず提供されるため、上記のメカニズムも下記のメカニズムも、不正な「共有」から完全に免れることはできないことに注意してください。しかし、どちらのアプローチも、正直なユーザーを正直に保つには十分すぎるほどであり、それが望みのすべてです。署名付き URL と Cookie の署名には有効期限があるため、共有可能な期間は限られており、CloudFront ログ分析を通じてそのようなパターンを識別し、それに応じて対応できます。どのアプローチを採用する場合でも、ログを常に把握しておくことの重要性を忘れないでください。


リバース プロキシも良いアイデアで、おそらく簡単に実装でき、プロキシを実行している EC2 マシンがバケットと同じ AWS リージョンにあり、プロキシが Nginx や HAProxy のような堅牢で効率的なコードに基づいている場合は、追加のデータ転送料金やスループットの問題もなく、十分にパフォーマンスを発揮するはずです。

この環境では、固定 IP アドレスがあるため、リバース プロキシがプライベート オブジェクトにアクセスできるようにバケットを構成できるため、何も署名する必要はありません。

バケットポリシーでは、「匿名」ユーザーにs3:getObject権限を付与することでこれを実現します。場合にのみソース IPv4 アドレスがプロキシの 1 つの IP アドレスと一致します。プロキシは、承認されたユーザーに代わって S3 から匿名でオブジェクトを要求します (署名は不要)。これには、S3 VPC エンドポイントを使用するのではなく、プロキシに Elastic IP アドレスを与えるか、プロキシを NAT ゲートウェイまたは NAT インスタンスの背後に配置して、S3 が NAT デバイスのソース IP を信頼するようにする必要があります。するS3 VPC エンドポイントを使用する場合、リクエストが S3 VPC エンドポイントを通過したという理由だけで S3 がリクエストを信頼できるようにすることが可能ですが、これはテストしていません。(S3 VPC エンドポイントはオプションです。明示的に設定していない場合は、S3 VPC エンドポイントが存在せず、おそらく必要ありません)。


私の理解が正しければ、3 番目のオプションは最も弱いようです。権限はあるが悪意のあるユーザーがキーを取得し、それを 1 日中共有することができます。

おすすめ記事