Amazon S3 バケットへのアクセス元を制限する IAM ポリシーを設定する時に、使えるグローバル条件コンテキストキーを調べてみた

2023.06.22

いわさです。

先日、IAM ポリシーを使って Amazon S3 バケットへのアクセスを制御する機会がありました。

制御の方法として IP アドレスや VPC エンドポイントなど様々な方法があるのですが、この時グローバル条件コンテキストキーというやつを使って条件を設定することになると思います。

いくつかよく使うコンテキストキーがあります。
ただ検証してみるとどうやら、どういう構成でどの経路を制御したいかによって使えるもの使えないものがあることがわかりました。

せっかくなので、今回検証した内容をまとめておこうかなと思います。

前提として次のように、いくつかの VPC 上のインスタンスやオンプレミス上のクライアント PC から S3 バケットへアクセスしている場合を想定しており、その中で次の図の中の VPC A の EC2 のみアクセス出来るようにしたいが、どういうパターンの時にどういう方法が取れそうかを考えてみました。

上記であれば次のようなグローバル条件コンテキストキーを使っていない IAM ポリシーを IAM ユーザーや IAM ロールへアタッチしています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::hoge0621bucket",
                "arn:aws:s3:::hoge0621bucket/*"
            ]
        }
    ]
}

この記事では上記に対して無条件にバケットへのアクセス許可された状態から、条件を追加することでどの経路でどうアクセス出来るのかを検証します。
拒否を含むその他のポリシーやバケットポリシーとのは考慮していませんのでご注意ください。

パブリック IP アドレス制限

まずはaws:SourceIpです。
これは使ったことのある方も多いと思いますが、アクセス元の IP アドレスを条件に追加します。
次の場合であれば設定された IP アドレスの場合にこのアクションが許可されます。

aws:SourceIp

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::hoge0621bucket",
                "arn:aws:s3:::hoge0621bucket/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "18.177.76.124",
                        "52.195.95.181"
                    ]
                }
            }
        }
    ]
}

使いやすいのですが注意点があって、ここで指定する IP アドレスはパブリック IP アドレスです。
EC2 のプライベート IP アドレスを指定出来ないという点と、NAT Gateway などを使ってアウトバウンド通信の出口を構成している場合は NAT Gateway のパブリック IP アドレスとなります。

VPC A の NAT Gateway のパブリック IP アドレスを指定すると、次のようにそれ以外の経路からのアクセスはできなくなります。

アクセスキーでもインスタンスプロファイルでも使えます。

VPC エンドポイント制限

次はaws:SourceVpceaws:SourceVpcです。
これらは VPC エンドポイントを使うプライベート通信の経路を使った時にどこからのアクセスを許可するか制御することが出来ます。

aws:SourceVpceの場合は VPC エンドポイントの ID を指定します。

aws:SourceVpce

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::hoge0621bucket",
                "arn:aws:s3:::hoge0621bucket/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:SourceVpce": "vpce-0eaa74487a4765447"
                }
            }
        }
    ]
}

VPC エンドポイント A の ID を指定した場合は次のように VPC エンドポイント A 経由の通信のみが許可されます。
こちらについてもアクセスキーとインスタンスプロファイルどちらも使うことが出来ます。

aws:SourceVpcの場合は VPC エンドポイント ID ではなく次のように VPC ID を指定します。

aws:SourceVpc

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::hoge0621bucket",
                "arn:aws:s3:::hoge0621bucket/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:SourceVpc": "vpc-0283aed9667fba81d"
                }
            }
        }
    ]
}

ただしこの場合は、VPC であればどの通信でも良いわけではなく VPC エンドポイント経由のリクエストでのみ利用可能なので、実態としては VPC エンドポイントによる制限に近いです。
このキーは VPC に複数のエンドポイントが指定されている場合に VPC 単位で指定することが想定されているようです。

VPC ID であれば経路を問わず許可したい場合は次のaws:Ec2InstanceSourceVpcを使うことが出来ます。

VPC 制限

aws:Ec2InstanceSourceVpcは今回初めて使いました。
こちらも先程のaws:SourceVpcと似ていて VPC ID を指定します。

aws:Ec2InstanceSourceVpc

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::hoge0621bucket",
                "arn:aws:s3:::hoge0621bucket/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:Ec2InstanceSourceVpc": "vpc-0283aed9667fba81d"
                }
            }
        }
    ]
}

aws:SourceVpcとの相違点ですが、これは対象 VPC からの通信であればパブリックとプライベートどちらも対象となります。
そのため次のように VPC エンドポイントを使う場合でも使わない場合でもこの条件を使うことが出来ます。

注意点とし、このキーはインスタンスプロファイルを使って Assume Role された時しか使うことが出来ません。
そのためアクセスキーを使って IAM ユーザーでアクセスする場合はこのキーが利用出来ません。

さいごに

本日は Amazon S3 バケットへのアクセス元を制限する IAM ポリシーを設定する時に、使えるグローバル条件コンテキストキーを調べてみました。

いくつか似たようなキーが存在しますが、通信経路がインターネットなのか VPC エンドポイントなのか、アクセスキーなのかインスタンスプロファイルなのかで使えるキーが異なってきます。
選択する際にはアーキテクチャー構成にあわせた選択が必要なので気をつけましょう。