1. Qiita
  2. Items
  3. AWS

AWS CloudFrontでプライベートコンテンツを配信

  • 41
    Like
  • 0
    Comment
More than 1 year has passed since last update.

この記事は、AWS S3 + CloudFront で動画ストリームの続きです。

目的

期限付きURLでの接続を行う。(ワンタイムURL)
動画ストリームに閲覧制限し配信したい。(今回は画像で試した)
最終的にはPloneの認証を使って動画を配信したい。(次回以降にチャレンジ)

S3 及び CloudFront の設定

新規にバケットを作り、お試しの画像を置く。この画像をプライベート配信する事を試す。

S3

  • 新規にバケットを作る (c2-video-test-private)
    • ログの設定は行う
  • Upload
    • 画像ファイルをアップロード "terada_pythonbr.jpg"

CloundFront

  • CloudFront アクセスIDの取得
    • IAMのWeb管理コンソールへ行く
    • Details内の、 "CloudFront Key Pair" で、"Create New Key Pair"を取得
    • 秘密鍵と公開鍵をダウンロードする
  • CloudFront Origin CloudFrontのWeb管理画面で、"Private Content"から"Origin Access Identity"へ行く(あとで作る方法もある)
    • Create OAI をクリック
    • コメントに "OAI for c2-video-test-private" と入れて作成
  • 新規に"Private Distribution"を作る (Web用)
  • 設定を行う
    • Restrict Bucket Access: Yes
    • Origin Access Identity: Use an Existing Identity
    • Your Identities: を前もって作ったものを選択(またはここで新規に作ることも可能)
    • Grant Read Permissions on Bucket: Yes
    • HTTPS Only:Yes
    • Restrict Viewer Access: Yes
    • Trusted Signers
    • Logging: On
    • その他Loggingの設定(バケットとPath)
  • Domain Name: dn045wcqv2fv4.cloudfront.net となった

Signed URLを作る

以下の botoの項目を参照しローカルのPython環境で作ってみる。

制限なしURLは、以下となるはず。

https://dn045wcqv2fv4.cloudfront.net/terada_pythonbr.jpg
当然ですが、エラーが帰ってきました。

error.xml
<Error>
  <Code>MissingKey</Code>
  <Message>Missing Key-Pair-Id query parameter</Message>
</Error>

制限付きURLを作る

(boto関係の詳細は下部に記載)

sample.py
ACCESS_KEY_ID = "xxxxxxxxxxxxxxxxx"
SECRET_ACCESS_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxx"
YOUR_KEYPAIR_ID = "xxxxxxxxxxxxxx"
YOUR_PRIVATE_KEY_FILE_LOCATION = "xxxxxxxxxxxxxxxxxxxxx.pem"
url = "https://dn045wcqv2fv4.cloudfront.net/terada_pythonbr.jpg"
expire_time = int(time.time() +3600)

conn = CloudFrontConnection(ACCESS_KEY_ID, SECRET_ACCESS_KEY)
distribution = Distribution(connection=conn, config=None, domain_name='', id='', last_modified_time=None, status='')

signed_url = distribution.create_signed_url(url=url, keypair_id=YOUR_KEYPAIR_ID, expire_time=expire_time, private_key_file=YOUR_PRIVATE_KEY_FILE_LOCATION)
>>> print signed_url
https://dn045wcqv2fv4.cloudfront.net/terada_pythonbr.jpg?Expires=1406023941&Signature=Ihps3u0~jQ-Twkghg2tqQ-dTMEZoRC-Jb13F4FgNe~1MVAsXQ-yAbXtEKSTsIhN6OLZmuUii6E1xs7nWfe-76SGk26Jmx5edd35EgwQ8mH~2XlY4QOqP1Fgza93q02oQNhJWte1mef4tc8p3fJO6yzebpTEh4MqvQOt9s5bcKq9ad8EGSmfXfUlgL6b87z6TOAXVFQuIotttu6ajlfbCpplIUD-~r-6W~SB6n2dyB8SaoKgJBTkEKJwFiBWx2S5M20-06hsLOeV23UBJcuq6~C-pE1r1ViE8Ia-tM8L6v7zcbtLfOdw9lgFzYoMoh-KiWOAdz7pc-koYMVPXZ-9DuQ__&Key-Pair-Id=APKAJAJZQHPKZI6OK5UQ

ブラウザでアクセステスト

https://dn045wcqv2fv4.cloudfront.net/terada_pythonbr.jpg?Expires=1406023941&Signature=Ihps3u0~jQ-Twkghg2tqQ-dTMEZoRC-Jb13F4FgNe~1MVAsXQ-yAbXtEKSTsIhN6OLZmuUii6E1xs7nWfe-76SGk26Jmx5edd35EgwQ8mH~2XlY4QOqP1Fgza93q02oQNhJWte1mef4tc8p3fJO6yzebpTEh4MqvQOt9s5bcKq9ad8EGSmfXfUlgL6b87z6TOAXVFQuIotttu6ajlfbCpplIUD-~r-6W~SB6n2dyB8SaoKgJBTkEKJwFiBWx2S5M20-06hsLOeV23UBJcuq6~C-pE1r1ViE8Ia-tM8L6v7zcbtLfOdw9lgFzYoMoh-KiWOAdz7pc-koYMVPXZ-9DuQ__&Key-Pair-Id=APKAJAJZQHPKZI6OK5UQ

2014/07/22 18:14にアクセスできた。
2014/07/22 19:15になったらアクセス出来ないはず

boto

boto は、AWSのAPIを操作するPythonモジュールです。以前はAmazon非公式でしたが、いまは開発者がAmazon所属になったはずなので、半公式なはずです。

事前準備

$ pip install rsa
$ pip install boto

Signed URLの取得方法

説明が以下にありました。
http://boto.readthedocs.org/en/latest/ref/cloudfront.html

create_signed_url(url, keypair_id, expire_time=None, valid_after_time=None, ip_address=None, policy_url=None, private_key_file=None, private_key_string=None)
  • url (str)
  • keypair_id (str)
  • expire_time (int)
  • valid_after_time (int)
  • ip_address (str)
  • policy_url (str)
  • private_key_file (str or file object.)
  • private_key_string (str)

以下にサンプルがあった

http://stackoverflow.com/questions/2573919/creating-signed-urls-for-amazon-cloudfront

import boto
from boto.cloudfront import CloudFrontConnection
from boto.cloudfront.distribution import Distribution

expire_time = int(time.time() +3000)
conn = CloudFrontConnection('ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')

##enter the id or domain name to select a distribution
distribution = Distribution(connection=conn, config=None, domain_name='', id='', last_modified_time=None, status='')
signed_url = distribution.create_signed_url(url='YOUR_URL', keypair_id='YOUR_KEYPAIR_ID_example-APKAIAZVIO4BQ',expire_time=expire_time,private_key_file="YOUR_PRIVATE_KEY_FILE_LOCATION")

調査時に参照したURL

動画で試してみる

TODOにしていた、動画ストリームに上記を対応させる

準備

  • c2-video-test-private バケットに、videoフォルダを追加
  • PyConAPACTW2014terada.mp4 を videoフォルダに追加
  • CloudFrontにストリーム対応のDistributionを追加
    • Create時に、RTMPを選択
    • Origin Domain Name : c2-video-test-private
    • Restrict Bucket Access: Yes
    • Origin Access Identity: Use an Existing Identity
    • Your Identities: を前もって作ったものを選択 (OAI for c2-video-test-private)
    • Grant Read Permissions on Bucket: Yes
    • Restrict Viewer Access: Yes
    • Trusted Signers: Self
    • Logging: On
    • その他Loggingの設定(バケットとPath)

ここまでは、今までのおさらいで簡単に出来るはず。

Signed URLを作る

上記同様に、botoを使って作業

  • url = "rtmp://s3lse3ja7xuop9.cloudfront.net/cfx/st/&mp4:video/PyConAPACTW2014terada.mp4"
  • policy_url = "video/" ワイルドカードを指定している。 **rtmpの時は* 上記のようにPATHだけを書く(rtpm://から書くとうまくいかない<これで数日ハマった)
>>> url = "rtmp://s3lse3ja7xuop9.cloudfront.net/cfx/st/&mp4:video/PyConAPACTW2014terada.mp4"
>>> policy_url = "video/*"
>>> signed_url = distribution.create_signed_url(url=url, keypair_id=YOUR_KEYPAIR_ID, expire_time=expire_time, private_key_file=YOUR_PRIVATE_KEY_FILE_LOCATION, policy_url=policy_url)
>>> print signed_url
rtmp://s3lse3ja7xuop9.cloudfront.net/cfx/st/&mp4:video/PyConAPACTW2014terada.mp4?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoidmlkZW8vKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTQwNjg5OTIwMX19fV19&Signature=m10lfH4vpepAWVNLCGO9xr~TFs-ZCUklra-I4D6WZvqO3aHhijIbtPQOiK00BPZzTxnu-enkvTuao1aDoP~HSONzF5xIqGqMuP4RYJ-B0~g5iQxvac1VVkb~3lZXMRN3Oz45BsrRWQawyXp1o~0M9sFr~zIVQAbM8aAji1WmTu0~fY0UcfgO74DNevYw4-I4S8S2KLnSimFGeU0bz3b8bXtgxketPz0JhTyM4akK8gD7xWjskrxFOZ4pskCaLvJr3Pyb9pJsqQ9T2izNsPs0Ms5pi94FnOdyejSRWezqrxp00KNttnlc3DGCOcmcCNDNYdIMxmNC6MuAfQKx~a1tig__&Key-Pair-Id=APKAJAJZQHPKZI6OK5UQ

動画表示用のテンプレート

srcの部分をSigned URLにする。

<source src="rtmp://s3lse3ja7xuop9.cloudfront.net/cfx/st/&mp4:video/PyConAPACTW2014terada.mp4?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoidmlkZW8vKiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTQwNjg5OTIwMX19fV19&Signature=m10lfH4vpepAWVNLCGO9xr~TFs-ZCUklra-I4D6WZvqO3aHhijIbtPQOiK00BPZzTxnu-enkvTuao1aDoP~HSONzF5xIqGqMuP4RYJ-B0~g5iQxvac1VVkb~3lZXMRN3Oz45BsrRWQawyXp1o~0M9sFr~zIVQAbM8aAji1WmTu0~fY0UcfgO74DNevYw4-I4S8S2KLnSimFGeU0bz3b8bXtgxketPz0JhTyM4akK8gD7xWjskrxFOZ4pskCaLvJr3Pyb9pJsqQ9T2izNsPs0Ms5pi94FnOdyejSRWezqrxp00KNttnlc3DGCOcmcCNDNYdIMxmNC6MuAfQKx~a1tig__&Key-Pair-Id=APKAJAJZQHPKZI6OK5UQ"
                 type='rtmp/mp4' />

テストページ

すでに、閲覧期限が過ぎていると思うが、以下で見れることを確認
http://c2-video-test.s3-website-ap-northeast-1.amazonaws.com/index2.html

次回以降のTODO

  • 動画ストリームに閲覧制限し配信したい。 -> 20140801 上記の「動画で試してみる」項目に記載。
  • iOS用HLSの時ってどうなるのか調査 -> http://qiita.com/terapyon/items/fadecf13ed1d11dcd34d
  • 最終的にはPloneの認証を使って動画を配信したい。

著者関連Blog記事

AWS CloudFront でプライベートコンテンツ配信