今回のゴール
- SQSキューのメッセージ中に機密データがある
- 社内のコンプライアンス上インターネットを経由しないでSQSメッセージを送受信したい
等の要件はよくあると思います。
そこで今回はVPCエンドポイント経由でのみSQSにメッセージ送受信できるように設定していきます。
まず、現状を確認します。
VPC内のEC2からsqs.ap-northeast-1.amazonaws.comの名前解決を行うと、グローバルIPが返ってきました。
nslookup sqs.ap-northeast-1.amazonaws.com
Non-authoritative answer:
sqs.ap-northeast-1.amazonaws.com canonical name = ap-northeast-1.queue.amazonaws.com.
Name: ap-northeast-1.queue.amazonaws.com
Address: 52.119.xxx.xxx
EC2インスタンスの作成
手順は省略しますが、メッセージ送信用にEC2インスタンスを作成します。
セキュリティーグループの作成
エンドポイントにアタッチするセキュリティーグループを作成します。
[セキュリティグループ名]:sg_endpoint_sqs
[説明]:access to sqs
[VPC]:VPCを選択
【インバウンドルール】
[タイプ]:https
[ソース]:SQSにアクセスするEC2のセキュリティーグループを選択
エンドポイントの作成
SQSのサービスを選択して、VPCとサブネットを選択します。
先ほど作成したセキュリティーグループを選択します。
確認
再度nslookupで確認するとエンドポイントのアドレスが返ってきました。
nslookup sqs.ap-northeast-1.amazonaws.com
Non-authoritative answer:
Name: sqs.ap-northeast-1.amazonaws.com
Address: 10.0.xxx.xxx
Name: sqs.ap-northeast-1.amazonaws.com
Address: 10.0.xxx.xxx
SQSのアクセスポリシーの設定
SQSのキューに下記のアクセスポリシーを設定して、エンドポイント経由以外のメッセージの送受信を拒否しました。
今回は実施しておりませんが、特定アカウントのユーザーやロールにメッセージの送受信を許可するときは、そのアクセスポリシーを記述します。
カスタム Amazon SQS アクセスポリシー言語の例
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-creating-custom-policies-access-policy-examples.html
{
"Version": "2008-10-17",
"Id": "__default_policy_ID",
"Statement": [
{
"Sid": "__owner_statement",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::(your AWS Account ID):root"
},
"Action": "SQS:*",
"Resource": "arn:aws:sqs:ap-northeast-1:(your AWS Account ID):test-queue.fifo"
},
{
"Sid": "2",
"Effect": "Deny",
"Principal": "*",
"Action": [
"sqs:SendMessage",
"sqs:ReceiveMessage"
],
"Resource": "arn:aws:sqs:ap-northeast-1:(your AWS Account ID):test-queue.fifo",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-xxxxxxxxxxxxx"
}
}
}
]
}
確認
コンソールからのメッセージの送信
コンソールからキューにメッセージを送信してみます。
SQSサービスでキューを選択して、「メッセージを送受信」をクリックします。
[メッセージ本文]と[メッセージグループID]を入力して「メッセージを送信」ボタンをクリックします。
AccessDeniedとなりメッセージが送信エラーとなることが確認できました。
EC2からのメッセージの送信
EC2からCLIでメッセージを送信してみると・・・
予想に反してAccessDeniedとなり送信できませんでした。
aws sqs send-message --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/test-queue.fifo --message-group-id "test-group" --message-body "abc"
An error occurred (AccessDenied) when calling the SendMessage operation: Access to the resource https://ap-northeast-1.queue.amazonaws.com/ is denied.
SQSのAPIエンドポイントは
- (旧)ap-northeast-1.queue.amazonaws.com
- (新)sqs.ap-northeast-1.amazonaws.com
の2つが存在し、–queue-url のパラメータで新を指定しているにも関わらず、旧のエンドポイントを参照しているようです。(2021/10/24時点)
ですので、–endpoint-urlで明示的にエンドポイントのURLを指定する必要があります。
aws sqs send-message --endpoint-url https://sqs.ap-northeast-1.amazonaws.com --queue-url https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/test-queue.fifo --message-group-id "test-group" --message-body "abc"
無事メッセージを送信する事ができました。
SDKでもメッセージを送信してみましたが、SDKを使用する際は–endpoint-urlを指定しなくてもメッセージを送信する事ができました。
(SDKのバージョンが古い時は旧エンドポイントを参照するものもあるようです)