CloudFrontでセキュア(許可された人のみ)な配信を実現するには、Lambda@Edgeを実装するか、署名付きURLか署名付きCookieを使う事になります。
Lambda@Edgeよりも署名付きの方が、処理をAWSに任せられるのでシンプルに実現できます。
署名付きURLは、URLにパラメータを入れる事になるので、リクエスト毎に入れられる場合に使える。ワイルドカード(*)で複数ファイルを対象にする事もできる。
一方、署名付きCookieは、URLにパラメータを入れるのが難しい場合(ストリーミング配信等)に使えます。Cookieなので期限や複数同時に対応できるようにPath指定もした方が良さそう。

パブリックキーを作成

https://us-east-1.console.aws.amazon.com/cloudfront/v3/home#/publickey/create

パブリックキーを作成
	パブリックキー
		名前: cloudfront_public_key
			※公開鍵のファイル名(拡張子なし)にしてみました。ドットは使えない
		キー: (作成した公開鍵の内容)※下記のコマンドで作成
	[パブリックキーを作成]
% openssl genrsa -out cloudfront_private_key.pem 2048
% openssl rsa -pubout -in cloudfront_private_key.pem -out cloudfront_public_key.pem
% cat cloudfront_public_key.pem

キーグループを作成

https://us-east-1.console.aws.amazon.com/cloudfront/v3/home#/keygrouplist/create

キーグループを作成
	キーグループ
		名前: cloudfront_public_key_group
			※パブリックキー名に「_group」を付けてみました
		パブリックキー: cloudfront_public_keyを選択
	[キーグループを作成]

ビヘイビアを作成

今回は構築済みのディストリビューションを使います。
CloudFront(S3オリジン)構築とawsコマンド(S3, CloudFront)メモ

また、今回は「/auth」ディレクトリ以下に制限を掛けるので、ビヘイビアを作りますが、
全体を対象にする場合はデフォルトのを編集するか、構築時に指定してください。

https://us-east-1.console.aws.amazon.com/cloudfront/v3/home#/distributions

対象のディストリビューション選択
ビヘイビア
	ビヘイビアを作成

ビヘイビアを作成
	設定
		パスパターン: /auth/*

〜ここからはデフォルトと同じのを選択 ※これ大事!〜
		オリジンとオリジングループ: デフォルトと同じのを選択
		ビューワー
			ビューワープロトコルポリシー: ●Redirect HTTP to HTTPS
			許可されたHTTPメソッド: ●GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
			HTTPメソッドをキャッシュ: ■オプション
〜ここまで〜

			ビューワーのアクセスを制限する: ●Yes
				信頼された認可タイプ: ●Trusted key groups (recommended)	※デフォルト
				キーグループを追加: 上記で作成したキーグループ名を選択

〜ここからはデフォルトと同じのを選択 ※これ大事!〜
		キャッシュキーとオリジンリクエスト
			キャッシュポリシー: CachingOptimized	※デフォルト
			レスポンスヘッダーポリシー: CORS-With-Preflight
〜ここまで〜

	[ビヘイビアを作成]

<省略(デフォルトと同じのを選択 ※これ大事!)>
6. プリフライトリクエストに応答できず一部ユーザーが表示できず

<省略(デフォルトと同じのを選択 ※これ大事!)>

動作確認

動画を変換して設置しましたが、S3にアップロードしても良い。
S3設置トリガーで自動変換と、MediaConvertでCMAFを暗号化(未解決)してみる

% curl -i https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8
HTTP/2 403 
content-type: text/html
content-length: 526
date: Thu, 19 May 2022 11:44:06 GMT
last-modified: Wed, 02 Sep 2020 11:29:13 GMT
etag: "0f2ee0533109062bc0ed22032229f69d"
accept-ranges: bytes
server: AmazonS3
vary: Origin
x-cache: Error from cloudfront
via: 1.1 2b20977f9e276750dc3347b53d99bae4.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P2
x-amz-cf-id: 1JeRYrGgD0sQZcN1Zn_CifM1bGN99rup4tIiMwerYfEkCpUDOOtWcg==
age: 47483

<html>
<head>
<meta name="robots" content="noindex" />
<title>Not Found</title>
</head>
<body>
Not Found<br/>
<!-- IE bug support dumy data
123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890 -->
</body>
</html>

エラーページで403を設定しているとそのページが返却される。
(S3に存在しなくても、署名がエラーでも403になる)
デバッグ時は解り難いので、一時的に外します。

MissingKeyが返却されるのでOK

% curl -i https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8
HTTP/2 403 
server: CloudFront
date: Fri, 20 May 2022 00:57:45 GMT
content-type: text/xml
content-length: 146
vary: Origin
x-cache: Error from cloudfront
via: 1.1 2005babf9e16815c80be6808c6f595b0.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C2
x-amz-cf-id: d8MdxP0kpFNxqQESzsYCSc8I0bXXQalB_L9MtU69e0zTr79FBLCcwg==

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>MissingKey</Code>
  <Message>Missing Key-Pair-Id query parameter or cookie value</Message>
</Error>

署名付きURLを試す

sign — AWS CLI 1.24.4 Command Reference

AWSコマンドで発行

% aws cloudfront sign \
	--url https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8 \
	--key-pair-id K1**********X2 \
	--private-key file://cloudfront_private_key.pem \
	--date-less-than 2022-05-21T15:10:00+09:00
https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/info.json?Expires=1653112080&Signature=fgTNi4pfrUFltHF65HcR2hQq08p63zOeyt2zSBRj9GDrkYc2vxo3~kudSm~i6F2zZeAup1SsRb1ujjYYR7oYzapR0kJqx~Fjb-E1~Kpz2ZN6XOhYDR0BxI5va1Cylx~4jSGl~01w4iA~~G5s9CwUYWV7WS6oe7JklijQVyVqzHkuTF~8H937I2jkXie5sUEFLII4iwPlGQYgj-x2Dfx8VD3iGM8Poclz6JO7-Yr8ctcbYg23LWbVNEp1vp3BfsbQEE~~CeOryz9mWnCcyoniBlmZwmmwngoJTqWmnndmpU9fQryocG9ZzcALWYuXf7NUbf8GmiGcFEVuXDtDqeG~Gg__&Key-Pair-Id=K1**********X2

url: 対象のURL(*を使う場合は–date-greater-thanの指定も必要)
key-pair-id: キーグループのパブリックキー(下記、画像参照)
private-key: 作成した秘密鍵(絶対パスで指定する場合は「file:///Users/xxx/xxx.pem」)
date-less-than: 有効期限の終了日時

動作確認

出力されたURLにリクエスト → 200で内容が返却される

% curl -i "https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8?Expires=1653113400&Signature=fThfpMfITzArdvP5FVljmdTK-SVVTM9noxYpS8JNYxI6g7Ufl6f0SX1Eb6P7KD3jAWzwJLmTcxk0a8mETPpQMGN7rIyT7jVk2sAkJj5d1-wKpG4U1A6MxD92aLXFrpZiW57AhNI03wzKvZBigb6Nt1Z-0GY53HpGGIqYG4G7X4eqdGc0LTuVTgEkGLZUs3Ps~nsCTaWRLagfCIxP6HR1CZQDuvmIc~EJ6feR58NQta2~dWBBEeTAp1WhD35Jg98Qeb4Q8o2xVgMCvAZpDiIsJ-gXbyywxG2qrfVk39av8PYXsL2wsW4jGxTF2FU7~yRH9uO8WxrPrCQVFNBDG3xvsw__&Key-Pair-Id=K1**********X2"
HTTP/2 200 
content-type: application/vnd.apple.mpegurl
content-length: 213
date: Sat, 21 May 2022 06:07:06 GMT
last-modified: Fri, 20 May 2022 00:28:53 GMT
etag: "3106d77c498a94487ddd4ce1a1139656"
accept-ranges: bytes
server: AmazonS3
vary: Origin
x-cache: Miss from cloudfront
via: 1.1 c9203ba15af2ae82294719bd8bb5fcce.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P2
x-amz-cf-id: k-hDi4NHN-uPNSZBxc_9gEBy_e5kadMJZYN08uuUVvwGoCdBM8TZHQ==

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=1165158,AVERAGE-BANDWIDTH=727352,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=24.000
Big%20Buck%20Bunny_video.m3u8

終了日時以降にリクエスト → 403(AccessDenied)になる

% curl -i "https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8?Expires=1653113400&Signature=fThfpMfITzArdvP5FVljmdTK-SVVTM9noxYpS8JNYxI6g7Ufl6f0SX1Eb6P7KD3jAWzwJLmTcxk0a8mETPpQMGN7rIyT7jVk2sAkJj5d1-wKpG4U1A6MxD92aLXFrpZiW57AhNI03wzKvZBigb6Nt1Z-0GY53HpGGIqYG4G7X4eqdGc0LTuVTgEkGLZUs3Ps~nsCTaWRLagfCIxP6HR1CZQDuvmIc~EJ6feR58NQta2~dWBBEeTAp1WhD35Jg98Qeb4Q8o2xVgMCvAZpDiIsJ-gXbyywxG2qrfVk39av8PYXsL2wsW4jGxTF2FU7~yRH9uO8WxrPrCQVFNBDG3xvsw__&Key-Pair-Id=K1**********X2"
HTTP/2 403 
server: CloudFront
date: Sat, 21 May 2022 06:30:01 GMT
content-type: text/xml
content-length: 110
vary: Origin
x-cache: Error from cloudfront
via: 1.1 c840859ec974616ca6ae517a4e6900e8.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P2
x-amz-cf-id: U9b1q0XpPJoSC-SrXh8CVoecCopAtiAJVTX9lOZh2-MlXjFgIf6HEw==

<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access denied</Message></Error>%

署名付きCookieを試す

カスタムポリシーを使用する署名付き Cookie の設定 – Amazon CloudFront

opensslで作成

エポック秒(UNIX秒)変換 : Developer Tools
JST「2022-05-21 18:30:00」→「1653125400」

CloudFront-Policyに設定する値

% echo '{"Statement":[{"Resource":"https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/*","Condition":{"DateLessThan":{"AWS:EpochTime":1653125400}}}]}' > policy.json

% cat policy.json | openssl base64 | tr '+=/' '-_~'
eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jZG4ubmlnaHRvbmx5
LmNvbS9hdXRoL0JpZyUyMEJ1Y2slMjBCdW5ueS5tcDRfMjAyMjA1MjAwMDI3MTkv
KiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6
MTY1MzEyNTQwMH19fV19Cg__

CloudFront-Signatureに設定する値

% cat policy.json | openssl sha1 -sign cloudfront_private_key.pem | openssl base64 | tr '+=/' '-_~'
NLzCFTsnDHLkg1Od~S3GYs64bxbvIB8LaD9X-2DKWrtUxxJKx2swif6lrsCP-hgq
FFJ8AP8HN0u82OzKQmQr~8mlzVt6PqH~640jXetlE3MIe-X~8Txsy7SNsPvuIrWr
MpjeeusBa~xzhnwXAF4Ek~h2AyNUuPv8NF8a7olPYOntkWzJj9GLzUG6TChEfsB8
iBw-eSaNwmHm0twzijl7jlgKxTsoYJr6Jv3p54sUFzmw3W1-VSbOUKafRnhuTjil
SKfc498I1yfnjawBzFKpZMcd4Vi7lKWJ0GA7GSjX8Mzm6HUPXhloRft0sVePrBhA
Sd43gIzchwx2NIcqYsCT6A__

動作確認

CloudFront-Policy: 上記で作成した値
CloudFront-Signature: 上記で作成した値
CloudFront-Key-Pair-Id: キーグループのパブリックキー(下記、画像参照)

終了日時前にリクエスト → 200で内容が返却される

% curl -i -H 'Cookie:CloudFront-Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jZG4ubmlnaHRvbmx5LmNvbS9hdXRoL0JpZyUyMEJ1Y2slMjBCdW5ueS5tcDRfMjAyMjA1MjAwMDI3MTkvKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTY1MzEyNTQwMH19fV19Cg__' \
	 -H 'Cookie:CloudFront-Signature=NLzCFTsnDHLkg1Od~S3GYs64bxbvIB8LaD9X-2DKWrtUxxJKx2swif6lrsCP-hgqFFJ8AP8HN0u82OzKQmQr~8mlzVt6PqH~640jXetlE3MIe-X~8Txsy7SNsPvuIrWrMpjeeusBa~xzhnwXAF4Ek~h2AyNUuPv8NF8a7olPYOntkWzJj9GLzUG6TChEfsB8iBw-eSaNwmHm0twzijl7jlgKxTsoYJr6Jv3p54sUFzmw3W1-VSbOUKafRnhuTjilSKfc498I1yfnjawBzFKpZMcd4Vi7lKWJ0GA7GSjX8Mzm6HUPXhloRft0sVePrBhASd43gIzchwx2NIcqYsCT6A__' \
	 -H 'Cookie:CloudFront-Key-Pair-Id=K1**********X2' \
	 https://cdn.nightonly.com/auth/Big%20Buck%20Bunny.mp4_20220520002719/Big%20Buck%20Bunny.m3u8
HTTP/2 200 
content-type: application/vnd.apple.mpegurl
content-length: 213
date: Sat, 21 May 2022 06:07:06 GMT
last-modified: Fri, 20 May 2022 00:28:53 GMT
etag: "3106d77c498a94487ddd4ce1a1139656"
accept-ranges: bytes
server: AmazonS3
vary: Origin
x-cache: Hit from cloudfront
via: 1.1 31644ad9395bb6bc6190c221b30bd768.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-C4
x-amz-cf-id: CcNdce7uCgYN0yGbzFIezZUydXGxVp7CfLDHA_EuhtWmGVRJd1BFSQ==
age: 11788

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=1165158,AVERAGE-BANDWIDTH=727352,CODECS="avc1.4d401f,mp4a.40.2",RESOLUTION=1280x720,FRAME-RATE=24.000
Big%20Buck%20Bunny_video.m3u8

終了日時以降にリクエスト → 403(AccessDenied)になる

HTTP/2 403 
server: CloudFront
date: Sat, 21 May 2022 09:30:50 GMT
content-type: text/xml
content-length: 110
vary: Origin
x-cache: Error from cloudfront
via: 1.1 c8cb49c2b391bae10c56b1a57df509d0.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-C4
x-amz-cf-id: vrL8QcESB9QdTcJjAdEVat43dpzjxIZslrPe1LXmbm8ecTrmj1CR2A==

<?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access denied</Message></Error>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です