share facebook facebook2 twitter menu hatena pocket slack

2015.02.17 TUE

S3で他人のディレクトリの中身が一切見れない、IAMの作り方

WRITTEN BY今岡 久敏

こんにちは、cloudpack今岡 です。

Amazon S3IAMと組み合わせることにより、ファイルサーバ(Windowsの共有的な)のような構成を組むことも可能です。先にいうと、バケット単位での設定は結構簡単ですが、バケットは同じ、ディレクトリで分離という方法をなんとかします。

やりたいこと

目指すはコモンセンス(と私が思う)Windowsの共有です。 バケットは1つ、その中にディレクトリが2つあり、片方にはアクセスできるが、片方にはファイルの読み書きは無論、ディレクトリ内のファイル一覧も見れないように設定したい。
S3で他人のディレクトリの中身が一切見れない、IAMの作り方

知っておいたほうがいいこと

S3に実はディレクトリはない

KVSと言って良いです。各オブジェクト(Value)に、ファイルパス(Key)が付いていると理解します。後々この概念が無いと理解出来ません。

ListAllMyBucketはほぼ必須

この権限は、自分(AWSアカウント)の持っているバケットを全部見せる権限です。S3のGUIブラウザ CloudBerryとかを使うならば、この設定をしておかないと、いきなりエラーが出たりします。ログイン後のディレクトリ&バケットを指定できるGUIツールの場合は、必須ではありません。この権限はあくまでバケット一覧を見せるだけで、バケットの中身は見れません。

Deny > Allow > 設定なし(Deny)

覚えておきましょう。一旦Allowで許してもDenyでかき消せるということです。ただし今回の設定では使いません。

リソース絞り or S3:Prefix絞り

IAMの設定では、arn:で始まるリソースで絞るか、Condition & s3:prefixで絞るかになりますが、どっちでもいいわけではなく、使い分けが必要です。下記の例では、バケットのトップディレクトリに対してListBucketを許していますが、これをConditionを使わずリソースだけでやってしまうと、バケット全体という意味になってしまいます。特にActionによっては、Conditionでないとマズイものもあるので、Actionに応じてどちらにするかを決めましょう。

設定例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<your bucket>"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:prefix": [
                        ""
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<your bucket>"
            ],
            "Condition": {
                "StringLike": {
                    "s3:prefix": [
                        "B/*"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::<your bucket11>/B/*"
            ]
        }
    ]
}

説明

最初のListAllMyBucket

これは前述の通り。まあ必須です。

最初のListBucket

ListBucketはバケットの中身をList(lsやdir)できる権限。ここでいきなりCondition s3:prefixを使います。他所で書かれているのは、ここでCondtionを使わないでリソースだけで絞ってあるため、Aの中身もList出来てしまうという話が多いです。それに対し、 Condition s3:prefix = "" を指定することにより、明示的にバケット名直下のディレクトリに対してListできるように指定します。

2番めのListBucket

今度は本当にアクセスできるB/ディレクトリに対してListが効くようにします。

最後のPut,Get,Delete…

ここで実際にファイルの読み書きを設定します。

Denyを使う場合

上記のListBuckets3:prefixで絞らず、Denyを後付して権限を奪う方法もありますが、例えばアクセスさせたくないディレクトリが増えた場合、その都度Denyルールを追記する必要があります。Groupで管理しても、これは結構大変です。なので、なるべくDenyを使わない方法にこだわった。

他に気になること

今回はバケット直下にディレクトリがある想定ですが、深い階層のディレクトリにこれをやろうとすると、考えないといけないっすね。。

元記事はこちらです。
S3で他人のディレクトリの中身が一切見れない、IAMの作り方

今岡 久敏

「常に新しいモノの方が、古いモノより優れている、というマインドを持てなくなった時、それはエンジニアとしての死を意味する」え、誰の言葉だって?俺の言葉だよ。