VPCエンドポイントポリシーの運用について本気出して考えてみた

記事タイトルとURLをコピーする

おはこんばんちは!
クラウドインテグレーション部の山本です
乃木坂46 と 山登り と サウナが好きです
愛してます

今日は「VPC エンドポイントポリシー」についてです

VPCエンドポイントポリシーとは?

VPCエンドポイントに付けるポリシーです
そのVPCエンドポイントを利用して操作可能なリソースを制限します
例えば S3 のVPCエンドポイントに付ける VPC エンドポイントポリシーに 「バケット:Bucket-AAAA へのアクセス許可」のみを記述します(※1)

  • ※1
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Principal": "*",
              "Action": "*",
              "Resource": [
                  "arn:aws:s3:::Bucket-AAAA/*",
                  "arn:aws:s3:::Bucket-AAAA"
              ]
          }
      ]
  }

IAMユーザーに「バケット:Bucket-BBBB へのアクセス許可」を持つポリシー(※2)を付与します

  • ※2
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "s3:PutObject",
              "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::Bucket-BBBB/*"
        }
    ]
}

※2 の権限を持つ IAM ユーザーが ※1 のVPCエンドポイントポリシーを持つ VPC エンドポイントを利用するときにはバケット:Bucket-BBBB に対する操作はできません
VPCエンドポイントポリシーでは バケット:Bucket-AAAA に対する操作のみを許可しているためです

3行まとめ:
VPCエンドポイントポリシーを使うと VPCエンドポイントを利用する IAM ユーザー や IAM ロールに想定外の権限があってもVPCエンドポイントでアクセス拒否をすることができます
厳重なセキュリティが必要な環境においては二重の防護策となります
しかし IAM と VPCエンドポイントポリシーで二重管理をすることにもなってしまうため運用管理が煩雑になるという側面もあります( VPCエンドポイントポリシーによる制御が必要かどうかは慎重に検討が必要です )

補足 (参考までに細かい仕様を記載)

出典:Use VPC endpoint policies

  • VPCエンドポイントポリシーを指定せずに VPCエンドポイントを作成した際には すべてのリソースに対するすべての操作を許可するポリシーが付いています
 {
    "Statement": [
        {
            "Action": "*",
            "Effect": "Allow",
            "Resource": "*",
            "Principal": "*"
        }
    ]
}
  • ポリシーはいつでも変更できます
    • ポリシーを変更した場合、変更が有効になるまでに数分かかります
  • ポリシーの記述方法の詳細については、『IAMユーザーガイド』の「IAMでのポリシーとアクセス許可」を参照してください

  • 他のIAMポリシーと同じようにポリシーを記述することができるものの、次の点に注意してください

    • ポリシーにはプリンシパル要素が含まれている必要があります
    • エンドポイントポリシーのサイズは、20,480文字(空白を含む)を超えることはできません。
    • VPCエンドポイントポリシーをサポートするAWSサービスの詳細については、AWS services that integrate with AWS PrivateLink を参照してください
  • ゲートウェイエンドポイントに適用するVPCエンドポイントポリシーの場合は以下の注意点があります

    • プリンシパルを "AWS":"アカウント番号" または "AWS":"arn:aws:iam::アカウント番号:root" の形式で指定すると、アクセスは AWSアカウントのrootユーザーにのみ許可されます
      • アカウントのすべてのIAMユーザーとロールに許可されるわけではありません
      • Principal要素にAmazonResource Name(ARN)を指定すると、ポリシーが保存されるときにARNが一意のプリンシパルIDに変換されます。

VPCエンドポイントポリシーの運用を始める前に考えたほうが良いこと

運用する環境の VPCエンドポイントに どんな VPCエンドポイントポリシーを書いたら良いか整理する

  1. VPCエンドポイントを利用する IAM リソースを整理
  2. 1の IAM リソース が VPCエンドポイントを利用して操作する対象のリソースや実行する操作を整理 (例として S3のエンドポイントなら 対象の S3バケット名や Put / Get などの操作を整理)

1,2 を整理すると どんな VPCエンドポイントポリシーを書いたら良いかなんとなく見えてきます

VPCエンドポイントを利用して操作するリソースのリソース側における制御

リソース側で「特定のVPCエンドポイントのみからの操作を許可する」リソースベースのポリシーを記述できる場合があります
例として、API Gateway には API毎にリソースポリシーがあり「特定のVPCエンドポイントのみからの操作を許可する」設定が可能です

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-xxxx"
                }
            }
        }
    ]
}

VPCエンドポイントポリシーを利用した制御の例

いくつかのサービスについて例を示してみます
私の手元にて検証を行い動作したものです

前提として
EC2 に付けた IAM Role (インスタンスプロファイルrole-for-ec2) から VPCエンドポイント(vpce-xxxx)を利用して同じAWSアカウントにある各サービスの各リソースを操作します ※各リソース名はサンプルにしています
最大限に制御をするにはどうしたらよいか?という観点で検証しました

運用管理が煩雑になるという側面もあるため本当に必要な制御かは環境ごとに慎重に検討が必要です

ECR

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.ecr.dkr
  • エンドポイントの用途

  • 制御内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーで許可(Allow)する Principal と Action, Resource を定義する
    • ECRのリポジトリポリシーで該当のVPCエンドポイントを経由しない操作をDenyする
  • 制御の例

    • role-for-ec2
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "ecr:BatchGetImage",
              "ecr:PutImage"
            ],
            "Resource": "arn:aws:ecr:ap-northeast-1:123456789012:repository/repository-name"
        }
    ]
}
{
    "Statement": [{
        "Sid": "0",
        "Principal": {
            "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
        },
        "Action": [
      "ecr:BatchGetImage",
      "ecr:PutImage"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:ecr:ap-northeast-1:123456789012:repository/repository-name"
    }]
}
  • ECRのリポジトリポリシー
    • 例外として 該当のVPCエンドポイントを使わない環境にいる ユーザー (hogehoge01@fugafuga) の操作を許可する (NotPrincipal 内)
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "0",
      "Effect": "Deny",
      "NotPrincipal": {
        "AWS": [
          "arn:aws:iam::123456789012:root",
          "arn:aws:iam::123456789012:user/hogehoge01@fugafuga"
        ]
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:PutImage"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": "vpce-xxxxxxx"
        }
      }
    }
  ]
}

API Gateway

{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "execute-api:Invoke"
            ],
            "Resource": "arn:aws:execute-api:ap-northeast-1:123456789012:リソースID/*"
        }
    ]
}
{
    "Statement": [
        {
            "Principal": "*",
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:execute-api:ap-northeast-1:123456789012:リソースID/*"
            ]
        }
    ]
}
  • リソースポリシーの設定
    • 留意点:API Gatewayリソースポリシーの例
      • API Gateway コンソールを使用してデプロイ済み API にリソースポリシーをアタッチする場合、または既存のリソースポリシーを更新する場合、変更を有効にするにはコンソールの API を再デプロイする必要があります
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}

S3

  • VPCエンドポイントのタイプ

    • ゲートウェイ型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.s3
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する Action, Resource を定義する
      • ※ ゲートウェイ型 のエンドポイントにおいて Principal は意図した動作をしないことがあるため制御しないことにした
    • バケットポリシーにて該当のVPCエンドポイントを経由しない指定ActionをDenyする
      • ※ Action を * にすると バケットポリシーを編集できなくなる点に注意
  • 制御の例

    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "s3:PutObject",
              "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::s3-example/*"
        }
    ]
}
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "*",
            "Resource": [
                "arn:aws:s3:::s3-example/*",
                "arn:aws:s3:::s3-example"
            ]
        }
    ]
}
{
    "Version": "2012-10-17",
    "Id": "Policy1415115909152",
    "Statement": [
        {
            "Sid": "Access-to-specific-VPCE-only",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
              "s3:PutObject",
              "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::s3-example",
                "arn:aws:s3:::s3-example/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-xxxx"
                }
            }
        }
    ]
}

SNS

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.sns
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する Action, Resource, Principal を定義する
    • Access policy にて 対象となるResource を定義し 通信元のVPCエンドポイント以外からの指定のActionを制限(Deny)する
  • 制御の例

    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "sns:Publish"
            ],
            "Resource": "arn:aws:sns:ap-northeast-1:123456789012:Topic名"
        }
    ]
}
{
  "Statement": [{
    "Action": ["sns:Publish"],
    "Effect": "Allow",
    "Resource": "arn:aws:sns:ap-northeast-1:123456789012:Topic名",
    "Principal": {
      "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
    }
  }]
}
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "SNS:Publish",
      "Resource": "arn:aws:sns:ap-northeast-1:123456789012:Topic名",
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": "vpce-xxxx"
        }
      }
    }
  ]
}

SQS

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.sqs
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する対象の Action, Resource, Principal を定義する
    • キューポリシーにて該当のVPCエンドポイントを経由しない指定ActionをDenyする
  • 制御の例

    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "SQS:GetQueueUrl"
            ],
            "Resource": "arn:aws:sqs:ap-northeast-1:123456789012:キュー名"
        }
    ]
}
  • vpce-xxxxのポリシー
{
  "Statement": [{
    "Action": ["SQS:GetQueueUrl"],
    "Effect": "Allow",
    "Resource": "arn:aws:sqs:ap-northeast-1:123456789012:キュー名",
    "Principal": {
      "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
    }
  }]
}
  • キューポリシー
{
  "Version": "2008-10-17",
  "Id": "1",
  "Statement": [
    {
      "Sid": "1",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "SQS:GetQueueUrl",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpce": "vpce-xxxx"
        }
      }
    }
  ]
}

DynamoDB

  • VPCエンドポイントのタイプ

    • ゲートウェイ型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.dynamodb
  • エンドポイントの用途

    • DynamoDBのテーブルへの操作
    • ゲートウェイ型のVPCエンドポイントであるためプリンシパルを "AWS":"AWS-account-ID" または "AWS":"arn:aws:iam::AWS-account-id:root" の形式で指定するとアクセスはAWSアカウントのrootユーザーにのみ許可されます
      • アカウントのすべてのIAMユーザーとロールに許可されるわけではありません
  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する Action と Resource を定義する ※ ゲートウェイ型 のエンドポイントにおいて Principal は意図した動作をしないことがあるため制御しない
    • DynamoDB にリソースベースのポリシーはない 2021-06-03 時点
  • 制御の例

    • 前提
      • EC2よりアタッチされたIAMロール(role-for-ec2)でテーブルを参照する
      • EC2の所属するVPCにはDynamoDBのVPCエンドポイント(vpce-xxxx)が存在する
    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "dynamodb:DescribeTable"
            ],
            "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/テーブル名"
        }
    ]
}
  • VPCエンドポイントポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "dynamodb:DescribeTable",
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:123456789012:table/テーブル名"
            ]
        }
    ]
}

EC2

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.ec2
    • com.amazonaws.ap-northeast-1.ec2messages
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する対象のPrincipal を定義する
    • EC2 にリソースベースのポリシーはない 2021-06-03 時点
  • 制御の例

    • 前提
      • エンドポイントが2つあるため代表して com.amazonaws.ap-northeast-1.ec2 のエンドポイントを例示
    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "ec2:CreateImage"
            ],
            "Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance/インスタンスID"
        }
    ]
}
  • VPCエンドポイントポリシー
{
  "Statement": [{
    "Action": ["ec2:CreateImage"],
    "Effect": "Allow",
    "Resource": "*",
    "Principal": {
      "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
    }
  }]
}

CloudWatchLogs

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.logs
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action と Resource を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する Action と Resource, Principal を定義する
    • CloudWatchLogs にリソースベースのポリシーはない 2021-06-03 時点
  • 制御の例

    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:ロググループ名:log-stream:ログストリーム名"
        }
    ]
}
  • VPCエンドポイントポリシー
{
    "Statement": [
        {
            "Action": [
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:ロググループ名:log-stream:ログストリーム名",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
            }
        }
    ]
}

CloudWatchMetrics

  • VPCエンドポイントのタイプ

    • インターフェイス型
  • エンドポイント名

    • com.amazonaws.ap-northeast-1.monitoring
  • エンドポイントの用途

  • 制御の内容

    • IAMポリシーにて許可(Allow)する Action を定義する
    • VPCエンドポイントポリシーにて許可(Allow)する Action と Principal を定義する
    • CloudWatchLogs にリソースベースのポリシーはない 2021-06-03 時点
  • 制御の例

    • role-for-ec2のポリシー
{
  "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "0",
            "Effect": "Allow",
            "Action": [
              "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        }
    ]
}
{
  "Statement": [{
    "Action": ["cloudwatch:PutMetricData"],
    "Effect": "Allow",
    "Resource": "*",
    "Principal": {
      "AWS": "arn:aws:iam::123456789012:role/role-for-ec2"
    }
  }]
}