もうコロナ収束しても出社する気がない streampack 木村です。
こういったご時世を反映してか、ライブ配信案件がかなり増加してきています。
HTTP ベースのストリーミングは基本、来るものは拒まず
なので、何かで制限をかけてあげないといけないのですが、お手軽案として、CloudFront を利用した Signed Cookie (署名付き cookie)
の簡単な例をご紹介します。
構成
使用するリソースは以下です。
- MediaLive
- MediaStore
- S3
- CloudFront
前提
- MediaLive、MediaStore、S3、CloudFront については既に構築済みでストリーミングができる状態にあるところから開始します。
- CloudFront には独自ドメインを設定しています。(タダで取得した
streampack.ga
)
手順
それではさっそくまいりましょう。
CloudFront キーペアの作成
まずは CF のキーペアを作成します。 ローカルで作る方法もありますが、AWS コンソールから発行することもできます。(要 root アカウント)
出来上がった プライベートキー
と アクセスキー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 取得先をそれぞれ設定します。
Behaviors 設定
HTML5 Player を S3 から (Default)
HLS は MediaStore から (ts と m3u8) 取得するように設定します。
Restrict Viewer Access 設定
Behaviors の ts と m3u8 設定で Restrict Viewer Access
を有効にします。
Default はそのまま無効とします。 これは HTML を読み込ませて cookie を取得される為です。
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 が認証されて視聴が可能となります。
ちなみに同じ HTML から document.cookie 部分を削除すると CF に怒られて視聴不可になります。
当たり前だけど 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さんが作成された下記の投稿が大変参考になりました。