S3 REST API エンドポイントを CloudFront ディストリビューションのオリジンとして使用すると、「403 Access Denied」エラーが発生する理由を知りたいです
Amazon CloudFront において、Amazon Simple Storage Service (Amazon S3) が返す「403 Access Denied」エラーをトラブルシューティングしたいです。
簡単な説明
「Access Denied」エラーを回避するには、次の構成を使用します。
- S3 オブジェクトへのパブリックアクセスを許可します。
- AWS Key Management Service (AWS KMS) によるサーバー側暗号化が行われたオブジェクトを含む S3 バケットには、オリジンアクセスコントロール (OAC) を使用します。
注: オリジンアクセスアイデンティティ (OAI) では AWS KMS で暗号化されたオブジェクトを扱えないため、OAI ではなく OAC を使用する必要があります。 - S3 バケットポリシーを更新し、s3:GetObject へのアクセスを付与します。
- S3 バケットを所有する AWS アカウントは、オブジェクトの所有者でもある必要があります。
- リクエストされたオブジェクトが S3 バケットに存在することを確認します。
- デフォルトのルートオブジェクトを定義し、クライアントがディストリビューションのルートをリクエストできるようにします。
- OAI の構成では、S3 バケットポリシーに OAI を含める必要があります。OAC の構成では、S3 バケットポリシーに CloudFront サービスプリンシパルを含める必要があります。
解決策
注: AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI で発生したエラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用していることを確認してください。
S3 オブジェクトへのパブリックアクセスを許可する
S3 バケット内のオブジェクトがパブリックアクセス可能かどうかを確認するには、S3 オブジェクトの URL をウェブブラウザで開くか、その URL に対し curl コマンドを実行します。
S3 オブジェクトの URL は、次のような形式です。
**https://DOC-EXAMPLE-BUCKET.s3.amazonaws.com/index.html **
ウェブブラウザまたは curl コマンドから「Access Denied」エラーが返される場合、そのオブジェクトではパブリックアクセスが許可されていません。
オブジェクトをパブリックアクセス可能にするには、次のいずれかの操作を行います。
- バケットに読み取り専用権限を付与するバケットポリシーを作成します。
- S3 コンソールを使用し、オブジェクトに対するパブリック読み取りアクセスを許可します。
- REST API エンドポイントを使用し、ディストリビューションに OAC または OAI を設定します。
- AWS Signature バージョン 4 を使用して S3 へのリクエストを認証します。
AWS KMS で暗号化されたオブジェクトに OAC を使用する
OAC を使用するには、AWS KMS キーポリシーにステートメントを追加し、CloudFront サービスプリンシパルにキーの使用許可を付与します。OAC の代わりに Lambda@Edge を使用することもできます。詳細については、「CloudFront を使用して S3 の SSE-KMS で暗号化されたコンテンツを扱う」を参照してください。
オブジェクトが AWS KMS で暗号化されているかどうかを確認するには、次のいずれかの手順を実行します。
- S3 コンソールを使用してオブジェクトのプロパティを確認します。[暗号化] ダイアログボックスを確認します。AWS KMS が選択されている場合、そのオブジェクトは AWS KMS で暗号化されています。
- head-object コマンドを実行します。コマンドで ServerSideEncryption が aws:kms として返される場合、そのオブジェクトは AWS KMS で暗号化されています。
S3:GetObject へのアクセスを許可する
バケットポリシーに s3:GetObject に対する明示的な Allow ステートメントがある場合も、明示的な Deny ステートメントと競合していないかを確認してください。明示的な Deny ステートメントは、明示的な Allow ステートメントよりも優先されます。Deny ステートメントと Allow ステートメントの詳細については、「ポリシー評価ロジック」を参照してください。
バケットポリシーが s3:GetObject を許可しており、明示的な Deny ステートメントが含まれていないことを確認するには、次の手順を実行します。
-
Amazon S3 コンソールを開きます。
-
目的のバケットを選択します。
-
[アクセス許可] タブを選択します。
-
[バケットポリシー] を選択します。
-
"Action": "s3:GetObject" または "Action": "s3:*" を含むステートメントの有無を確認します。
次のポリシー例には、CloudFront の OAC および CloudFront の OAI に s3:GetObject へのアクセスを付与する Allow ステートメントが含まれます。このポリシーには、s3:GetObject へのパブリックアクセスを付与する Allow ステートメントも含まれます。ただし、s3:GetObject に対する明示的な Deny ステートメントが含まれており、リクエストが特定の Amazon Virtual Private Cloud (Amazon VPC) から送信されない場合、アクセスはブロックされます。{ "Version": "2012-10-17", "Id": "PolicyForCloudFrontPrivateContent", "Statement": [{ "Sid": "Allow-OAC-Access-To-Bucket", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } }, { "Sid": "Allow-OAI-Access-To-Bucket", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EAF5XXXXXXXXX" }, "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ] }, { "Sid": "Allow-Public-Access-To-Bucket", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ] }, { "Sid": "Access-to-specific-VPCE-only", "Effect": "Deny", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": "vpce-1a2b3c4d" } } } ] } -
バケットポリシーを変更し、CloudFront の OAI または OAC、あるいは s3:GetObject へのパブリックアクセスをブロックするステートメントを削除するか、編集します。
注: CloudFront は、「Access Denied」エラーの結果を最長 5 分間キャッシュします。バケットポリシーから Deny ステートメントを削除した後は、ディストリビューションで無効化を実行すると、オブジェクトをキャッシュから削除できます。
S3 バケットとオブジェクトに所有権を付与する
バケットまたはオブジェクトを作成した AWS Identity and Access Management (IAM) アカウントが、そのバケットまたはオブジェクトの所有者であるかどうかを確認します。
注: オブジェクト所有権の要件は、バケットポリシーが付与するアクセスにのみ適用されます。この要件は、オブジェクトのアクセスコントロールリスト (ACL) が付与するアクセスには適用されません。
バケットとオブジェクトの所有者が同じかどうかを確認するには、次の手順を実行します。
-
list-buckets コマンドを実行し、バケット所有者の S3 正規 ID を取得します。
aws s3api list-buckets --query Owner.ID -
list-objects コマンドを実行して、オブジェクト所有者の S3 正規 ID を取得します。
aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix index.html注: 上記のコマンド例では、単一のオブジェクトが表示されます。ただし、list-objects コマンドを実行すると複数オブジェクトを確認できます。
正規 ID が一致しない場合、バケットとオブジェクトの所有者は異なります。
注: Amazon S3 コンソールでバケットとオブジェクトの所有者を確認することもできます。所有者はバケットまたはオブジェクトの [アクセス許可] タブで確認できます。
オブジェクトの所有者をバケットの所有者に変更するには、次の手順を実行します。
-
オブジェクト所有者のアカウントで get-object-acl コマンドを実行し、ACL の権限を取得します。
aws s3api get-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name -
オブジェクトに ACL の権限 bucket-owner-full-control がある場合は、ステップ 3 に進んでください。オブジェクトに ACL の権限 bucket-owner-full-control がない場合は、オブジェクト所有者のアカウントで put-object-acl コマンドを実行します。
aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name --acl bucket-owner-full-control -
バケット所有者のアカウントから、次のコマンドを実行してオブジェクトをコピーし、オブジェクトの所有者を変更します。
aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html s3://DOC-EXAMPLE-BUCKET/index.html --storage-class STANDARD注: --storage-class を実際のストレージクラスに置き換えてください。
オブジェクトをバケットに移動する
オブジェクトがバケット内にあるかどうかを確認するには、head-object コマンドを実行します。
注: S3 オブジェクト名では、大文字と小文字を区別します。CloudFront に送信されたオブジェクトリクエストが S3 オブジェクト名と一致することを確認します。リクエストに正しいオブジェクト名が含まれない場合、Amazon S3 はそのオブジェクトが存在しないと見なす応答を返します。CloudFront が Amazon S3 にリクエストするオブジェクトを識別するには、サーバーアクセスログを使用します。
バケット内にオブジェクトがある場合は、「Access Denied」エラーによって「404 Not Found」エラーがマスキングされることはありません。「Access Denied」エラーを解決するには、他の構成要件を確認します。
オブジェクトがバケット内にない場合は、「Access Denied」エラーにより「404 Not Found」エラーがマスキングされます。欠けているオブジェクトに関連する問題を解決する必要があります。
デフォルトのルートオブジェクトを定義する
デフォルトのルートオブジェクトを定義する方法については、「デフォルトのルートオブジェクトを指定する」を参照してください。
注: セキュリティの観点から、s3:ListBucket へのパブリックアクセスを拒否することをおすすめします。s3:ListBucket へのパブリックアクセスを許可した場合、ユーザーはバケット内のすべてのオブジェクトを閲覧、一覧表示できます。この場合、キーやサイズなどのオブジェクトメタデータの詳細は、すべてのユーザーに公開されます。
S3 バケットポリシーに OAI または CloudFront サービスプリンシパルの権限を追加する
バケットポリシーで OAI が許可されているかどうかを確認するには、Amazon S3 コンソールを開きます。使用するバケットを探し、[アクセス許可] タブの [バケットポリシー] を選択します。
次のポリシー例には、OAC を設定する際の CloudFront サービスプリンシパルに対する Allow ステートメントが含まれます。
{ "Sid": "Allow-OAC-Access-To-Bucket", "Effect": "Allow", "Principal": { "Service": "cloudfront.amazonaws.com" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*", "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } } }
次のポリシー例には、OAI に対する Allow ステートメントが含まれます。
{ "Sid": "1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EAF5XXXXXXXXX" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*" }
CloudFront コンソールでバケットポリシーを更新するには、次の手順を実行します。
- CloudFront コンソールを開きます。
- 目的のディストリビューションを選択します。
- [オリジンおよびオリジングループ] タブを選択します。
- 目的の S3 オリジンを選択し、[編集] を選択します。
- [バケットアクセスの制限] で [Yes] を選択します。
- **[オリジンアクセスアイデンティティ]**で既存の ID を選択するか、新しく ID を作成します。
- [バケットへの読み取り権限の付与] で [はい、バケットポリシーを更新します] を選択します。
- [はい、編集します] を選択します。
関連情報
CloudFront で発生するエラー応答ステータスコードのトラブルシューティング
Amazon S3 が返す 403 Access Denied エラーのトラブルシューティング方法を教えてください
Amazon S3 ウェブサイトのエンドポイントを CloudFront ディストリビューションのオリジンとして使用すると、403 Access Denied エラーが発生する理由を知りたいです
- 言語
- 日本語

