S3パブリックアクセス拒否の原因と解決策:バケットレベルの「Block Public Access」が優先される仕組み
S3に画像をアップロードしてオブジェクトACLを「public-read」に設定したのに、URLにアクセスすると「Access Denied」が返ってくる。オブジェクト単体の設定は正しいはずなのに、なぜ拒否されるのか——この問題の原因はほぼ確実に、バケットレベルの「Block Public Access」設定にある。オブジェクトACLより上位のレイヤーが存在することを知らないと、何度設定を変えても解決しない。
TL;DR:S3パブリックアクセス拒否の原因まとめ
| 確認レイヤー | 設定項目 | 影響範囲 |
|---|---|---|
| アカウントレベル | S3 Block Public Access(アカウント全体) | 全バケットに適用 |
| バケットレベル | S3 Block Public Access(バケット個別) | そのバケット内の全オブジェクト |
| バケットポリシー | Principal: * を許可するポリシーの有無 | ポリシーで指定したリソース |
| オブジェクトACL | public-read ACL | 個別オブジェクト |
結論:オブジェクトACLを「public-read」にしても、バケットまたはアカウントレベルの「Block Public Access」が有効な場合、そのACLは無効化される。上位レイヤーの設定が下位を上書きする構造になっている。
S3パブリックアクセス制御の仕組み:なぜオブジェクトACLだけでは不十分か
S3のアクセス制御は複数のレイヤーが重なって機能する。オブジェクトACLはその中で最も下位のレイヤーに位置する。AWSは2018年以降、誤ったパブリック公開によるデータ漏洩を防ぐため「Block Public Access」という上位の制御機構を導入した。この設定が有効な場合、オブジェクトACLやバケットポリシーで「public」を許可しようとしても、Block Public Accessがそれを遮断する。
Block Public Accessには4つの独立した設定項目がある。それぞれが異なるシナリオをカバーしており、全部オフにしないとパブリックアクセスが通らないケースもある。
- アカウントレベルのBlock Public Access:全バケットに適用される最上位の制御。ここが有効だと個別バケットの設定に関わらずブロックされる。
- バケットレベルのBlock Public Access:そのバケット内の全オブジェクトに適用。アカウントレベルがオフでもここが有効なら拒否される。
- バケットポリシー評価:Block Public Accessが無効の場合のみ評価される。Principal: * を許可するポリシーが必要。
- オブジェクトACL評価:Block Public Accessが無効で、かつACLが有効化されている場合のみ機能する。
Block Public Accessは「安全装置」のようなものだ。オブジェクトACLというトリガーを引いても、安全装置がかかっていれば発射されない。安全装置を外す操作とトリガーを引く操作は別々に行う必要がある。
S3パブリックアクセス拒否の診断手順
ステップ1:アカウントレベルのBlock Public Access状態を確認する
オブジェクトやバケットの設定を見る前に、まずアカウント全体の設定を確認する。ここが有効なら、それ以降の診断は意味をなさない。アカウントレベルの設定はAWS CLIで以下のように取得できる。
aws s3control get-public-access-block \
--account-id 123456789012
レスポンス例:
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}
いずれかの項目がtrueの場合、その項目が何をブロックしているかを理解した上で対処する必要がある。4つの項目の意味は次のとおり。
| 設定項目 | ブロック対象 |
|---|---|
| BlockPublicAcls | 新規のパブリックACL設定をブロック |
| IgnorePublicAcls | 既存のパブリックACLを無視(無効化) |
| BlockPublicPolicy | パブリックアクセスを許可するバケットポリシーの設定をブロック |
| RestrictPublicBuckets | パブリックポリシーが設定されたバケットへのアクセスをAWSサービスと認証済みユーザーのみに制限 |
ステップ2:バケットレベルのBlock Public Access状態を確認する
アカウントレベルがオフでも、バケット個別の設定が有効な場合がある。バケット作成時のデフォルトは全項目trueなので、明示的にオフにしていなければブロックされたままになる。
aws s3api get-public-access-block \
--bucket your-bucket-name
パブリックアクセスを許可するには、このバケットのBlock Public Accessを無効化する必要がある。
ステップ3:バケットレベルのBlock Public Accessを無効化する
アカウントレベルとバケットレベルの両方の設定がパブリックアクセスをブロックしていないことを確認した上で、バケットの設定を変更する。本番環境では影響範囲を十分に確認してから実行すること。
aws s3api put-public-access-block \
--bucket your-bucket-name \
--public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
変更後、再度get-public-access-blockで設定が反映されていることを確認する。
ステップ4:バケットポリシーでパブリックアクセスを許可する(推奨アプローチ)
Block Public Accessを無効化した後、オブジェクトACLではなくバケットポリシーでパブリックアクセスを制御する方法が現在のAWSの推奨に近い。ACLはレガシーな仕組みであり、新規バケットではデフォルトで無効化されている(Object Ownershipの設定による)。
バケットポリシーで特定バケット内の全オブジェクトへのGetObjectを許可する例:
🔽 バケットポリシーのJSONを展開
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
aws s3api put-bucket-policy \
--bucket your-bucket-name \
--policy file://bucket-policy.json
ステップ5:Object Ownershipの設定を確認する
2023年以降に作成されたバケットでは、Object Ownershipがデフォルトで「Bucket owner enforced」に設定されており、この場合ACLは完全に無効化される。オブジェクトACLを使おうとしている場合、この設定が原因でACLが機能しないことがある。
aws s3api get-bucket-ownership-controls \
--bucket your-bucket-name
レスポンスにBucketOwnerEnforcedが返ってきた場合、ACLは使用できない。パブリックアクセスにはバケットポリシーを使用すること。
実際の現場で起きた誤診パターン
「オブジェクトのプロパティを見たら『パブリック』と表示されているのに、URLにアクセスすると403が返ってくる」という問い合わせは珍しくない。コンソールのオブジェクト詳細画面でACLが「public-read」になっていることを確認して、設定は正しいと判断してしまう。
実際の原因はバケットレベルのIgnorePublicAcls: trueだった。この設定が有効な場合、ACLの値がどう設定されていても、S3はそのACLを評価しない。コンソール上でACLが「public-read」と表示されていることは事実だが、それが実際のアクセス制御に反映されているかどうかは別の話だ。
ACLの設定値と、そのACLが実際に評価されるかどうかは独立した状態として管理されている。これを混同すると診断が迷走する。
最小権限の原則:パブリック公開が本当に必要か再考する
S3オブジェクトをパブリックに公開する前に、本当にそれが必要かを確認する。多くのユースケースでは、以下の代替手段がより安全だ。
| ユースケース | 推奨アプローチ |
|---|---|
| 一時的なファイル共有 | S3 Presigned URLを使用(有効期限付き) |
| Webサイトの静的コンテンツ配信 | CloudFront + OAC(Origin Access Control)でS3をプライベートに保つ |
| アプリケーションからのアクセス | IAMロールを使用し、パブリックアクセスは不要 |
| 完全なパブリック公開が必要 | Block Public Accessを無効化 + バケットポリシーで制御 |
S3パブリックアクセス拒否の解決:まとめと次のステップ
S3のパブリックアクセス拒否は、オブジェクトACLの設定だけを見ていても解決しない。アクセス制御の評価はアカウントレベル→バケットレベル→バケットポリシー→オブジェクトACLの順に行われ、上位レイヤーが下位を上書きする。Block Public Accessはその最上位に位置する安全装置であり、意図的に無効化しない限り機能し続ける。
診断の起点は常にアカウントレベルのBlock Public Access確認から始めること。その後バケットレベル、Object Ownership、バケットポリシーの順に確認することで、原因を体系的に特定できる。
関連する公式ドキュメントとして、Amazon S3 Block Public Accessの使用およびオブジェクト所有権の制御を参照すること。
用語集
| 用語 | 説明 |
|---|---|
| Block Public Access | S3バケットおよびオブジェクトへのパブリックアクセスをアカウントまたはバケットレベルで制御するAWSの機能。ACLやバケットポリシーより上位で機能する。 |
| オブジェクトACL(Access Control List) | 個別のS3オブジェクトに対するアクセス権限を定義するリスト。Block Public Accessが有効な場合は無視される。 |
| Object Ownership | S3バケット内のオブジェクトの所有権とACLの有効/無効を制御する設定。'Bucket owner enforced'の場合、ACLは完全に無効化される。 |
| Presigned URL | 特定のS3オブジェクトへの一時的なアクセスを許可するURL。有効期限と署名が含まれており、バケットをパブリックにせずにファイルを共有できる。 |
| Origin Access Control(OAC) | CloudFrontからS3バケットへのアクセスを制御する仕組み。S3バケットをプライベートに保ちながらCloudFront経由でコンテンツを配信できる。 |
コメント
コメントを投稿