AWS VPCエンドポイントを介して通信しているか確認するには?

2022.11.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

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

参考