概要
CloudFront + S3 で Web サイト作るなら OAC が良さそうだと思った話。
CloudFront + S3 の組合せ
S3 で静的 Web サイトを構成するにあたって、HTTPS 対応等のために CloudFront を使うことが多いと思う。つい一週間くらい前にも、S3 にホストしたサイトで HTTPS を強制する2つの方法をまとめた。
紹介した2つの方法は以下の通り。
- REST API エンドポイント + Origin Access Control (OAC)
- Web サイトエンドポイント + Referer 制限
2つ方法があるということは選択の必要があるということ。じゃあどっちがいいのか。
この点について、前回はこんな風に書いていた。
今のところ、「Web サイトエンドポイント + Referer 制限」推し。メリットはこれくらい。
S3 にホストした Web サイトで HTTPS を強制する:https://www.akahige-life.com/s3-website-hosting-with-https/
- 静的 Web ホスティングの機能(トップページ、エラーページ、リダイレクト等)が利用できる。
- 新たなリソース(Origin Access Control setting)を作成しなくていい。
タイトル通り、結論としては「REST API エンドポイント + OAC」推しに変わった。
REST API + OAC を推す
理由
なぜ REST API + OAC を推すのか。
その理由は、S3 のパブリックアクセスブロックが使用できること。
パブリックアクセスブロックとは
S3 にはパブリックアクセスブロックという機能がある。その名の通り、S3 バケットに保存されるオブジェクトに対するアクセスを制限することができる。コンソールから S3 バケットを作成した場合、デフォルトでパブリックアクセスブロックは有効になっている。(※ CloudFormation で作成した場合はデフォルトで無効。)
パブリックアクセスブロックには4つの設定がある。ざっくりまとめると次のイメージ。
BlockPublicAcls | パブリックアクセス可能な ACL の設定を禁止 |
IgnorePublicAcls | パブリックアクセス可能な ACL を無視 |
BlockPublicPolicy | パブリックアクセス可能なバケットポリシーの設定を禁止 |
RestrictPublicBuckets | パブリックアクセス可能なポリシーを持つバケットへのアクセスを制限 |
Access Control List (ACL) は、アクセス制御のために使用される設定である。現在では ACL は無効化が推奨されているらしい。
最近(?)のアップデートでも、ACL 無効化への移行を手助けするような機能が追加されている。
あと、執筆時点で初めて知ったが、ACL は AWS 固有のものではなく一般的な概念らしい。
Web サイトエンドポイントの場合
S3 の静的 Web ホスティング機能を使用する場合には、パブリックアクセスブロックを無効にし、バケットポリシーで全てのプリンシパルからのアクセスを許可する必要がある。
Web サイトエンドポイントを使用しているときに、試しにパブリックアクセスブロックを有効化してみたところ、サイト閲覧に影響がないように見えたが、CloudFront のキャッシュが効いていただけだった。ビヘイビアのキャッシュポリシーを「Managed-CachingDisabled」に変更してキャッシュを無効化すると、Access Denied になった。
推しを変えた一押し
そして、推しを完全に変えた最後の一押しがこれ。S3 におけるベストプラクティス。
Amazon S3 バケットに正しいポリシーが使用され、バケットが公開されていないことを確認する
Amazon S3 のセキュリティベストプラクティス:https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/security-best-practices.html
書いてるまま。S3 バケットの作成時にデフォルトで有効になっていることからも分かるように、パブリックアクセスブロックの有効化が推奨されている。
コンソールを確認しても、無効に設定している場合は警告ライクに表示される。
静的 Web ホスティング機能の補完
前回の記事で Web サイトエンドポイントを推していた理由の一つが、静的 Web ホスティングの機能(トップページ、エラーページ、リダイレクト等)が利用できることだった。
その辺りを補う方法について。
トップページについては、CloudFront の一般設定からデフォルトルートオブジェクトを設定することで対応可能である。index.html 等を設定することで、デフォルトでトップページにアクセスできる。
エラーページについても、CloudFront に設定項目があり、HTTP ステータスコードをベースにエラーレスポンスを設定できる。
リダイレクトについては、Lambda@Edge や CloudFront Functions 等のエッジ関数を利用することで実現できるらしい。関数使えるとなるとできることは未知数な気がする。この辺りは全く触ったことがないから、また今後の課題としたい。
まとめ
CloudFront と S3 を使って Web サイトをホストするより良い方法を考えてみた。
今だったら、S3 の REST API エンドポイントを CloudFron オリジンとして、OAC によるアクセス制限を設定する方法を推す。
理由は、S3 のパブリックアクセスブロックが使用可能になるから。
感想
一週間で、手のひらくるくる。
OAC ならパブリックアクセスブロックしてもサイトを公開できるとは知らなかった。せっかく S3 に Web ホスティング用の設定あるんなら使ってあげたいけど。セキュリティ面を考えるとパブリックアクセスブロックできる方がいい。
ただこうなると S3 の静的 Web サイトホスティングの使いどころが分からなくなった。
SEO 的にも HTTPS 対応は必須と言われてるから、多くの場面で CloudFront + S3 の組合せを使うことになると思う。その場合は REST API エンドポイント + OAC の方が良さそうだから……
となると、使いどころは閉じたネットワーク内での Web サイト?でも、閉じたネットワーク内で Web サイト使って情報共有するなら、みんなが書き込めるような動的サイトになる気がする。