AWS CLI等でSQS VPC Endpointを利用するときの注意点

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

SQS向けのVPC Endpoint (Private Link)を利用するときの注意点です。特に、AWS CLIをご利用の方。
なお本ブログでは、下記のバージョンのAWS CLIで検証を行っています。(2019/03/03時点で最新)

[ec2-user@swx-bastion-l01 ~]$ aws --version
aws-cli/1.16.116 Python/2.7.14 Linux/4.14.88-88.76.amzn2.x86_64 botocore/1.12.106

SQSのAPIエンドポイントには実は2種類あります。
かつて使われていたエンドポイント(以下、レガシーエンドポイント)と、新しいエンドポイント(以下、現行エンドポイント)です。

レガシーエンドポイント: ap-northeast-1.queue.amazonaws.com
現行エンドポイント: sqs.ap-northeast-1.amazonaws.com

2019/03/03現在、AWS CLIはデフォルトではSQSのレガシーエンドポイントを利用してしまいます。
これがVPC Endpointを利用してSQSに接続しようとしたときに、少し問題になります。

検証してみます。
とあるVPCに、SQSのInterface VPC Endpointを作成しました。
同じVPCにEC2をローンチします。セキュリティグループのアウトバウンド通信ではVPC内のローカル通信だけを許可します。これでこのEC2は、インターネットには出れないが、VPC内にあるVPC Endpointへはアクセスができる状態です。

nslookupで、レガシーエンドポイントと現行エンドポイントの名前解決をしてみます。

[ec2-user@swx-bastion-l01 ~]$ nslookup ap-northeast-1.queue.amazonaws.com
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
Name:   ap-northeast-1.queue.amazonaws.com
Address: 54.240.225.157

[ec2-user@swx-bastion-l01 ~]$ nslookup sqs.ap-northeast-1.amazonaws.com
Server:         192.168.0.2
Address:        192.168.0.2#53

Non-authoritative answer:
Name:   sqs.ap-northeast-1.amazonaws.com
Address: 192.168.4.179
Name:   sqs.ap-northeast-1.amazonaws.com
Address: 192.168.3.59

レガシーエンドポイントを名前解決したときは、パブリックIPが返ってきていることが分かります。
一方で現行エンドポイントを名前解決したときは、VPC EndpointのプライベートIPが返ってきていることが分かります。

AWS CLIでSQSのコマンドを実行してみます。

[ec2-user@swx-bastion-l01 ~]$ aws --region ap-northeast-1 sqs list-queues

Connect timeout on endpoint URL: "https://ap-northeast-1.queue.amazonaws.com/"

これはAWS CLIがデフォルトではレガシーエンドポイントを利用しようとしているため、パブリックIPに繋ぎに行こうとしてしまっており、タイムアウトしているのだと分かります。
ちなみに「 aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/123456789012/testqueue --message-body "Hello" 」のように、キューURLに現行エンドポイントが含まれているように見えてもAWS CLIだとレガシーエンドポイントに接続してしまいます。

ではAWS CLIさんに現行エンドポイントを使ってもらいましょう。
--endpoint-url オプションで現行エンドポイントを明示的に指定してあげます。

[ec2-user@swx-bastion-l01 ~]$ aws --region ap-northeast-1 sqs list-queues --endpoint-url https://sqs.ap-northeast-1.amazonaws.com
{
    "QueueUrls": [
        "https://sqs.ap-northeast-1.amazonaws.com/123456789012/test-queue"
    ]
}

成功しました。
このように、現行エンドポイントへアクセスしようとしているため、VPC Endpoint経由でアクセスされたことが分かります。
またCloudTrailでAPIアクセス履歴を見ると、接続元IPがEC2のローカルIPアドレスで記録されていることも分かります。
※ListQueues APIはCloudTrailに記録されないため、PurgeQueue APIで試してみました。

{
(中略)
    "eventSource": "sqs.amazonaws.com",
    "eventName": "PurgeQueue",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "192.168.1.10",
    "vpcEndpointId": "vpce-01234567890123456"
}

普通にパブリックなAPIエンドポイントからアクセスすると、このsourceIPAddressはEC2のElastic IPアドレスやNAT GatewayのIPアドレスになるはずです。
今回はVPC Endpointからしっかりアクセスできているので、VPC EndpointのIDまで記録されています。(上記例のIDは念のため適当な値にしています)

なお、AWS Tools for Powershellではデフォルトで現行エンドポイントを使うことも確認できました。
(念のため、お使いのCLI/SDKではどのような動きになるか、確認することを推奨いたします)

杉村 勇馬 (記事一覧)

クラウドインテグレーション部 技術3課 課長

マルチAWSアカウント管理運用やネットワーク関係のAWSサービスに関するブログをよく書いています

2020年10月現在、ハマっているものはポケモン ソード(遅い)