カルキチブログ

S3の403 Access Deniedを解決する時の覚書

S3の403エラーでオブジェクトにアクセスできなくなるたびにググってる気がするので、いい加減にちゃんと理解するためにこの問題の発生原因と解決方法についてまとめてみました。

S3の403 Access Deniedが発生する原因

403は認証エラーが発生していることを意味するステータスコードです。

つまり、S3のバケットやオブジェクトのアクセス権限が不足している時にこの問題は発生します。

閲覧権限が付与されていないS3オブジェクトにアクセスするとこのような画面が表示されます。

確認すべき項目と解決方法

権限が足りないことが原因で発生している問題なので、適切な権限を付与してあげればこの問題は解決することができます。

※全公開しても構わないファイルならそこまで神経質になる必要はありませんが、秘匿情報が含まれているバケットでこれ以降解説している内容を試すのは危険です。

ブロックアクセスリストをチェックする

まずチェックすべきは、ブロックアクセスリストにチェックがついていないかどうかです。

ブロックアクセスリストを確認するためには、オブジェクトのアクセス許可をクリックします。

アクセス許可をクリックして、ブロックパブリックアクセス (バケット設定)の下部にある編集ボタンをクリックします。

編集ボタンをクリックすると以下のような画面が表示されるので、全てのチェックを外して保存しましょう。

全てのチェックを外すと何が起きるかというと、S3のバケット内のオブジェクトへのアクセスを有効にするために必要なアクセスコントロールリスト (ACL)、バケットポリシー、アクセスポイントポリシーどの方法でもS3のバケット内のオブジェクトへアクセスすることが可能になります。

以下公式に記述されていた文章の引用です。

パブリックアクセスは、アクセスコントロールリスト (ACL)、バケットポリシー、アクセスポイントポリシー、またはそのすべてを介してバケットとオブジェクトに許可されます。すべての S3 バケットおよびオブジェクトへのパブリックアクセスが確実にブロックされるようにするには、[パブリックアクセスをすべてブロック] を有効にします。

引用: Amazon S3 ストレージへのパブリックアクセスのブロック

バケットポリシーが適切に設定されているか確認する

ブロックパブリックアクセスのチェックが全て外れていてもアクセスできない場合は、バケットポリシーが適切に設定されているか確認してみましょう。

バケットポリシーとはAWSのポリシーの一種で、バケットとその中のオブジェクトへのアクセス許可を付与できる権限設定のことです。

バケットポリシーはアクセス許可から編集することができ、権限の設定はJSONで記述する必要があります。

以下のように記述すると、バケットポリシーを設定したS3バケット内のオブジェクトに全てアクセスできるようになります。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{バケットの名前}/*"
        }
    ]
}

VersionはIAMポリシーの文法のバージョンなので、2012-10-17と記述します。

→長いこと変わっていないらしいです。

Statementの中の各項目には以下のような意味があるようです。

  • Statement.Sid・・・ポリシードキュメントに与える任意の識別子。ポリシー内で固有だったら大文字 (A〜Z)、小文字 (A〜Z)、数字 (0〜9)だったらなんでもいい。
  • Statement.Effect・・・ステートメントの結果を許可(Allow)または明示的な拒否(Deny)のどちらにするかを指定する。指定は必須。
  • Statement.Principal・・・どの相手(Principal)に対して許可ないし拒否するかを指定する。
  • Statement.Action・・・許可ないし拒否するアクションを指定する。(s3:GetObjectだと読み込みのみ許可)
  • Statement. Resource・・・一連のステートメントをどのリソースに反映するかを指定する。

バケットポリシーのStatement.Actionで指定可能なアクションは4種類あります。

  • s3:GetObject・・・読み込み
  • s3:PutObject・・・書き込み
  • s3:DeleteObject・・・削除
  • s3:ListBucket・・・オブジェクト一覧の確認

より詳細な情報が気になる方は、公式ドキュメントを確認してみてください。

S3のバケットポリシーはデフォルトでは全拒否となっているので、こいつが有効になっていないとブロックアクセスリストのチェックが全て外れていてもS3のオブジェクトにアクセスすることはできません。

また、バケットポリシーは特定のオブジェクトのみアクセスできるようにすることも可能です。

ポリシー内のResourceにオブジェクトの指定まで含めることで特定のオブジェクトのみアクセス制御を行うことができます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicRead",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::mybucket/test1/hoge.txt",
                "arn:aws:s3:::mybucket/test1/fuga.html"
            ]
        }
    ]
}

バケットポリシーが設定されていない場合はACLの設定を確認する

S3ではバケットポリシー以外に、アクセスコントロールリスト (ACL)でもオブジェクトのアクセス許可を付与することができます。

ACLはアクセス許可のオブジェクト所有者から有効にすることができます。

ACLを有効にした後はアクセス許可したいオブジェクトの画面に移動して、アクセス許可をクリックします。

編集をクリックして、全員(パブリックアクセス)の読み込みにチェックを付けると、バケットポリシーを設定しなくてもS3のオブジェクトにアクセスできるようになります。

バケットポリシーとACLの違い

バケットポリシーとACLはどちらもアクセス制御ができる点は同じですが、以下の点が異なっているらしいです。

  • バケットポリシー・・・バケットに対してアクセス権限を設定するためのもの。
  • ACL・・・バケット内のオブジェクト単位でアクセスアクセス権限を設定するためのもの。

どちらを使ったほうがいいかですが、ACLはバケットポリシーでDenyポリシーが設定されていた場合、バケットポリシーの拒否が優先されるのと、個別に許可と拒否を設定するくらいなら、そもそもバケットを分けてしまった方が管理が楽になるケースが多いため、基本的にはバケットポリシーを用いてアクセス制限を行なった方がいいらしいです。

参考: https://www.ctc-g.co.jp/solutions/cloud/column/article/16.html

個人の見解ですが、設定自体はACLの方が直感的でわかりやすいので、簡易的にアクセス制御を施したい場合はACLでもいいのかなと考えました。

まとめ

まとめです。

  • S3の403 Access Deniedが発生する原因は権限が付与されていないから。
  • 権限の付与は、バケットポリシーかACLで付与することができる。
  • どちらもアクセス制御ができる点は同じだが、両方設定されていた場合はバケットポリシーの方が優先されるのと、個別に許可・拒否を設定するくらいなら別でバケットを分けた方がいいので、バケットポリシーで制限をかけた方がいい。

今回の本筋とは外れますが、バケットのアクセス制限をIAMユーザーやグループレベルで制限したい時はIAMポリシーを使う必要があるそうです。

参考: https://qiita.com/K5K/items/ef6a02aee760b128a25b

おまけ

クラウド周りマジで苦手なので、もうちょいできるようになりたい。