Develop with pleasure!

福岡でCloudとかBlockchainとか。

CloudFrontでプライベートコンテンツの公開:Securing Your Content in Amazon S3

Securing Your Content in Amazon S3を意訳。

CloudFrontのPrivate Distributionを使用するには、CloudFrontアクセスIDを作成し、そのIDのみからコンテンツへアクセスできるようS3内のオブジェクトのACLを設定する必要がある。このセクションでは、アクセスIDとは何か、アクセスIDを組み込むためにどのようにdistributionを変更すれば良いか、どのようにCloudFrontからS3内のデータへのアクセスか認可するかについて説明する。

CloudFrontアクセスIDについて

CloudFrontアクセスIDは、S3のバケットからのコンテンツの取得を許可する仮想IDである。まず自分のAWSアカウントでCloudFrontアクセスIDを作成し、そのIDをdistributionにアタッチし、S3のオブジェクトへの読み取り権をそのIDに与える。S3のバケットへのPublicアクセスを禁止した後は、CloudFront distributionのみがバケット内のオブジェクトへアクセスすることができるようになる。そして署名者のアカウントがdistoributionの設定に追加されると、署名されたURLを持つユーザのみがアクセスできるようになる。

1ユーザあたり、100個までのCloudFrontアクセスIDを持つことができ、それぞれのIDを1つもしくは複数のdistributionにアタッチできる。ただ、通常1つのアクセスIDで十分事足りると思われる。

以下の例では、3つのことなるdistributionの例を表している。

http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/images/PrivateContent_MultipleDistributions.gif

  1. Distribution 1はPublicなコンテンツ用の設定で、誰でもObjectの読み取り権限をもてるようS3のACLが設定されている。そのため誰もが、S3もしくはCloudFrontを介してコンテンツにアクセスすることが可能。
  2. Distribution 2は署名されたURLを持つPrivateなコンテンツとなるよう設定されている。このdistributionにはCloudFrontアクセスID Aがアタッチされており、S3のオブジェクトのACL設定はアクセスID Aに読み取り権限を与えるよう設定されている。このdistributionのコンテンツは、署名されたURLを持たないユーザからアクセスできない。
  3. Distribution 3はベーシックURLを持つPrivateなコンテンツとなるよう設定されている。このdistributionにはCloudFrontアクセスID Aがアタッチされており、S3のオブジェクトのACL設定はアクセスID Aに読み取り権限を与えるよう設定されている。このdistributionのコンテンツはPrivateではないが、エンドユーザはCloudFrontを介してのみアクセスが可能となる。(=CloudFrontを介さないS3への直アクセスはできない。)


CloudFrontアクセスIDの作成

CloudFrontアクセスIDの作成は、2010-11-01/origin-access-identity/cloudfrontリソースへのPOSTで生成できる。distribution作成時にRequest内にユニークな参照を提供する必要がある。オプションでIDにコメントを付加することも可能。

※2011/5/19現在、AWSのManagement ConsoleではアクセスIDの作成やPrivateコンテンツを提供するdistributionの更新はサポートしていない。

distribution用のCloudFrontアクセスIDの作成

1.以下のようなCloudFrontコントロールAPIリクエストを送信する。

POST /2010-11-01/origin-access-identity/cloudfront HTTP/1.1
[Required headers]  
<?xml version="1.0" encoding="UTF-8"?>
<CloudFrontOriginAccessIdentityConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
  <CallerReference>20091130090000</CallerReference>   
  <Comment>Your comments here</Comment>
</CloudFrontOriginAccessIdentityConfig>

2.以下のようなレスポンスを受け取る。

201 Created
Location: https://cloudfront.amazonaws.com/2010-11-01/origin-access-identity/cloudfront/E74FTE3AJFJ256A
x-amz-request-id: request_id

<?xml version="1.0" encoding="UTF-8"?>
<CloudFrontOriginAccessIdentity xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
  <Id>E74FTE3AJFJ256A</Id>
  <S3CanonicalUserId>
     cd13868f797c227fbea2830611a26fe0a21ba1b826ab4bed9b7771c9a69ba19f
  </S3CanonicalUserId>
  <CloudFrontOriginAccessIdentityConfig>
    <CallerReference>20091130090000</CallerReference>   
    <Comment>Your comments here</Comment>
  </CloudFrontOriginAccessIdentityConfig>
</CloudFrontOriginAccessIdentity>

3.IdとS3CanonicalUserId を記録する。
これはらの値は後半のプロセスで使用する。IdはアクセスIDをdistributionへアタッチする際に使用し、S3CanonicalUserIdは、S3のACL内でCloudFrontを識別するのに使用する。

以上でアクセスIDが生成されたので、Privateコンテンツ用に設定されたdistributionを作成することができる。


Private Content Distributionの作成

distributionは、設定値によってPublicにでもPrivateにでもすることができる。Privateコンテンツ用のdistributionを作成するためには、PrivateなURLに署名を行う署名者のアカウントを割り当てる。署名は、署名者が所有するRSA鍵の秘密鍵を使用して暗号化されたポリシーステートメントのハッシュである。

設定の中にOriginAccessIdentityという要素があることを除けば、PrivateコンテンツDistributionはPublicコンテンツDistributionと変わりはなく、その要素は以下のフォーマッで定義する必要がある。
origin-access-identity/cloudfront/ID


PrivateコンテンツDistributionの作成

要素OriginAccessIdentityを含むdistributionの作成。
以下のようなリクエストで新しいPrivateコンテンツDistributionを作成する。

POST /2010-11-01/distribution HTTP/1.1
[Required headers]

<?xml version="1.0" encoding="UTF-8"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
  <S3Origin>
     <DNSName>mybucket.s3.amazonaws.com</DNSName>
     <OriginAccessIdentity>
     origin-access-identity/cloudfront/E127G7VVVYK51Z
     </OriginAccessIdentity>
  </S3Origin>
  <CallerReference>20091130090000</CallerReference>
  <Comment>My comments</Comment>
  <Enabled>true</Enabled>
</DistributionConfig>

ストリーミング配信distribution用の以下のリクエストは、静的なコンテンツのdistributionに似てる。

POST /2010-11-01/streaming-distribution HTTP/1.1
[Required headers]

<?xml version="1.0" encoding="UTF-8"?>
<StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-11-01/">
  <S3Origin>
     <DNSName>mybucket.s3.amazonaws.com</DNSName>
     <OriginAccessIdentity>
     origin-access-identity/cloudfront/E127G7VVVYK51Z
     </OriginAccessIdentity>
  </S3Origin>
  <CallerReference>20091130090000</CallerReference>
  <Comment>My comments</Comment>
  <Enabled>true</Enabled>
</StreamingDistributionConfig>

既存のdistributionをUpdateする場合については、Updating a Distribution's Configurationを参照。

以上で、PrivateコンテンツDistributionの設定の作成はできたので、あとはS3のPrivateコンテンツオブジェクトのACLを設定する必要がある。Privateコンテンツオブジェクトの詳細についてはModifying the ACL on Your Private Content Objectsを参照。

PrivateコンテンツオブジェクトのACLの変更

PrivateコンテンツDistributionが用意できたら、CloudFrontアクセスIDにPrivateコンテンツへのアクセス権限を付与する。この際変更するのは、distributionで提供されるオブジェクトのS3のACLを変更する。(変更するのはオブジェクトの設定でありバケットの設定ではない。)オブジェクトのACLでは、CloudFrontアクセスIDのS3のCanonicalUser IDに参照権限を追加する。Amazon S3 CanonicalUser ID は、distributionと関連付けだれているCloudFront IDではない。ACLを変更するには、S3のAPIを使用するかManagement Consoleを使用すれば良い。

S3のAPIを使用してACLの設定を変更する際、まずオブジェクトのACLをGETし、ACLの設定を変更し、最後に変更されたACLをPUTする。ACLのフォーマット及びACLの更新に関する詳細は、REST Access Control PolicyAccess Control Listsを参照。

ACLの変更はAWS SDKを使用してコードで行うことも可能。サンプルコードについてはCreate a URL Signature Using C# and the .NET Frameworkを参照。

もし、PublicコンテンツDistributionをPrivateコンテンツDistributionに変更したい場合は、Publicに設定されてあるACLを全て削除すること。

※重要
CloudFrontでPrivateコンテンツを提供するためには、S3のバケットはDNSセーフな名前である必要があり、バケット名は全て小文字である必要がある。バケット名は「http://bucketname.s3.amazon.com」のようにURLの先頭に来る。詳細については、Bucket Restrictions and Limitationsを参照。

次のステップでは、distributionへのエンドユーザからのアクセスの制御と署名されたURLを作成する必要がある。詳細については、Restricting End User Accessを参照。