VPCエンドポイント経由して別AWSアカウントのS3バケットにアクセスしてみた

ご機嫌いかがでしょうか、豊崎です。

VPCエンドポイントを使用してプライベートな通信でのS3のクロスアカウントアクセスを試す機会がありましたので、書いていきたいと思います。

構成図

本投稿では以下のような登場人物でのクロスアカウントアクセスを行いたいと思います。

S3のクロスアカウントアクセスについてはハマりどころも含めすでに弊社千葉が書いていますので、こちらも参考にしてください。

 

[S3]クロスアカウント時のアップロード時の権限エラー[はまった]

今回はVPCエンドポイントを経由した通信と、「bucket-owner-full-control」に対する回避策をS3バケットポリシーに記述する方法について追記しています。

前提

必要なものはこれだけです。

  • アカウントA
    • IAMRole(S3FullAccess)の作成
    • 上記IAMRoleの付与されたEC2(Amazon Linux以外はAWS CLIが使えるようにしておく)
    • AWS CLIでのPutObject時には「--acl bucket-owner-full-control」オプション必須
    • VPCにS3のVPCエンドポイントが作成されていること
  • アカウントB
    • S3バケットの作成
    • S3バケットポリシーの設定

本投稿ではアクセス制御はS3バケットポリシー側で行う方針で作成をしていきます。

やってみた

アカウントA

まずはVPCにS3のVPCエンドポイントを設定していきます。

設定方法は以下記事を参考にしてください。

【新機能】S3がVPCのプライベートサブネットからアクセス可能になりました!

続いてIAMRoleを作成していきます。今回は「demo-s3-crossaccount」という名前でIAMRoleを作成しました。ポリシーにはAWS管理ポリシーの「AmazonS3FullAccess」をアタッチしてあります。

作成したIAMRoleをEC2にアタッチしておきます。

 

 

アカウントB

こちらではS3バケット「demo-s3-20190122」を作成しました。

作成したS3バケットにバケットポリシーを以下のポリシーを記載しました。PrincipalにアカウントAで作成したIAMRoleを指定して操作を許可/拒否しています。

IAMRoleとバケット名については環境ごとに読み替えてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Example permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::xxxxxxxxxxxx:role/IAMRoleName"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::<bucket-name>",
                "arn:aws:s3:::<bucket-name>/*"
            ]
        },
        {
            "Sid": "Example permissions2",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::xxxxxxxxxxxx:role/IAMRoleName"
            },
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::<bucket-name>",
                "arn:aws:s3:::<bucket-name>/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

検証環境でのポリシーでしたので、基本的にS3の全ての操作を許可しています。一部、PutObject(S3にオブジェクトを配置する系の操作)については「Condition」でノットイコール条件をつけています。

Deny部分の具体的な内容は「S3オブジェクトの配置を行う場合、配置するS3オブジェクトのアクセスコントロールリストに、バケット所有者(アカウントB)用のフルコントロールアクセス権を追加しない場合、アクセスを拒否する」となります。ややこしいのでゆっくり読んでください。

これをつけないとアカウントAが配置したS3オブジェクトに対してアカウントB側で参照などができません。(削除は可能)

試してみる

それでは実際にEC2からVPCエンドポイント経由でのS3へのオブジェクト配置を試してみたいと思います。

「--acl bucket-owner-full-control」をつけないとAccess Deniedになります。

$ aws s3 cp demo001 s3://demo-s3-20190122/ --region ap-northeast-1
upload failed: ./demo001 to s3://demo-s3-20190122/demo001 An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

「--acl bucket-owner-full-control」をつけるとS3オブジェクトの配置が成功しました。

$ aws s3 cp demo001 s3://demo-s3-20190122/ --acl bucket-owner-full-control --region ap-northeast-1
upload: ./demo001 to s3://demo-s3-20190122/demo001

マネジメントコンソールからもS3オブジェクトが配置されていることが確認できました。

また、S3オブジェクトのアクセスコントロールリストにバケット所有者(アカウントB)が指定されていることも確認済みです。

さいごに

今までのクロスアカウントの設定とほぼ変わらないですね。今回はPrivate環境のインターネットに出れないEC2からのIAMRoleとS3バケットポリシーを使ったクロスアカウントだったのですが、インターネットに出れるのであれば、AssumeRoleを利用したこちらの方が良さそうです。東京リージョンでSTSのエンドポイント使えるのはいつ頃になるんでしょうか。待ち遠しいです。この記事が誰かのお役にたてば幸いです。