CloudFront×S3でセキュアに静的サイトを配信をする
こんにちわ。
システムソリューション部のリンです。
インフラエンジニア3年目に突入した私ですが、ようやく「S3についてあまり知らないので、勉強してみようかな~('ω')」と思いながら、ネットサーフィンしていたら、こんな記事を見つけました。
「次は、Cloudfrontと連携して配信を行う方法を書きたいと思います。」と絞められているものの記事が無かった為、せっかくなので約9年の時を経て、リレー形式で書いてみたいと思います。
全体の流れ
S3バケットの作成
↓
バケットにhtmlファイルのアップロード
↓
CloudFrontディストリビューションの作成
↓
S3バケットのポリシー設定
↓
アクセスしてみる
実際にやってみる
S3バケットの作成
① S3コンソールに移動後、「バケットの作成」をクリックします。
② バケットタイプは「汎用」を指定し、バケット名を入力します
※ バケット名は世界中で一意である必要があります。
③ その他の設定はデフォルトでOKなのですが、パブリックアクセス設定で「パブリックアクセスを全てブロック」となっている事を確認してください。
※今回はCloudFrontを経由してのみ、S3バケット内のファイルを配信出来る様にしたい為です。
③ 確認が出来たら、「バケットを作成」をクリックして下さい。
作成できました!
④ファイルをアップロードする
バケット一覧画面からバケット名を押下 > アップロード
表示させたい静的ファイルをアップロードします。
今回私は、こちらのhtmlファイル(index.html)をアップロードしました。(ChatGPT作)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ありがとう</title> <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family%3A%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background-color%3A%20%23f0f0f0%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20%23333%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20center%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2050px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20h1%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%202.5em%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20p%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%201.2em%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<style>" title="<style>" /> </head> <body> <h1>この記事を読んでくれてありがとう!</h1> <p>CloudFront×S3でセキュアに静的サイトの配信を学んでいただけたでしょうか。</p> </body> </html>
CloudFrontの設定
配信したいファイルの設置が完了したので、続いてCloudFrontの設定を行っていきます。
CloudFront > ディストリビューションを作成 と画面遷移してください。
設定項目 | 値 |
Distribution options | Single website or app |
Origin domain | 作成したS3バケット |
名前 | 任意で指定 |
オリジンアクセス | Origin access control settings (recommended) |
オリジンアクセス に「Origin access control settings (recommended)」を選択したら、OAC(origin access control)を新規作成していきます。
OACが作成出来たら、Origin access controlに自動で今作成したOACが入ります。
その他の設定項目はデフォルトでOKなので、ディストリビューションの作成を押下します。
こんな感じでディストリビューションが作成できていればOKです!
ちなみに OAC(Origin Access Control) とは?
CloudFrontからS3バケットへのアクセスを制御するポリシーです。
CloudFrontからの要求をS3バケットが認識し、それ以外からのアクセスをブロック出来る様になります。
またOACはOAI(Origin Access Identity)の後継として2022年に登場しました。
OACはOAIよりも詳細なポリシー設定が可能で、OAIではサポートされていなかった以下についてもサポートされています。
・AWS KMS による Amazon S3 サーバー側の暗号化 (SSE-KMS)
・Amazon S3 に対する動的なリクエスト (PUT と DELETE)
S3バケットのポリシー設定
CloudFront > ディストリビューション > 作成したディストリビューションを押下 > オリジンのタブを押下
選択したオリジンに対して「編集」を押してください。
オリジンアクセスまで移動し、画像のように表示されているポリシーをコピーしてから、S3バケットのアクセス許可に遷移してください。
S3バケットの画面に遷移したら、アクセス許可のタブを選択、バケットポリシーを編集します。
先ほどコピーしたポリシーを貼り付けし、変更を保存してください。
ちなみにコピーされるポリシーは下記の様になります。
{ "Version": "2008-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [ { "Sid": "AllowCloudFrontServicePrincipal", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::cloudfront-s3-rin-test-bucket/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::xxxxxxxxxx:distribution/EE49MGYO530OK" } } } ] }
各ポリシーの意味 (重要ポイントのみ抜粋)
Principal | CloudFrontのサービスが指定されています。 これにより、CloudFrontのみがS3バケットのオブジェクトにアクセスできます。 |
Action | "s3:GetObject"は、オブジェクトを取得するための許可を示しています。 |
Resource | バケット内のすべてのオブジェクトを指定しています。 |
Condition | 特定のCloudFrontディストリビューションからのリクエストのみを許可するためのものです。 |
ここまで来れば準備完了です!
アクセスしてみる
今回は独自のドメインを紐づけていないので、ディストリビューションドメインに直接アクセスしていきます。
ディストリビューションドメイン名は、ディストリビューションの一般から確認できます。
無事アップロードしたHTMLファイルを表示できました!
S3のパブリックアクセスができないことも確認しておきたいので、S3のURLにもアクセスしてみます。
想定通りAccessDeniedになっていますね!