AWS マネジメントコンソールを操作していたら自端末から VPC エンドポイントを経由したサービスエンドポイント宛の通信が発生していた
コンバンハ、千葉(幸)です。
タイトルの繰り返しとなりますが、 AWS マネジメントコンソールを操作していたところ自端末から VPC エンドポイントを経由してサービスエンドポイント宛に通信を行なっていることに気づいた機会がありました。
念のためもう一度 繰り返すと、AWS マネジメントコンソールの操作中に自端末から VPC エンドポイント経由でのサービスエンドポイント宛の通信が行われていました。
ここまで読んでわたしの言わんとしていることを理解できた方は少ないと思います。理解できた方は、普段から「あなたは察しが良くて人の気持ちをよく理解する人だね」と褒めそやされていることでしょう。
今回は「 AWS マネジメントコンソールを操作していたら VPC エンドポイントを経由したサービスエンドポイントへの通信が行われていた」が答えになるクイズを考えましたので、ヒントを基に「そういう意味か」と腹落ちさせてみてください。
問題
マネジメントコンソールを操作中に、ごく一部のサービス画面で想定通りの挙動を示さない事象が発生しました。具体的には以下のようなもので、参照系の操作が正常にできません。
- EC2 インスタンスの詳細画面で各種グラフを確認した際
- 「グラフデータの取得中にエラーが発生しました。」
- CloudWatch のダッシュボードを表示した際
- 「アラームの取得に失敗しました」
- 「ダッシュボードのロード中に不明なエラーが発生しました。グラフが見つからないか不完全である可能性があります。」
- CloudWatch Logs の一覧画面を開いた際
- 「ロググループの説明中にエラーが発生しました。」
なお、操作には AdministratorAccess を持つ IAM ユーザーを使用しており、Permissions boundary や Organizations SCP による制限は一切ないものとします。
この条件において、上記のエラーが発生した原因として何が考えられるでしょうか。お答えください。
(原因としては複数あり得ますが、今回はその中でも単一のものに決め打ちします。)
ヒント1: 概ね正常に操作できる
前提のおさらいとなりますが、今回のケースでは以下を満たしています。
- マネジメントコンソールには正常に接続できている
- ほとんどのサービスの画面では操作・参照が問題なく実行できる
- エラーは一時的なものではなく、該当の画面を開いた際は毎回発生する
ヒント2: Trail にエラーが記録されていない
エラーが発生してから一定期間経過後に CloudTrail を確認しても、エラー発生時の操作(参照)に該当するイベント(例えばDescribeLogGroups
など)は記録されていませんでした。
ヒント3: VPC 環境との接続
今回マネジメントコンソールを操作しているネットワーク環境は、Direct Connect により VPC と接続されています。
以降、この VPC のことを単に「 VPC 」と呼びます。
ヒント4: VPC エンドポイント
VPC 上には VPC エンドポイントが存在しています。
ヒント5: Route 53 リゾルバー
VPC 上には Route 53 リゾルバーインバウンドエンドポイントが存在し、クライアント端末は参照先の DNS として VPC 内 DNS を使用しています。
ヒント6: プライベート DNS 名
VPC エンドポイントはプライベート DNS 名が有効になっています。つまり、自動的に生成されたプライベートホストゾーンが VPC に関連づけられており、エンドポイントの IP アドレスを指し示す リソースレコードセットが登録されています。
ヒント7: エンドポイントの種類
VPC に存在するエンドポイントは以下の二種類です。
com.amazonaws.ap-northeast-1.logs
com.amazonaws.ap-northeast-1.monitoring
ヒント8: SecuriryGroup
VPC エンドポイントに設定されている SecuriryGroup では、以下のインバウンドルールが定義されています。
プロトコル | ポート | 送信元 |
---|---|---|
TCP | 443 | VPC の CIDR 全体 |
はい、流石にもう分かりましたね。
答え
マネジメントコンソールの操作中、一部箇所のデータ取得のためにサービスエンドポイント宛の通信が発生した。それは今回の構成では VPC エンドポイントを経由しようとするが、 SecuriryGroup で自端末からのインバウンドが許可されていないためにブロックされた。だから。
というものでした。そういうことがあるんだなぁと少し感心してしまいました。シンプルに解決するなら、SecuriryGroup のインバウンドを開放してあげればいいですね。
HAR ファイルでの通信状況の確認
実を言うとこの事象は自分自身が直面した訳ではないので、発生した方から以下手順にのっとり HAR ファイルを取得・提供してもらいました。
その内容を確認したところ、API リクエストを行う通信の種類として大まかに以下に分かれることに気づきました。
- マネジメントコンソール経由
- 直接実行
マネジメントコンソール経由
例えば東京リージョンのマネジメントコンソールの URL は以下です。
https://ap-northeast-1.console.aws.amazon.com/
マネジメントコンソールから各種リソースを参照する際には、以下のような URL の形式で API リクエストが実行されていることがわかりました。(一部抜粋)
- https://ap-northeast-1.console.aws.amazon.com/ec2/ecb/elastic/?call=com.amazonaws.ec2.AmazonEC2.DescribeInstances - https://ap-northeast-1.console.aws.amazon.com/ec2/ecb/elastic/?call=com.amazonaws.ec2.AmazonEC2.DescribeNetworkInterfaces - https://ap-northeast-1.console.aws.amazon.com/p/log/1/cloudwatch/1/OP/&k0=GetMetricData_Time&m0=105151&cb=1627464726415
それぞれ以下の API を呼び出しているようです。
- DescribeInstances
- DescribeNetworkInterfaces
- GetMetricData
直接実行
以下の宛先への通信も付随して発生していました。サービスエンドポイント そのものですね。
https://logs.ap-northeast-1.amazonaws.com/
https://monitoring.ap-northeast-1.amazonaws.com/
後者を例に取ると、以下のようなヘッダーを持つ POST リクエストが実行されていました。
フィールド名 | 値 |
---|---|
Referer | https://ap-northeast-1.console.aws.amazon.com/ |
User-Agent | (省略) |
authorization | AWS4-HMAC-SHA256 Credential=ASIAXXXXXX/20210728/ap-northeast-1/monitoring/aws4_request |
content-type | application/x-amz-json-1.0 |
sec-ch-ua | Chromium;v="91" |
sec-ch-ua-mobile | ?0 |
x-amz-console-signature | xxxxxxx |
x-amz-date | 20210728T092800Z |
x-amz-security-token | xxxxxxx |
x-amz-target | CloudWatchVersion20130116.GetMetricData |
最下段から、GetMetricData
の API を実行するものであることが読み取れます。
今回の環境ではクライアントは VPC 内 DNS (Route53 リゾルバー)を参照していますので、 monitoring.ap-northeast-1.amazonaws.com
を名前解決すると VPC エンドポイントが持つプライベート IP アドレスが返却されます。
よって、上記のようなリクエストは VPC エンドポイントを経由することになる……という状況でした。面白いですね。
すべてがマネジメントコンソール経由ではない
マネジメントコンソール上での操作による API リクエストはすべてそちらを経由して行われるものとずっと思い込んでいました。そうではありませんでした。
直接サービスエンドポイント宛に通信が行われれることが問題になるケースはそこまで多くないと思いますが、今回のようにいくつか条件が重なると思わぬ落とし穴にハマることもあります。
「権限は問題ないのになぜかエラーが出る……!」という事態に陥ったとき、切り分け材料の一つとして思い出していただければ幸いです。
以上、 チバユキ (@batchicchi) がお送りしました。