AWS VPCエンドポイントを介して通信しているか確認するには?
VPCエンドポイントを用意したときに、インターネットを経由せずにAWSサービスにアクセスできていることを確認する方法を紹介します。
確認対象のVPCエンドポイントの種類
今回は、VPCエンドポイントのスコープをゲートウェイ型とインターフェイス型のエンドポイントに限定し、Gateway LoadBalancer型は対象外とします。
インターフェース型
現在主流のエンドポイントです。サブネットにエンドポイントサービス向けのElastic Network Interface(ENI)を作成します。
Reachability Analyzer を利用すると、EC2のENIはインターフェイス型VPCエンドポイントのENIと通信していることがわかります。
例として、SNSのエンドポイントを作成します。
名前解決で確認
利用環境からサービスエンドポイントを名前解決し、プライベートIPアドレスを返せば成功です。
$ dig +short sns.ap-northeast-1.amazonaws.com. 10.30.134.227
これはエンドポイントで作成された ENI の IP アドレスです。
VPCエンドポイントの "Enable private DNS names" がチェックされていないと、グローバルIPアドレスを返すので、ご注意ください。
なお、VPC外(AWS CloudShellなど)から名前解決すると、グローバルIPアドレスを返します。
CloudTrail で確認
APIを実行し、CloudTrail から確認することも可能です。
$ aws sns list-topics
CloudTrail ログを確認し、vpcEndpointId
フィールドが存在すれば成功です。
{ "eventVersion": "1.08", ... "eventSource": "sns.amazonaws.com", "eventName": "ListTopics", "sourceIPAddress": "10.30.0.160", ... "vpcEndpointId": "vpce-01251def6b627a209", ... }
sourceIPAddress
もプライベートIPアドレスなことを確認できますね。
接続性で確認
名前解決とCloudTrailを使う方法は、プライベート・パブリックのサブネットの違いに関係なく使えます。
プライベートサブネット限定の確認方法として、インターネットと通信できない(例:ping
が通らない)にもかかわらず、APIを実行できれば成功です。
$ ping -c 1 www.amazon.com PING d3ag4hukkh62yn.cloudfront.net (108.138.10.130) 56(84) bytes of data. --- d3ag4hukkh62yn.cloudfront.net ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms $ aws sns list-topics { "Topics": [ ... }
プライベートサブネットからNAT経由でインターネットと通信できる場合、この方法は使えません。
CloudWatch メトリクスで確認
インターフェース型VPCエンドポイントが利用するAWS PrivateLink はデータポイントをAmazon CloudWatchに発行します。
https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-cloudwatch-metrics.html
例えば、VPCエンドポイント経由で確立された新しい接続の数(NewConnections
)は
- Endpoint Type(
Interface
) - Service Name(
com.amazonaws.リージョン.サービス名
) - VPC Endpoint Id
- VPC Id
- (サブネット Id)
のディメンションがあります。
メトリクスにデータポイントを確認できれば、成功です。
このメトリクスはGateway Load Balancer エンドポイントやエンドポイントサービスでも利用できます。
なお、メトリクスからPrivateLinkの利用状況はわかるものの、PrivateLinkを利用する各通信の詳細はわからないことにご留意ください。
ゲートウェイ型
S3とDynamoDBで利用可能なレガシーなエンドポイントです。利用側のルーティングにより、サービスエンドポイントへのトラフィックをゲートウェイに向けます。AWS PrivateLinkは作成されません。
Reachability Analyzer を利用すると、EC2のENIはゲートウェイ型VPCエンドポイントにルーティングされていることがわかります。
例として、S3のゲートウェイ型のエンドポイントを作成します。
名前解決では確認できない
利用環境からサービスエンドポイントを名前解決すると、グローバルIPアドレスが返るため、判別できません。
$ dig +short s3.ap-northeast-1.amazonaws.com 52.219.152.100 ...
CloudTrail で確認
APIを実行し、CloudTrail から確認します。
$ aws s3 ls s3://YOUR-BUCKET/
CloudTrail ログを確認し、vpcEndpointId
フィールドが存在すれば成功です。
{ ... "eventSource": "s3.amazonaws.com", "eventName": "ListBuckets", ... "sourceIPAddress": "10.30.0.160", ... "vpcEndpointId": "vpce-0554e2f536c2ae78c", ... }
sourceIPAddress
がプライベートIPアドレスなことも確認できますね。
接続性で確認
CloudTrailを使う方法は、プライベート・パブリックのサブネットの違いに関係なく使えます。
プライベートサブネット限定の確認方法として、インターネットと通信できない(例:ping
が通らない)にもかかわらず、APIを実行できれば成功です。
$ ping -c 1 www.amazon.com PING d3ag4hukkh62yn.cloudfront.net (108.138.10.130) 56(84) bytes of data. --- d3ag4hukkh62yn.cloudfront.net ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms $ aws s3 s3://YOUR-BUCKET/ ...
NAT経由でインターネットと通信できる場合、この方法は使えません。
S3アクセスログから
S3限定ではありますが、S3バケットのサーバーアクセスログを有効にし、接続元のIPアドレスで判別する方法もあります。
Key | Value |
---|---|
Bucket Owner | 0086... |
Bucket | BUCKETNAME |
Time | [04/Nov/2022:11:35:46] |
Remote IP | 10.30.136.135 |
Requester | 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be |
Request ID | 3E57427F33A59F07 |
Operation | REST.GET.BUCKET |
Key | - |
Request-URI | "GET /?list-type=2&delimiter=%2F&prefix=&encoding-type=url HTTP/1.1" |
HTTP status | 200 |
... | - |
ログのRemote IP
フィールドがプライベートIPアドレス(10.30.136.135
)なことも確認できますね。
参考
最後に
最後に、エンドポイント型別に利用可能な方法を整理します。
エンドポイント型 | 名前解決 | CloudTrail |
---|---|---|
インターフェース型 | ○ | ○ |
ゲートウェイ型 | X | ○ |
なお、VPCエンドポイントを利用しない場合、通信はインターネットを経由する一方で、AWSグローバルネットワークに閉じています。
AWSのグローバルIPの空間はインターネットなのか? - NRIネットコムBlog
VPCエンドポイントを使うときは、その狙いも明確にしましょう。
AWS PrivateLink・VPCエンドポイントを利用するメリットやユースケースを整理してみた | DevelopersIO