LoginSignup
7
1

More than 3 years have passed since last update.

CloudFront Signed Cookie でストリーミング URL を保護

Last updated at Posted at 2020-05-22

もうコロナ収束しても出社する気がない streampack 木村です。

こういったご時世を反映してか、ライブ配信案件がかなり増加してきています。

HTTP ベースのストリーミングは基本、来るものは拒まずなので、何かで制限をかけてあげないといけないのですが、お手軽案として、CloudFront を利用した Signed Cookie (署名付き cookie) の簡単な例をご紹介します。

構成

使用するリソースは以下です。

  • MediaLive
  • MediaStore
  • S3
  • CloudFront

前提

  • MediaLive、MediaStore、S3、CloudFront については既に構築済みでストリーミングができる状態にあるところから開始します。
  • CloudFront には独自ドメインを設定しています。(タダで取得した streampack.ga

手順

それではさっそくまいりましょう。

CloudFront キーペアの作成

まずは CF のキーペアを作成します。 ローカルで作る方法もありますが、AWS コンソールから発行することもできます。(要 root アカウント)

【作成方法】
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html

出来上がった プライベートキーアクセスキーID は大切に保存しておきましょう。

カスタムポリシーステートメントの用意

署名付き cookie で利用するポリシーを JSON ファイルとして作成します。

設定するパラメータは必要最低限として、これを policy.json として保存します。

{"Statement":[{"Resource":"http*://*.streampack.ga/*","Condition":{"DateLessThan":{"AWS:EpochTime":1621555191}}}]}
Items Values
Resource 対象となるホスト、パスを指定(ワイルドカード可)
AWS:EpochTime 有効期限を UNIXTIME で指定

1. ポリシーステートメントを base64 エンコード

下記コマンドを実行して結果をメモしておきましょう。

$ cat ./policy.json | openssl base64 | tr '+=/' '-_~'

2. ポリシーステートメントを署名して base64 エンコード

下記コマンドを実行して結果をメモしておきましょう。

$ cat ./policy.json | openssl sha1 -sign ./[privatekey].pem | openssl base64 | tr '+=/' '-_~'

3. cookie をセットする

上記を結果を用いてセットする cookie を作成します。
Player が CF にアクセスするときに下記 cookie を渡すことにより、認証をパスすることができます。

cookie value
CloudFront-Key-Pair-Id アクセスキーID
CloudFront-Policy 上記1の結果
CloudFront-Signature 上記2の結果

CloudFront 設定

Origins 設定

今回、マルチオリジンを利用して、Player と HLS 取得先をそれぞれ設定します。

スクリーンショット 2020-05-22 17.05.25.png

Behaviors 設定

HTML5 Player を S3 から (Default)
HLS は MediaStore から (ts と m3u8) 取得するように設定します。

スクリーンショット 2020-05-22 17.09.08.png

Restrict Viewer Access 設定

Behaviors の ts と m3u8 設定で Restrict Viewer Access を有効にします。
Default はそのまま無効とします。 これは HTML を読み込ませて cookie を取得される為です。

スクリーンショット 2020-05-22 17.12.43.png

Player の用意

今回 HTML で javascript を使用して cookie をセットし、同時に HTML5 Player も埋め込んでしまいます。

Player 例:

<!DOCTYPE html>
<html>
<head>
  <title>Clappr Player</title>
  <meta charset="UTF-8">
  <!-- Player -->
  <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/clappr/0.2.86/clappr.min.js"></script>
</head>
<body>
  <div id="player"></div>
  <script>
    document.cookie = "CloudFront-Key-Pair-Id=XXXXXXXXXXXXXXXXXXXX; path=/";
    document.cookie = "CloudFront-Policy=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; path=/";
    document.cookie = "CloudFront-Signature=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; path=/";
    var player = new Clappr.Player({
      source: "https://xxx.streampack.ga/xxx/index.m3u8",
      parentId: "#player"
    });
  </script>
</body>

document.cookie に上記で作成した cookie を指定し、ついでに path=/ も付与することで、サイト全体がこの cookie の対象となります。

source には CloudFront 経由の MediaStore の HLS URL を指定します。

視聴

S3 にアップした HTML ファイルに CF 経由でアクセスします。
Behaviors Default には制限をかけていないので、HTML ファイルまでは誰でもアクセスできます。

ブラウザがこの HTML を読み込む際に、cookie を取得して、続く m3u8 と ts のリクエストの際に、この cookie を付与することにより、CF の署名付き cookie が認証されて視聴が可能となります。

スクリーンショット 2020-05-22 17.33.21.png

ちなみに同じ HTML から document.cookie 部分を削除すると CF に怒られて視聴不可になります。

スクリーンショット 2020-05-22 17.44.08.png

当たり前だけど URL 直打ちも拒否ります!

kimura7:~ kimura$ curl https://xxx.streampack.ga/xxx/index.m3u8
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>D601B63B9BB1393C</RequestId><HostId>qV0Y6iA+8rZx0Q8TM/pn+r22UyykEKnsdyPUHmkFjRd4v8Y/7BHH3gM6prUe6v8d/zxHjSNjXz0=</HostId></Error>

まとめ

今回は超絶、全部手作業ですが、最小構成の場合は結構簡単に設定することができます。

これで ffmpeg -i -movflags faststart.... な人はサヨウナラです。

参考

cookie 生成にあたり、@suhirotakaさんが作成された下記の投稿が大変参考になりました。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1