🕌

S3のアクセス制御

に公開

目的

不必要にパブリックアクセスブロックがOFFになっているS3を洗い出して閉じるという作業を行っていました。
その中でS3のアクセス制御が結構ややこしかったので、備忘のために整理します。

ちなみに、パブリックアクセスブロックがデフォルトでONにされるようになったのは、2023年4月からです。それ以前に作られたバケットはパブリックアクセスブロックがOFFになったまま放置されている可能性があるので見てみるのおすすめです。

参考

https://dev.classmethod.jp/articles/notice-202304-default-change-amazon-s3-bpa-acl/

S3のアクセス制御方法や注意すべき設定は多岐にわたるので、以降で整理していきます。

①パブリックアクセスブロック

バケットやアカウント単位でパブリックアクセスを強制的に拒否します。
基本的に外部公開する要件がなければ、この設定はONにするべきです。(デフォルトでON)
この設定がONだと以降の設定でパブリックアクセスを許可するような設定をしていたとしても、全てブロックされます。(一番強い)
なので、現在OFFのものをONにしてよいか判断する場合は、様々な観点から調査しないといけません。

②バケットポリシー

バケット内のオブジェクトへのアクセス権限を制御します。
S3外部公開する場合、ここで許可/拒否設定を完結させるのがベストプラクティスです。
宣言的なので、全拒否+例外許可みたいな形に書くことになります。
※他のアカウントが所有するオブジェクトには適用されません。

③バケットACL

他アカウントに対して読み取り/書き込み権限の制御します。
基本的に設定が複雑化するため、ACL無効化が推奨されています。
バケットACLでは以下のGranteeに対してRead,Write,Listなどの権限を付与可能です。
①Bucket owner
②EveryOne(public access)
③Authenticated users Group(anyone with an AWS account)
④S3 log delivery group
⑤Access for other AWS accounts(追加で許可設定を与えている場合のみ)

②、③、⑤に権限が付与されている場合、パブリックアクセスブロックONにするとそのGranteeからアクセスできなくなります。(Bucket ownerがそもそも外部アカウントの場合は対象外とします。そもそも設定いじれることあんまないと思うし。。)

※注意点として、バケットACLで許可している設定でも、バケットポリシーで明示的に拒否されていればアクセスはブロックされます。逆にバケットポリシーで許可されていても、バケットACLで拒否されていれば、アクセスはブロックされます。

パブリックアクセスブロック(最強)→バケットポリシー、バケットACL(同率)→オブジェクトACLです。
上の階層で拒否されたアクセスは下で許可してもアクセスできません。

④オブジェクトACL

オブジェクトごとでアクセス権限を制御します。
※②や③より弱い設定で、どちらかで拒否されている権限はオブジェクトACLで許可していてもブロックされます。
また、そもそもACL有効化かつオブジェクト所有者がオブジェクトライターに設定されたバケットでしか使えません。ただし、ACL有効化、オブジェクト所有者オブジェクトライターは管理難易度や運用工数が増加するので、ベストプラクティスからは逸脱した設定です。

さらに、S3に対して複数のオブジェクトライターが存在する場合、各々のライターに書き込まれたオブジェクトACLを確認する必要があり結構面倒です。
私の場合は、そもそもオブジェクトライターの全量を把握していなかったので、全てのオブジェクトACLを確認する羽目になりました。。。

⑤静的ウェブサイトホスティング

バケット内のオブジェクトをWebサイトとして公開する機能です。
※パブリックアクセスブロックをOFFにする必要があります。

⑥静的ウェブサイトホスティングリダイレクト

バケット内のオブジェクト自体は公開せず、アクセスされたURLを別のURLやドメインにリダイレクトする機能です。
※リダイレクトの場合はパブリックアクセスブロックONにして問題ありません。なので、静的ウェブサイトホスティングが有効になっているから、パブリックアクセスブロックONにできないと判断するのではなく、もう一段確認する必要があります。

実際の作業

上記すべての項目に対して、外部許可する設定が付与されていないことを確認してからパブリックアクセスブロックONにしないといけません。

実際に行った手順
1.パブリックアクセスブロックOFFになっているバケットを洗い出す。
2.静的ウェブサイトホスティングされているか、リダイレクトされているのかどうかを洗い出す。
3.オブジェクトACLを確認する。
4.バケットACLを確認する。
5.バケットポリシーを確認する。
6.全て問題なければ、パブリックアクセスブロックをONにする。

感想

パブリックアクセスブロックOFF→ONが可能か判断するのは手間がかかります😱
誰がどこのS3にオブジェクトをPUTしているかわかっていれば、1オブジェクトACLを確認すれば済みそうですが、各バケット全オブジェクトチェックするのはCLIでもだいぶ時間がかかっていました。
幸い、バケットポリシーほとんど空でしたが、びっしり書かれていたとしたら確認するの大変そうだなーと思います😓

S3の不必要なパブリックアクセス許可はセキュリティ的にクリティカルですし、2023年3月まではデフォルトで許可されていたのを考えると、実は意図せず開けっ放しになっていたということが割とあるのかなーと思います。

PS
CORS設定を忘れていました。(S3パブリックアクセスブロックの文脈ではこの設定を確認する必要はありませんが、アクセス制御機能の一つではあります。)
どのオリジン(ドメイン)からWebブラウザ経由でS3オブジェクトにアクセスできるかを制御するものです。
パブリックアクセスを許可していても、ブラウザ側のセキュリティでデフォルトではアクセスブロックされるので、ブウウザ経由で別ドメインからS3へアクセスさせることを想定している場合は、こちらで適切な設定をする必要があります。
基本的に、ブラウザ→CloudFront→S3みたいな形をとることが多いと思いますが、CloudFrontを経由させずに直接S3にブラウザからアクセスさせるようなケースではCORS設定は必須です。
アクセス制御についてだと、IAM以外に著名付きURLとかもあるんですね、今回は対象外ということで。

Discussion