Closed23

VPC Endpoint Workshop

kenryokenryo

このハンズオンではVPC Endpoint、IAM、Cloud9、VPC、CloudFormation、S3、SQSを使用するので、
それらを作成する権限を持ったIAMユーザーが必要。
今回は管理者権限を持つものでやる。

kenryokenryo

CloudFormation Bootstrap Scripts

ハンズオンを体験するため、提供されている以下のyamlテンプレートでCloudFormationスタックを作成しておきます。
なお、このハンズオンはバージニア北部(us-east-1)を使用した方がいいと注意書きされているため、それに従います。

https://github.com/aws-samples/vpcendpointworkshop/blob/master/cfn/vpc-endpoints-lab.yaml

スタック作成の際に聞かれるEvent Engine Lab Environment ?パラメータはfalseにすること。それ以外のパラメータはデフォルトでやってみる。

kenryokenryo

スタックが2つ作成された上から1つ目はCloud9、2つ目はデモアプリ。
出力の値は後で使用するのでタブはこのままにしておきます。

kenryokenryo

LAB SCENARIO

このハンズオンのシナリオについて簡単に説明します。

あなたはセキュリティエンジニアでAWS EC2インスタンスにホストされているアプリケーションを管理しています。
アプリケーションには売上・報酬情報を扱うアプリ(セールスアプリ)と売上・報酬情報からレポートを作成するエンジン(レポートエンジン)があります。
CEOは売上・報酬情報をインターネットに流さず、プライベートなネットワークセグメントを通るようにすべきと判断し、セキュリティエンジニアに改善を依頼しました。

請求・報酬データはセールスアプリ、レポートエンジン間でS3を介して受け渡ししています。
また、レポートエンジンのレポート作成のトリガーはセールスアプリが格納するSQSキューです。
EC2からS3、SQSへのデータ送受信は何もしない場合、インターネットゲートウェイを経由し、インターネットに流れます。
インターネットにデータを流さず、AWS内部でセキュアに通信するにはVPCエンドポイントを使用し、エンドポイント経由でS3、SQSにアクセスするようにします。

https://dev.classmethod.jp/articles/vpc-endpoint-gateway-type/

以下はハンズオンにあったアプリの処理の流れです。

  1. セールスアプリから日々の売上情報をS3にアップロードします。その後、報酬情報を更新します。
  2. 1の処理が完了したら、SQSキューにメッセージを配置します。このキューはレポートエンジンのレポート作成および作成後のキューの削除処理のトリガーとなります。
  3. レポートエンジンはSQSに配置されたメッセージを読み、レポート作成を実行します。
  4. レポートエンジンは作成したレポートをS3にアップロードし、SQSのメッセージを削除します。

kenryokenryo

CLOUD9 WORKSPACE

この章ではCloud9のEC2インスタンスからセールスアプリ、レポートエンジンそれぞれのEC2インスタンスにSSHでアクセスしてみます。

まず、初めにCloud9に進み、CloudFormationで作成されたIDEにアクセスします。
IDEのターミナルで、以下のコマンドを実行し、SSH設定をします。

aws s3 cp s3://ee-assets-prod-us-east-1/modules/7dbaeba0ef084e64a3566ebed6cb8bd2/v1/prepcloud9forssh.sh ./prepcloud9forssh.sh; chmod 700 prepcloud9forssh.sh; ./prepcloud9forssh.sh

実行結果の赤線、黄線に各アプリのアクセスコマンドが書かれているので、別ターミナルでそれぞれ実行します。

セールスアプリ

レポートエンジン

kenryokenryo

BUILD GATEWAY ENDPOINTS

以下の図はEC2インスタンスからゲートウェイ型のVPCエンドポイントを経由してS3にアクセスするまでの流れです。

  1. S3用APIをEC2から呼び出してS3にアクセスするため、EC2にIAMロールを付与する
  2. EC2インスタンスがあるプライベートサブネットのルートテーブルにVPCエンドポイントへのルートを追加する
  3. VPCエンドポイント経由でアクセスできるS3を制限するため、リソースポリシーを作成する
  4. VPCエンドポイント経由からのみアクセスされるようS3バケットポリシーを作成する

kenryokenryo

EC2 INSTANCE PROFILES (IAM)

IAMロールが2つ新規作成されていた。

vpc-endpoints-lab-us-east-1-salesapp-roleはセールスアプリ用のロールです。
S3へのGet, Put ,Deleteを許可するポリシー、SQSへのSend, Receive, Deleteなどを許可するポリシーが付与されていました。
また、信頼関係はec2.amazonaws.comが書かれていました。
vpc-endpoints-lab-us-east-1-reportsengine-roleはレポートエンジン用のロールです。

セールスアプリはsqs:SendMessagesqs:ReceiveMessageを許可、つまり、メッセージの送信と受信を許可。
レポートアプリはsqs:ReceiveMessagesqs:DeleteMessageを許可、つまり、メッセージの受信と削除を許可していました。

kenryokenryo

ROUTE TABLES

次にルートテーブルを見てみると2つ作成されていた。

ルートを見ると、S3へのアクセス(pl-から始まる送信先)の場合、VPCエンドポイント(vpce-から始まるターゲット)に向かうルートが記載されていた。

kenryokenryo

ENDPOINT RESOURCE POLICY

続いてエンドポイントリソースポリシーの確認と修正

S3のVPCエンドポイントをチェックし、ポリシータブを選択。ポリシーを以下のように編集する。
このポリシーによってResourceに指定されているバケットへActionの実行を許可する。
なお、Resourceのexamplerestrictedbucketnameの部分はCloudFormatonスタック出力のRestrictedS3Bucketの値に書き換える。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Access-to-specific-bucket-only",
			"Effect": "Allow",
			"Principal": "*",
			"Action": [
				"s3:GetObject",
				"s3:PutObject"
			],
			"Resource": [
				"arn:aws:s3:::examplerestrictedbucketname",
				"arn:aws:s3:::examplerestrictedbucketname/*"
			]
		}
	]
}
kenryokenryo

S3 BUCKET RESOURCE POLICY

S3バケットポリシーの確認と更新をおこないます。
S3の画面からバケット(restrictedbucket)を選択し、アクセス制御タブを選択します。
バケットポリシーを以下のJson形式で設定します。

なお、Resourceのexamplerestrictedbucketnameの部分はCloudFormatonスタック出力のRestrictedS3Bucketの値に書き換える。
Conditionのvpce-vpceidの部分はCloudFormatonスタック出力のS3VPCGatewayEndpointの値に書き換える。

 {
   "Version": "2012-10-17",
   "Id": "vpc-endpoints-lab-s3-bucketpolicy",
   "Statement": [
     {
       "Sid": "Access-to-put-objects-via-specific-VPCE-only",
       "Principal": "*",
       "Action": "s3:PutObject",
       "Effect": "Deny",
       "Resource": ["arn:aws:s3:::examplerestrictedbucketname",
                    "arn:aws:s3:::examplerestrictedbucketname/*"],
       "Condition": {
         "StringNotEquals": {
           "aws:sourceVpce": "vpce-vpceid"
         }
       }
     }   
   ]
}

Principalが*になっているが、これはゲートウェイ型のVPCエンドポイントにはPrincipalに特定のIAMロールやユーザーを指定することができないからみたいだ

For gateway endpoints only, you cannot limit the principal to a specific IAM role or user. We specify * to grant access to all IAM roles and users. For gateway endpoints only, if you specify the principal in the format “AWS”:“AWS-account-ID” or “AWS”:“arn:aws:iam::AWS-account-ID:root”, access is granted to the >AWS account root user only, and not all IAM users and roles for the account.

kenryokenryo

BUILD INTERFACE ENDPOINTS

SQSへのアクセスもS3と同様にVPCエンドポイントを経由させる。
今度はゲートウェイ型のエンドポイントではなく、インターフェース型のを使用する。

  1. SQS用のAPIをEC2が実行できるようにIAMロールを作成する。
  2. プライベートサブネットからのインバウンドアクセスのみを許可するセキュリティグループを作成する。
  3. 特定のSQSキューに指定したIAMプリンシパルのみアクセスするようVPCエンドポイントポリシーを作成する。
  4. SQSリソースポリシーでアクセス元のVPCエンドポイントを制限する。

kenryokenryo

SECURITY GROUPS

Interface-Endpoint-Security-Groupというセキュリティグループが作成されているので、そいつのインバウンドルールを更新する。
既存ルールを削除し、セールスアプリ用セキュリティグループとレポートエンジン用セキュリティグループからのアクセスに制限する。
各セキュリティグループのIDはCloudFormationの出力(SecurityGroupForSalesApp 、SecurityGroupForReportsEngine)から確認できる。

kenryokenryo

ENDPOINT RESOURCE POLICY

CloudFormationの出力InterfaceEndpointPolicyURLを辿るとSQSとEC2を繋ぐVPCエンドポイントの情報が閲覧できます。
エンドポイントをチェックし、ポリシータブを選択、ポリシーの編集を行います。
VPCエンドポイントのアクセスを制限するためJsonを追加します。
examplequeueARNはCloudFormation出力SQSQueueARNの値を設定
exampleaccountidはAWSアカウントIDを指定

{
   "Statement": [{
      "Action": ["sqs:SendMessage","sqs:ReceiveMessage","sqs:DeleteMessage"],
      "Effect": "Allow",
      "Resource": "examplequeueARN",
      "Principal": { "AWS": "exampleaccountid" }
   }]
}

これを指定することでVPCエンドポイントにどんな用途で誰がどこにアクセスするかを制限することができる。
この場合、SQSサービスにメッセージを送信、受信、削除するのは、指定したAWSアカウントのみに制限している。

以下がわかりやすかった。

https://dev.classmethod.jp/articles/aws-kms-now-supports-vpc-endpoint-policies/#toc-5

kenryokenryo

QUEUE RESOURCE POLICY

管理コンソールのSQS画面でCloudFormationによって作成されたキューを選択します。
アクセスポリシータブを選択し、編集ボタンでJsonを更新します。

sqsexampleARNはCloudFormation出力のSQSQueueARNの値に置き換えます。
vpce-vpceidはCloudFormation出力のSQSVPCInterfaceEndpointの値に置き換えます。
こちらのJsonもVPCエンドポイントと同様にアクセス制限を行なっています。どのキューにどういった操作を誰に許可しているかを定義しています。
この場合、SQSQueueARNのキューに対するメッセージの送信、受信、削除の操作をインターフェース型のエンドポイント経由のみに制限させています。

 {
  "Version": "2012-10-17",
  "Id": "vpc-endpoints-lab-sqs-queue-resource-policy",
  "Statement": [
    {
      "Sid": "all-messages-sent-from-interface-vpc-endpoint",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sqs:SendMessage",
      "Resource": "sqsexampleARN",
      "Condition": {
        "StringEquals": {
          "aws:sourceVpce": "vpce-vpceid"
        }
      }
    },
    {
      "Sid": "all-messages-received-from-interface-vpc-endpoint",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sqs:ReceiveMessage",
      "Resource": "sqsexampleARN",
      "Condition": {
        "StringEquals": {
          "aws:sourceVpce": "vpce-vpceid"
        }
      }
    },
    {
      "Sid": "all-messages-deleted-from-interface-vpc-endpoint",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "sqs:DeleteMessage",
      "Resource": "sqsexampleARN",
      "Condition": {
        "StringEquals": {
          "aws:sourceVpce": "vpce-vpceid"
        }
      }
    }

  ]
}
kenryokenryo

※SQSにメッセージが送信できてしまっているので要確認

  • インターフェース型セキュリティグループの設定は問題なし
  • SQSポリシーからメッセージ送信権限を削除してみても通った
  • セキュリティグループからインバウンド設定を削除したらタイムアウト
  • セールスアプリ、レポートエンジンのEC2からコマンド実行していたからでした。通るのは当たり前。

CLOUD9 TO SQS QUEUE

セキュリティグループの設定により、VPCエンドポイントを経由してSQSキューにアクセスできるのはEC2のみになっているはず。
Cloud9からSQSにアクセスするとどうなるか試してみる。

以下のコマンドを
<region>はCloudFormationを実行したリージョン
<sqsqueueurlvalue>はCloudFormation出力SQSQueueURLの値
<restrictedbucket>はCloudFormation出力RestrictedS3Bucketの値
に置き換え、Cloud9でログイン時のEC2で実行する(セールスアプリ用EC2、レポートエンジン用EC2にログインせず)

nslookup sqs.<region>.amazonaws.com
aws sts get-caller-identity
aws sqs send-message --queue-url <sqsqueueurlvalue> --endpoint-url https://sqs.<region>.amazonaws.com --message-body "{datafilelocation:s3://<restrictedbucket>/test.txt}" --region <region>
KensukeSatou:~/environment $ nslookup sqs.us-east-1.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.2.151
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.1.116

KensukeSatou:~/environment $ aws sts get-caller-identity
{
    "UserId": "XXX",
    "Account": "XXX",
    "Arn": "arn:aws:iam::XXX:user/KensukeSatou"
}
KensukeSatou:~/environment $ aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/XXX/lab-us-east-1-sqs-queue --endpoint-url https://sqs.us-east-1.amazonaws.com --message-body "{datafilelocation:s3://XXX-lab-us-east-1-restrictedbucket/test.txt}" --region us-east-1
^[c^[c^[c

nslookupでSQSのパブリックDNSに紐づくプライベートIPアドレスを取得することができます。
以下からもIPアドレスを確認することができます。

https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#NIC:search=InterfaceSecurity;sort=networkInterfaceId

aws sts get-caller-identityでアカウントID、AssumedRole情報が取得できます。セールスアプリとレポートエンジンは異なるロールを使用していることがわかります。
https://dev.classmethod.jp/articles/get-aws-account-id-with-get-caller-identity/

aws sqs send-messageでSQSにメッセージ送信ができます。–endpoint-urlオプションでSQSのエンドポイントを明示的に指定することができます。

なぜ、Cloud9からSQSにアクセスできないか。
それはインターフェース型エンドポイントのセキュリティグループはインバウンドとしてセールスアプリ・レポートエンジンのセキュリティグループからのアクセスのみを制限しているからです。

kenryokenryo

SALESAPP EC2 TO SQS

以下のコマンドを
<region>はCloudFormationを実行したリージョン
<sqsqueueurlvalue>はCloudFormation出力SQSQueueURLの値
<restrictedbucket>はCloudFormation出力RestrictedS3Bucketの値
に置き換える。
Cloud9でセールスアプリ用EC2にSSHでログイン後、コマンドを実行する。

nslookup sqs.<region>.amazonaws.com
aws sts get-caller-identity
aws sqs send-message --queue-url <sqsqueueurlvalue> --endpoint-url https://sqs.<region>.amazonaws.com --message-body "{datafilelocation:s3://<restrictedbucket>/test.txt}" --region <region>

今度はタイムアウトにならずうまくいく
利用可能なメッセージが1つ増えていることが確認できる

KensukeSatou:~/environment $ ssh ec2-user@salesapp -i vpce.pem
The authenticity of host 'salesapp (10.0.1.123)' can't be established.
ECDSA key fingerprint is SHA256:cuXnTFHXdhusMMM17I6bafjlecpwOWdw2vZhSGsWgHo.
ECDSA key fingerprint is MD5:06:e3:91:d6:5d:fb:27:a5:ba:b6:72:d6:80:59:e5:2a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'salesapp,10.0.1.123' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-0-1-123 ~]$ nslookup sqs.us-east-1.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.2.9
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.1.189

[ec2-user@ip-10-0-1-123 ~]$ aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "AROAY2H4XULGXZ37XCYPK:i-09bc56d4411935cb8", 
    "Arn": "arn:aws:sts::XXX:assumed-role/lab-us-east-1-salesapp-role/i-09bc56d4411935cb8"
}
[ec2-user@ip-10-0-1-123 ~]$ aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/XXX/lab-us-east-1-sqs-queue --endpoint-url https://sqs.us-east-1.amazonaws.com --message-body "{datafilelocation:s3://XXX-lab-us-east-1-restrictedbucket/test.txt}" --region us-east-1
{
    "MD5OfMessageBody": "162a6dd7fa31ad46b1ba509495a24c6c", 
    "MessageId": "b84fb28e-0062-40b6-a79c-8dadd7bcdfb9"
}
[ec2-user@ip-10-0-1-123 ~]$ 

A. インターフェース型VPCエンドポイントのセキュリティグループでは、セールスアプリのセキュリティグループからのインバウンドアクセスを許可しているため、アクセスに成功します。

B. インターフェースエンドポイントポリシーでPrincipalに指定したアカウントからのsqs:SendMessagesqs:ReceiveMessagesqs:DeleteMessageの実行を許可しているため、SQSへのメッセージ送信に成功します。

C. SQSのリソースポリシーでインターフェース型VPCエンドポイントからのsqs:SendMessagesqs:ReceiveMessagesqs:DeleteMessageの実行を許可しているため、SQSへのメッセージの送信に成功します。

続いて、先ほど送信したメッセージを取り出してみます。

以下のコマンドを
<region>はCloudFormationを実行したリージョン
<sqsqueueurlvalue>はCloudFormation出力SQSQueueURLの値
に置き換える。
Cloud9でセールスアプリ用EC2にSSHでログイン後、コマンドを実行する。

aws sqs receive-message --queue-url <sqsqueueurlvalue> --endpoint-url https://sqs.<region>.amazonaws.com --region <region>

メッセージ送信コマンドで--message-bodyに指定した文字列がBodyの値として返却されていた

[ec2-user@ip-10-0-1-123 ~]$ aws sqs receive-message --queue-url https://sqs.us-east-1.amazonaws.com/XXX/lab-us-east-1-sqs-queue --endpoint-url https://sqs.us-east-1.amazonaws.com --region us-east-1
{
    "Messages": [
        {
            "Body": "{datafilelocation:s3://XXX-lab-us-east-1-restrictedbucket/test.txt}", 
            "ReceiptHandle": "AQEBSrNrAd7GvL2l5AuL4I80r+1aCKmJ2eNLrLHKpxm5HaL3Kt04dU9TrNanDanRWEHTFXuwhuHHXoqXSVwiQ+lotVx50+8RJpCBvye5MMpIkgYUSm2IQ59+AHrtOVeSmIHhExGL9J5hGEuZdTwJ2A7drDDTQEiwxBdKAPwM4h8o86NoBFvo29I/+Ig9ghJFK3Dir3C/l7p2GTVLdgLK6XDi1Yp042ECopQ7lpGAJwYUsndiGmv0+E57kf6zj8e8X3ChgI+rnoVocZZiDVIRNuliaHHg8PkKekets97vOZDCyrW3DWr5GxwSE91kwRUzT3nTdW6UAKL0K0Fo6zYCuyNodwNxthbtaI9+6+v0AV9DlID4+jvCsTVwGn2vZo8p6McCebUaz/ngYCLsLXlEYjf0bQ==", 
            "MD5OfBody": "162a6dd7fa31ad46b1ba509495a24c6c", 
            "MessageId": "b84fb28e-0062-40b6-a79c-8dadd7bcdfb9"
        }
    ]
}

キューは利用可能なメッセージのままだった

セールスアプリのIAMロールは以下の通りsqs:ListQueuesの権限を持っている。一方、インターフェースエンドポイントポリシーはsqs:ListQueuesを許可していない。
この状態でsqs:ListQueuesを実行したらどうなるか

{
    "Statement": [
        {
            "Action": [
                "sqs:SendMessage",
                "sqs:ReceiveMessage",
                "sqs:DeleteMessage",
                "sqs:GetQueueUrl",
                "sqs:GetQueueAttributes",
                "sqs:ListQueues",
                "sqs:ListQueueTags"
            ],
            "Resource": "arn:aws:sqs:us-east-1:XXX:lab-us-east-1-sqs-queue",
            "Effect": "Allow"
        }
    ]
}

以下のコマンドを
<region>はCloudFormationを実行したリージョン
に置き換える。
Cloud9でセールスアプリ用EC2にSSHでログイン後、コマンドを実行する。

aws sqs list-queues --region <region> --endpoint-url https://sqs.<region>.amazonaws.com

アクセス拒否された。直感としてあっている。

[ec2-user@ip-10-0-1-123 ~]$ aws sqs list-queues --region us-east-1 --endpoint-url https://sqs.us-east-1.amazonaws.com

An error occurred (AccessDenied) when calling the ListQueues operation: Access to the resource https://sqs.us-east-1.amazonaws.com/ is denied.
[ec2-user@ip-10-0-1-123 ~]$ 
kenryokenryo

REPORTS ENGINE EC2 TO SQS

以下のコマンドを
<region>はCloudFormationを実行したリージョン
<sqsqueueurlvalue>はCloudFormation出力SQSQueueURLの値
に置き換える。
Cloud9でレポートエンジン用EC2にSSHでログイン後、コマンドを実行する。

nslookup sqs.<region>.amazonaws.com
aws sts get-caller-identity
aws sqs receive-message --queue-url <sqsqueueurlvalue> --endpoint-url https://sqs.<region>.amazonaws.com --region <region>
[ec2-user@ip-10-0-2-120 ~]$ nslookup sqs.us-east-1.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.2.41
Name:   sqs.us-east-1.amazonaws.com
Address: 10.0.1.165

[ec2-user@ip-10-0-2-120 ~]$ aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "AROAY2H4XULGSHW3WS3YP:i-0c7435aa1a7ac3781", 
    "Arn": "arn:aws:sts::XXX:assumed-role/lab-us-east-1-reportsengine-role/i-0c7435aa1a7ac3781"
}
[ec2-user@ip-10-0-2-120 ~]$ aws sqs receive-message --queue-url https://sqs.us-east-1.amazonaws.com/XXX/lab-us-east-1-sqs-queue --endpoint-url https://sqs.us-east-1.amazonaws.com --region us-east-1
{
    "Messages": [
        {
            "Body": "{datafilelocation:s3://XXX-lab-us-east-1-restrictedbucket/test.txt}", 
            "ReceiptHandle": "AQEB1JqKyz065YtHZj49G8zUNRufso1QitLBbmuaxKifpnTkNZM200zJHY8j+1MakU49MxwpMeolr3MtzChlT1IsSxtV7v5lzVJ5ua2OdJn4CD8LJ2+OG2XL17C/FlVpd76qs74zD7jZo0mPNC92FQYv/GyKjaG8TiMCQ6gix1tttwhpasQz7W7JLtABg5zUcws80FpOwmLRnB89ndfYHL4SpDDvNZW6Efdb4BVeNaqRnt8lkZd4oIVx1LJI/ixZlYxiwuJVkUyJa1lI/Sphs8YXaHiWiCnOojlLVxw2xsG6t2mpgsVU//F3S3lzJB6axRogzbvlyQJ+81lNFN1uDCFUxaC25f3um8jQNmdSQBku9dnxlHV+AI0HCOJvUGTRSoIo4wS51cc+Wa04rPafO/id0A==", 
            "MD5OfBody": "162a6dd7fa31ad46b1ba509495a24c6c", 
            "MessageId": "d445eab9-967f-4315-87f2-1a60a7ea4238"
        }
    ]
}

利用可能なメッセージから処理中のメッセージに移動した

以下のコマンドを
<region>はCloudFormationを実行したリージョン
<sqsqueueurlvalue>はCloudFormation出力SQSQueueURLの値
<receipthandle>はaws sqs receive-messageのレスポンスReceiptHandleの値
に置き換える。
Cloud9でレポートエンジン用EC2にSSHでログイン後、コマンドを実行する。

aws sqs delete-message --queue-url <sqsqueueurlvalue> --endpoint-url https://sqs.<region>.amazonaws.com --region <region> --receipt-handle <receipthandle>
[ec2-user@ip-10-0-2-120 ~]$ aws sqs delete-message --queue-url https://sqs.us-east-1.amazonaws.com/XXX/lab-us-east-1-sqs-queue --endpoint-url https://sqs.us-east-1.amazonaws.com --region us-east-1 --receipt-handle AQEB1JqKyz065YtHZj49G8zUNRufso1QitLBbmuaxKifpnTkNZM200zJHY8j+1MakU49MxwpMeolr3MtzChlT1IsSxtV7v5lzVJ5ua2OdJn4CD8LJ2+OG2XL17C/FlVpd76qs74zD7jZo0mPNC92FQYv/GyKjaG8TiMCQ6gix1tttwhpasQz7W7JLtABg5zUcws80FpOwmLRnB89ndfYHL4SpDDvNZW6Efdb4BVeNaqRnt8lkZd4oIVx1LJI/ixZlYxiwuJVkUyJa1lI/Sphs8YXaHiWiCnOojlLVxw2xsG6t2mpgsVU//F3S3lzJB6axRogzbvlyQJ+81lNFN1uDCFUxaC25f3um8jQNmdSQBku9dnxlHV+AI0HCOJvUGTRSoIo4wS51cc+Wa04rPafO/id0A==
[ec2-user@ip-10-0-2-120 ~]$ 

処理中のメッセージがなくなった

A. インターフェース型VPCエンドポイントのセキュリティグループでは、レポートエンジンのセキュリティグループからのインバウンドアクセスを許可しているため、アクセスに成功します。

B. インターフェースエンドポイントポリシーでPrincipalに指定したアカウントからのsqs:SendMessage、sqs:ReceiveMessage、sqs:DeleteMessageの実行を許可しているため、SQSへのメッセージ送信に成功します。

C. SQSのリソースポリシーでインターフェース型VPCエンドポイントからのsqs:SendMessage、sqs:ReceiveMessage、sqs:DeleteMessageの実行を許可しているため、SQSへのメッセージの送信に成功します。

kenryokenryo

REPORTS ENGINE EC2 TO S3

以下のコマンドを
<RestrictedS3Bucket>はCloudFormation出力RestrictedS3Bucketの値
に置き換える。
Cloud9でレポートエンジン用EC2にSSHでログイン後、コマンドを実行する。

nslookup s3.amazonaws.com
aws sts get-caller-identity
aws s3 cp s3://<RestrictedS3Bucket>/test.txt  .
exit

指定したファイルが存在しないと以下のように403エラーとなる。(404の方がしっくりくる)

[ec2-user@ip-10-0-2-120 ~]$ aws s3 cp s3://XXX-lab-us-east-1-restrictedbucket/test.txt  .
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

管理コンソールから手動アップロードはバケットポリシーにより拒否されるので、一度バケットポリシーを削除し、手動アップロードして、ポリシーを再設定。
ファイルはハンズオンにあった適当なファイルを使用するようにした。

[ec2-user@ip-10-0-2-120 ~]$ nslookup s3.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   s3.amazonaws.com
Address: 52.216.243.134
[ec2-user@ip-10-0-2-120 ~]$ aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "AROAY2H4XULGSHW3WS3YP:i-0c7435aa1a7ac3781", 
    "Arn": "arn:aws:sts::XXX:assumed-role/lab-us-east-1-reportsengine-role/i-0c7435aa1a7ac3781"
}
[ec2-user@ip-10-0-2-120 ~]$ aws s3 cp s3://XXX-lab-us-east-1-restrictedbucket/index.js  .
download: s3://XXX-lab-us-east-1-restrictedbucket/index.js to ./index.js
[ec2-user@ip-10-0-2-120 ~]$ exit
logout
Connection to reportsengine closed.
KensukeSatou:~/environment $ 
kenryokenryo

CLOUD9 TO UNRESTRICTED S3 BUCKET

以下のコマンドを
<UnrestrictedS3Bucket >はCloudFormation出力UnrestrictedS3Bucketの値
に置き換える。
Cloud9にログイン後、(SSHでセールスアプリ、レポートエンジンにログインしない)コマンドを実行する。

touch test.txt
aws sts get-caller-identity
nslookup s3.amazonaws.com
aws s3 cp test.txt s3://<UnrestrictedS3Bucket>/test.txt
aws s3 rm s3://<UnrestrictedS3Bucket>/test.txt   
KensukeSatou:~/environment $ touch test.txt
KensukeSatou:~/environment $ aws sts get-caller-identity
{
    "UserId": "AIDAY2H4XULG3MOG4EXUG",
    "Account": "XXX",
    "Arn": "arn:aws:iam::XXX:user/KensukeSatou"
}
KensukeSatou:~/environment $ nslookup s3.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   s3.amazonaws.com
Address: 52.217.195.208

KensukeSatou:~/environment $ aws s3 cp test.txt s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt
upload: ./test.txt to s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt
KensukeSatou:~/environment $ aws s3 rm s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt   
delete: s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt
KensukeSatou:~/environment $ 

特にエラーはなく成功しました。

A. Cloud9のインスタンスはパブリックサブネットにあり、ルートテーブルにはVPCエンドポイントへのエントリーがありません。S3へのトラフィックはインターネットゲートウェイを使用してインターネットに転送されます。

B. トラフィックはS3のパブリックIPにルーティングされます。

C. S3バケットポリシーでの制限などは行なっていないため、S3へのアップロード、オブジェクトの削除に成功します。

kenryokenryo

CLOUD9 TO RESTRICTED S3 BUCKET

つづいて、制限しているS3バケット(Restricted S3 Bucket)にCloud9からアクセスしたらどうなるでしょうか?

以下のコマンドを
<RestrictedS3Bucket >はCloudFormation出力RestrictedS3Bucketの値
に置き換える。
Cloud9にログイン後、(SSHでセールスアプリ、レポートエンジンにログインしない)コマンドを実行する。

touch test.txt
aws sts get-caller-identity
nslookup s3.amazonaws.com
aws s3 cp test.txt s3://<RestrictedS3Bucket>/test.txt
aws s3 rm s3://<RestrictedS3Bucket>/test.txt   
KensukeSatou:~/environment $ touch test.txt
KensukeSatou:~/environment $ aws sts get-caller-identity
{
    "UserId": "AIDAY2H4XULG3MOG4EXUG",
    "Account": "XXX",
    "Arn": "arn:aws:iam::XXX:user/KensukeSatou"
}
KensukeSatou:~/environment $ nslookup s3.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   s3.amazonaws.com
Address: 54.231.195.0

KensukeSatou:~/environment $ aws s3 cp test.txt s3://XXX-lab-us-east-1-restrictedbucket/test.txt
upload failed: ./test.txt to s3://XXX-lab-us-east-1-restrictedbucket/test.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
KensukeSatou:~/environment $ aws s3 rm s3://XXX-lab-us-east-1-restrictedbucket/test.txt   
delete: s3://XXX-lab-us-east-1-restrictedbucket/test.txt
KensukeSatou:~/environment $ 

Putは失敗、Deleteは成功しました。

画像はworkshopの画像そのまま。記載、画像が誤っている。
ただ、トラフィックの宛先であるUn-Resitricted Bucketを除けば、トラフィックの経路は正しい。

A. Cloud9のインスタンスはパブリックサブネットにあり、ルートテーブルにはVPCエンドポイントへのエントリーがありません。S3へのトラフィックはインターネットゲートウェイを使用してインターネットに転送されます。

B. トラフィックはS3のパブリックIPにルーティングされます。

C. RestrictedS3BucketはS3バケットポリシーでVPCエンドポイント以外でのPut操作を制限しています。そのため、Putはアクセス拒否されます。一方Deleteは制限されていないため、成功します。

kenryokenryo

SALESAPP EC2 TO UNRESTRICTED S3 BUCKET

セールスアプリからUnrestrictedS3Bucketにアクセスした場合どうなるでしょうか?

以下のコマンドを
<UnrestrictedS3Bucket >はCloudFormation出力UnrestrictedS3Bucketの値
に置き換える。
Cloud9にログイン後、SSHでセールスアプリにログインし、コマンドを実行する。

touch test.txt
aws sts get-caller-identity
nslookup s3.amazonaws.com
aws s3 cp test.txt s3://<UnrestrictedS3Bucket>/test.txt
[ec2-user@ip-10-0-1-127 ~]$ touch test.txt
[ec2-user@ip-10-0-1-127 ~]$ aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "AROAY2H4XULGVKQHG5UYK:i-0f09efa577c03b27f", 
    "Arn": "arn:aws:sts::XXX:assumed-role/lab-us-east-1-salesapp-role/i-0f09efa577c03b27f"
}
[ec2-user@ip-10-0-1-127 ~]$ nslookup s3.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   s3.amazonaws.com
Address: 52.217.43.142

[ec2-user@ip-10-0-1-127 ~]$ aws s3 cp test.txt s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt
upload failed: ./test.txt to s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
[ec2-user@ip-10-0-1-127 ~]$ aws s3 rm s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt 
delete failed: s3://XXX-lab-us-east-1-unrestrictedbucket/test.txt An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
[ec2-user@ip-10-0-1-127 ~]$ 

Put, Delete操作ともに失敗しました。

A. セールスアプリのインスタンスはプライベートサブネットにあります。上で実行したcpコマンドはaws sts get-caller-identityの結果から分かるようにセールスアプリのIAMロール権限で実行されます。
IAMロールではUnrestrictedS3Bucket,RestrictedS3BucketともにPutは許可しています。
トラフィックはVPCエンドポイントにルーティングされますが、VPCエンドポイントポリシーではRestrictedS3Bucket以外へのアクセスを許可していません。
よって、Put, Deleteに失敗します。

kenryokenryo

SALESAPP EC2 TO RESTRICTED S3 BUCKET

セールスアプリからRestrictedS3Bucketにアクセスしてみます。

以下のコマンドを
<RestrictedS3Bucket >はCloudFormation出力RestrictedS3Bucketの値
に置き換える。
Cloud9にログイン後、SSHでセールスアプリにログインし、コマンドを実行する。

touch test.txt
aws sts get-caller-identity
nslookup s3.amazonaws.com
aws s3 cp test.txt s3://<restrictedS3Bucket>/test.txt
[ec2-user@ip-10-0-1-127 ~]$ touch test.txt
[ec2-user@ip-10-0-1-127 ~]$ aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "AROAY2H4XULGVKQHG5UYK:i-0f09efa577c03b27f", 
    "Arn": "arn:aws:sts::XXX:assumed-role/lab-us-east-1-salesapp-role/i-0f09efa577c03b27f"
}
[ec2-user@ip-10-0-1-127 ~]$ nslookup s3.amazonaws.com
Server:         10.0.0.2
Address:        10.0.0.2#53

Non-authoritative answer:
Name:   s3.amazonaws.com
Address: 52.217.228.248

[ec2-user@ip-10-0-1-127 ~]$ aws s3 cp test.txt s3://XXX-lab-us-east-1-restrictedbucket/test.txt
upload: ./test.txt to s3://XXX-lab-us-east-1-restrictedbucket/test.txt
[ec2-user@ip-10-0-1-127 ~]$ aws s3 rm s3://XXX-lab-us-east-1-restrictedbucket/test.txt   
delete failed: s3://XXX-lab-us-east-1-restrictedbucket/test.txt An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
[ec2-user@ip-10-0-1-127 ~]$ 

Putは成功、Deleteは失敗しました。

A. セールスアプリのインスタンスはプライベートサブネットにあります。上で実行したcpコマンドはaws sts get-caller-identityの結果から分かるようにセールスアプリのIAMロール権限で実行されます。
IAMロールではUnrestrictedS3Bucket,RestrictedS3BucketともにPut, Deleteは許可しています。
VPCエンドポイントポリシーではPut操作しか許可されていません。また、バケットポリシーも同様です。
よって、Deleteに失敗します。

このスクラップは2022/04/04にクローズされました