CodlessCode
AWS

【 S3 + CloudFront 】カスタムヘッダーで制限された 静的 ウェブサイトを構成して入口をひとつにする

今回は、カスタムヘッダーで制限された静的ウェブサイトを構成します。
本記事は以下の続きとなっていますので、よければどうぞ👇

CloudFront + S3 で 静的 Webサイトを配信CloudFront と S3 を使って静的ウェブサイトを配信する方法をハンズオンっぽく紹介します。クラウドでは、静的コンテンツと動的コンテンツを分けて配信することでコスト削減やパフォーマンス向上、さらに可用性を高められるので重要視されます。アプリケーションの規模は関係なく、この方法はよく取られる手法です。...

前回は、CloudFrontとS3で静的コンテンツを配信できるようにしました。
このままだと、CloudFrontとS3どちらからでもコンテンツにアクセスできてしまいます。
※ウェブサイトへの入口が2つあるイメージです。

今回は
カスタムヘッダー(Referer)でS3の静的ウェブサイトエンドポイントへの直アクセスを制限して、CloudFront経由のアクセスのみ通すように設定します。

ウェブサイトへの入口をCloudFrontのみにするイメージです😊

 

はじめに

前回やったこと

前回やったこと

S3の静的ホスティングを有効にし、CloudFrontで公開しました。
CloudFront、S3どちらからでもウェブサイトにアクセスできる状態です。

※本記事は以下の続きです。良ければ参考にどうぞ!
CloudFront + S3 で 静的 Webサイトを配信

 

今回やること

S3の静的ウェブサイトエンドポイントへの直アクセスを制限してCloudFront経由のアクセスのみ通す概要図

カスタムヘッダーで制限された静的ウェブサイトを構成します。
具体的には、カスタムヘッダー(Referer)でS3へのアクセスを制限し、CloudFront経由のアクセスのみ通すようにします。

 

S3 側の設定

バケットポリシー 修正

S3オリジンへのアクセスは、ヘッダーに指定のReferer値を持つリクエストのみ許可する
ようにバケットポリシーを修正します。

Referer値を任意の値に読み替えて、以下のように入力しましょう。
※Referer値は誰にも知られないようにしてくださいね🤐

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Restricted by Referer header",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "バケットのARNを入力/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": "ここに任意の値を入力"
                }
            }
        }
    ]
}
バケットポリシー修正
 

動作確認

バケットウェブサイトエンドポイントをブラウザで開いてみます。
以下のように「403 Forbidden」になりました。
指定のReferer値がヘッダーにないためですね。

アクセス制限の確認1
 

Referer を設定して確認

以下のように、Postmanで「Header」にRefererを設定して「Send」すると、うまく接続出来ます。
バケットポリシーがうまく設定できましたね。

アクセス制限の確認2

値を知っていると接続できちゃうので、Referer値は秘密です🤐

 

CloudFront 側の設定

カスタムヘッダー追加

バケットポリシーに入力したReferer値をCloudFrontにも設定します。
該当のディストリビューションのオリジンを編集しましょう。

CloudFrontオリジン修正2

以下のように、Refererヘッダーを追加して変更を保存しましょう。

CloudFrontオリジン修正1
 

動作確認

ディストリビューションのデプロイが完了したら
該当のディストリビューションの一般タブでディストリビューション名を確認して、ブラウザからアクセスしてみます。
以下のように表示されたら成功です!

動作確認
 

おまけ

S3 直アクセスを CloudFront に リダイレクト する設定

S3バケットウェブサイトエンドポイントをブラウザで開いたとき、「403 Forbidden」と表示されましたが、これが気持ち悪いと思う人がいるかもしれません。(私です)
エラー情報は時として、攻撃者にとって有益な情報になってしまうので、できれば見せたくないなーと考えてます。

そこで
リクエストの結果がステータスコード403の場合、CloudFrontの方へリダイレクトする
ように追加設定していきましょう!

該当のS3バケットのプロパティタブで一番下までスクロールし、静的ウェブサイトホスティングを編集します。
リダイレクトルール – オプションで以下のように入力して変更の保存をしましょう。

[
    {
        "Condition": {
            "HttpErrorCodeReturnedEquals": "403"
        },
        "Redirect": {
            "HostName": "【CloudFrontディトリビューションのドメイン】",
            "HttpRedirectCode": "301",
            "Protocol": "https"
        }
    }
]

保存したら、S3バケットウェブサイトエンドポイントにアクセスしてみましょう。
ForbiddenではなくCloudFrontの方へリダイレクトされると思います!

ステータスコード403の場合だけリダイレクトするように変更しましたが、他にもルールを追加していけばさまざまな条件下でリダイレクトさせることが可能です。
以下を参考に目的にあったルールを作成してみてください👍
高度な条件付きリダイレクトを使用するようにリダイレクトルールを構成する

 

おわりに

カスタムヘッダー(Referer)で制限された静的ウェブサイトを構成し、ウェブサイトへの入口をひとつにすることができました。

前回の記事で書いたのですが、Refererヘッダーを不正アクセス対策として使うのはセキュリティ的に不十分です。
公式ドキュメントの記載はこちら)

ですが、カスタムヘッダーでこういうこともできるんだよっていう紹介になれば幸いです!

S3バケットをCloudFrontで配信するときのアクセス制御方法としては、OAI(オリジンアクセスアイデンティティ)を使う方法もあります。
ですが、OAIは静的ホスティングを有効にすると使えないので、今回のケースでは当てはまりませんが良ければご参考までにどうぞ👇

AWSカテゴリサムネイル画像
CloudFront と 代替 ドメイン を使って S3 にアクセスする方法CloudFront経由でS3の静的コンテンツにアクセスする手順を2ステップに分けて解説します。また、Route53・ACM・OAIも活用するので、CloudFrontのドメインと独自ドメインをリンクさせ、アクセス制限も設けてHTTPSで接続することができるようになります。...

前回の内容はこちらです。よければどうぞ👇

CloudFront + S3 で 静的 Webサイトを配信CloudFront と S3 を使って静的ウェブサイトを配信する方法をハンズオンっぽく紹介します。クラウドでは、静的コンテンツと動的コンテンツを分けて配信することでコスト削減やパフォーマンス向上、さらに可用性を高められるので重要視されます。アプリケーションの規模は関係なく、この方法はよく取られる手法です。...