LoginSignup
7
0

More than 3 years have passed since last update.

S3のパブリック公開はパブリックじゃない時もあるから気をつけろ!

Last updated at Posted at 2019-12-24

この投稿はGlobal Mobility Serviceのアドベントカレンダーの25日目です。

AWSでの今年の失敗を振り返りたいと思います。
S3のパブリック公開でやらかしました。

要約

S3のバケットポリシーによるパブリック公開はオブジェクトの権限によってパブリックじゃない時もあるので気をつけよう

失敗について

失敗までの経緯

S3のパブリック公開を調べてみると公式ドキュメントで以下の内容が見つかります。

匿名ユーザーへの読み取り専用アクセス許可の付与

次のポリシー例では、任意のパブリック匿名ユーザーに s3:GetObject アクセス許可を付与します。(これによって許可されるアクセスとオペレーションの一覧については、「ポリシーでのアクセス許可の指定」を参照してください。) このアクセス許可はオブジェクトデータを誰でも読み取り可能にするので、バケットをウェブサイトとして設定し、バケット内のオブジェクトをすべての人が読み取れるようにする場合に便利です。

これを見て、以下のようなバケットポリシーをパブリック公開したいバケットに設定しておけば大丈夫と思ってしまいました。

パブリック公開のバケットポリシー例
{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"PublicRead",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/*"]
    }
  ]
}

ちなみに、このバケットポリシーを設定するとAWSコンソール上でパブリックであることがアピールされるので、なんとなくこれで大丈夫だと思ってしまいます。

スクリーンショット 2019-12-23 16.10.53.png

失敗したケース

普段利用しているAWS環境はマルチアカウントになっています。
本ケースでは、以下のように別アカウント間でS3にオブジェクトを配置するという流れでした。
S3パブリック公開失敗例図 (2).png

BアカウントからAアカウントのバケットにPutObjectするのに、以下のようなバケットポリシーを適用しました。
特定のロールにPutObjectを許可するポリシーです。

パブリック公開と別アカウントからPutObjectを許可するバケットポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::hi1280-public/*"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::012345678901:role/AAccountAccessRole"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::hi1280-public/*"
        }
    ]
}

あとは、Bアカウントの環境からAWS CLIを使ってPutObjectをするだけの簡単なお仕事だと思って、オブジェクトを配置して安心していました。
が、のちに公開したはずのオブジェクトが見れないという連絡が来て焦りました。

実はこのようなケースの場合、PutObjectでオブジェクトを置いてもパブリック公開されません。
その当時は全く見ていなかったのですが、公式ドキュメントにちゃんと書かれていました。

注記
バケットとオブジェクトの所有者が同じ場合、オブジェクトへのアクセスは、バケットコンテキストで評価されるバケットポリシーで許可することができます。

つまり、バケットポリシーのみでパブリック公開できるのは、バケットが存在するAWSのアカウントと同じユーザやロールがオブジェクトを配置した時のみでした。

どうすれば良いのか

さらにこのような記述があります。

所有者が異なる場合、オブジェクトの所有者はオブジェクト ACL を使用してアクセス許可を付与する必要があります。

AWSのアカウントが異なる場合は、オブジェクトを配置したユーザやロールがACLでオブジェクトに対してアクセス権限を付与しなければいけなかったのです。

AWS CLIを使う場合、以下のコマンドです。

$ aws s3api put-object-acl --bucket bucket-name --key my_object --acl public-read

これで無事にオブジェクトをパブリック公開することができます。

まとめ

油断大敵。確認を怠らないようにしなければと思いました。
皆様におかれましては、このような失敗が起きないようにS3におけるアクセス権限には十分にお気をつけください。

おわりに

AWSはやっぱりよく分からないので色々学びあえるエンジニアを募集しています。

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0