在VPC中,我有两个子网,一个是带有EC2实例的公共子网,另一个是一个带有2个EC2实例的私有子网。所有3个EC2实例都具有访问S3的IAM角色相同的角色。
如果我登录并运行aws s3 ls
,则公共子网中的EC2实例可以直接访问S3。但是,私有子网中的两个EC2实例都不能。有什么原因?
ec2在私有子网中使用一个安全组,该组接受整个VPC的流量。
公共子网中的ec2使用一个安全组,该组接受 awhere 的流量。
所有3个EC2实例都使用相同的路由表,相同的NACL,使用相同的IAM角色,与该策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
如果我在私有子网中的EC2中手动创建凭据配置文件,则可以登录并访问" AWS S3 LS"。
更新:私有子网的路由表确实具有VPC端点。路由表是:
- dest = 10.1.0.0/16(myvpc) -> target = local
- dest = 0.0.0.0/0,target = igw
- dest = pl-68a54001(com.amazonaws.us-west-2.s3) -> target = vpce-26cf344f
其中,#3表示EC2可以通过VPC端点访问S3。添加#2是因为ELB在EC2实例的前面,并且必须访问Internet。
另一个观察结果:如果我启用在私有子网中分配公共IP ,然后启动一个新的EC2实例,则此EC2实例可以访问S3。如果我禁用专用子网中的公共IP,然后启动一个新的EC2实例,则新的EC2实例无法访问S3。
顺便说一句,在运行Terraform之前,我已经将区域设置为Us-West-2:
[ec2-user@ip-XXXXX]$ echo $AWS_DEFAULT_PROFILE
abcdefg
[ec2-user@XXXXX]$ aws configure --profile abcdefg
AWS Access Key ID [****************TRM]:
AWS Secret Access Key [****************nt+]:
Default region name [us-west-2]:
Default output format [None]:
当实例具有公共IP地址时您的解决方案有效,但是当它具有公共IP地址时不起作用,这表明实例实际上是在公共子网中。
确实,查看"私人子网的路由表",您包括此行:
2. dest=0.0.0.0/0, target=iGW
这使子网A 公共子网,因为它指向Internet网关。
澄清:
- a 公共子网是一个子网,带有路由表条目,指向Internet网关
- a 私有子网是一个子网,带有路由表, 指向Internet Gateway
因此,如果您实际上希望它们是私人的,则应从私人子网的路由表中删除上述条目。
接下来,看来您的aws s3 ls
请求未发送到VPC端点。这可能是因为您未将流量发送到路由表中列出的s3.us-west-2.amazonaws.com
。尝试此命令:
aws s3 ls --region us-west-2
将将请求发送到将通过VPC端点路由的S3端点。您应该将所有S3命令指向该区域,因为VPC端点仅指向其配置的区域。
当您将EC2放置在私有子网中时,网络级别将无法访问S3(IAM策略不是问题)。为了允许从私有子网中的EC2实例访问S3,您有以下选项。
- S3的VPC端点
- nat Gateway
在这两种方法中,如果您计划仅允许从私有子网中的EC2实例访问S3,请为S3配置VPC端点。