我使用 CloudFormation 向我的 VPC 添加了一个 VPC 终端节点,并允许使用 s3。路由在 AWS 控制台中可见,但在 EC2 实例的本地路由表中不可见:
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.29.4.129 0.0.0.0 UG 0 0 0 eth0
169.254.169.254 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
172.29.4.128 0.0.0.0 255.255.255.128 U 0 0 0 eth0
如何验证 VPC 中的 EC2 实例实际使用 S3 的 VPC 终端节点,而不是可用的互联网连接?
我想直接的方法是实际探测这些路线。
您可以跟踪路由到 s3 并查看 NAT 网关的内部 IP 是否在输出中的任何位置(例如第一跳)。
首先,在控制台中检查 NAT 网关内部 IP 。
带有端点集的示例输出 - 未显示网关 IP。这是你想看到的。
不同目的地的示例输出,通过 NAT(见第一跳)
我找到了一种验证 VPC 终端节点使用情况的方法。
aws ec2 describe-prefix-lists
;对于Windows PowerShell,Get-EC2PrefixList
结果应在属性中包含 VPC 终端节点前缀列表 ID
PrefixListId
。如需进一步验证,您可以将以下策略应用于 S3 存储桶:
使用您的 vpc ID 而不是 vpc-121212。然后,您应该只能从给定的 VPC 访问 S3 存储桶
您可以打开 S3 日志记录并检查文件是否从您的私有 IP 而不是公共 IP 访问。如果您的日志记录显示私有 IP 正在访问您已正确配置的存储桶。祝你好运!
我建议在没有 Internet 访问权限的子网中启动 ec2 实例(允许 IAM 角色列出 s3 存储桶)。
路由表中基本上只有 2 个活动规则(您的 VPC 子网范围和 s3 端点)。
连接到实例并运行命令:
它应该会因超时而失败,因为默认情况下 boto 会创建对全局 s3 url (s3.amazonaws.com) 的请求。
应该列出您在 us-east-1 区域中的存储桶(vpc 路由器会将您的请求路由到 s3.us-east-1.amazonaws.com)。
您的实例将发往 S3 的数据包转发到本地网关,然后 VPC“路由器”从那里将它们转发到 S3 终端节点。不需要客户端配置或知识。
您可以使用一组非常严格的 ACL 配置 S3 端点,以便它拒绝所有请求并观察您的客户端也收到故障。
@m-glatki 的答案(由于某种原因被接受)实际上是不正确的。
首先,您必须显式启用 ec2 VPC 接口才能执行
aws ec2 describe-prefix-lists
调用,否则您将获得超时。其次,即使您可以调用该 API,它也不会告诉您是否正在通过该端点路由您的流量。它仅提供有关当前区域中特定前缀列表 (PL) 的详细信息。
您需要做的是将 S3 VPC 端点与子网的路由表相关联,并确保您的 EC2 实例或服务的安全组允许通过该端点进行出口连接(您应该可以使用默认的“允许所有”出口规则)。这将通过端点路由 S3 流量,即使您连接了 NAT 网关。
您可以通过检查其关联的 cloudwatch 日志来验证您的流量是否未通过 NAT 路由(请参阅BytesOutToDestination、BytesOutToSource、BytesInFromDestination和BytesInFromSource指标)
还要检查@michael 正确指出的 S3 存储桶日志。
详细说明@m-glatki 解决方案,在存储桶上添加一个限制 S3 访问特定 VPC 端点的策略:
您将只能从使用 VPC 终端节点的进程中列出存储桶内容。否则,您将收到一条消息:
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
要获取 VPC 终端节点 ID,请使用以下命令:
aws ec2 describe-vpc-endpoints
看到这个链接