亚马逊AWS官方博客
从客户 Amazon VPC 访问外部亚马逊云科技托管服务
专题摘要
亚马逊云科技有很多的无服务器的托管服务,这些服务具有高可用性,高弹性和普遍性。从客户 VPC 内部访问外部的托管服务,几乎是必然的,也只有这样才能更有效地利用云上的优势。因此在继前面的第一部分讲述了 VPC 内部的资源相互访问后,我们需要考虑如何和外部的托管服务进行连接,以及访问这些服务的网络安全以及所需要的额外配置。
本文是“在亚马逊云科技上围绕 Amazon VPC 打造内外兼修的合适架构”系列主题的第二部分。主要讲述在亚马逊云科技中,如何从客户 VPC 中访问外部亚马逊云科技的托管服务。
本系列专题由如下几部分组成:
- 引论部分:在亚马逊云科技上围绕 Amazon VPC 打造内外兼修的合适架构。
- 第一部分:客户 Amazon VPC 内部资源和服务的相互访问。
- 第二部分(本篇):从客户 Amazon VPC 内部访问外部亚马逊云科技托管服务。
- 第三部分:从托管服务 Amazon Lambda 访问客户 Amazon VPC 内部私有资源。
- 第四部分:从托管服务 Amazon Glue 访问客户 Amazon VPC 内部私有数据存储。
- 第五部分:从托管服务 Amazon API Gateway 集成 Amazon VPC 内部私有服务。
- 第六部分:在亚马逊云科技上打造无服务器 Serverless 应用。
- 第七部分:从客户 Amazon VPC 访问其他客户 Amazon VPC 内的服务或资源。
- 第八部分(总结):在亚马逊云科技上打造合规的应用架构。
场景介绍
在很多的实际场景中,我们需要从 VPC 内部的 EC2 实例或者容器等访问外部的亚马逊云科技托管服务,例如:
- 应用程序访问 Amazon S3 以读取或写入非结构化的图像等静态数据,或者运行数据库的实例需要向 S3 备份数据。
- 访问 Amazon DynamoDB,将热数据存储到 DynamoDB 中。
- 将信息发送到 Amazon SQS 或者 Amazon SNS 的某个 Topic,用于消息通知。
- 调用某个 Amazon Lambda 函数完成某些特定操作。
- 为了应用的安全,访问 Amazon Secrets Manager 来获取数据库的用户和密码。
- 调用 Amazon Key Manager 的 API,对数据进行加密或解密。
- 将应用程序生成的指标或者日志输出到 Amazon Cloud Watch 中。
- 通过 API 发起 Amazon Glue 的某个 Job 作业调用,或者获取某个 Job 的执行状态。
- 调用其他 Amazon API Gateway 对外暴露的接口,以满足业务特定需求。
- 为了提高安全性,将 EC2 接受 Amazon Systems Manager 进行管理,并能通过 Session Manager 进行访问。
- 数据科学家通过 VPC 内部 EC2 实例私有访问 SageMaker Notebook 实例服务。
上述这些亚马逊云科技的托管服务,都可以通过互联网直接调用公有的 API 端点进行访问。公有子网的实例可以直接通过 IGW 访问互联网,而私有子网中的实例可以通过部署在公有子网中的 NAT 网关连接互联网。但在某些条件下发起调用的实例并不能访问互联网。例如:
- 当客户的应用不需要对互联网用户服务,或者在私有子网中没有通过 NAT 访问互联网的路由,因此客户 VPC 内部 EC2 上的应用无法通过互联网访问这些 VPC 外部的托管服务。
- 客户内部安全策略对 VPC 与互联网之间的通信有严格的限制规定,访问这些服务的流量不能通过互联网,流量必须保留在亚马逊云科技网络内部,以保证网络访问的合规性。
在这种情况下,通常需要创建 VPC 终端节点(VPC Endpoint),通过终端节点建立 VPC 本地网络和亚马逊云科技托管服务的专用连接。下图中,不需要连接互联网的情况下,通过 VPC 的终端节点,就可以访问到这些托管服务的终端节点服务(Endpoint Service),以保证访问的私密性。VPC 终端节点是虚拟设备,具有原生的可扩展性、弹性、安全性和访问控制。通过终端节点访问托管服务,还可以在终端节点中配置相应的策略(IAM Policy)来控制私密链接的使用,例如:只允许访问该托管服务的某些接口,使访问更加安全。
在客户 VPC 中可以创建两种终端节点,包括网关终端节点(Gateway Endpoint)和接口终端节点(Interface Endpoint),前者只支持 Amazon DynamoDB 和 Amazon S3 服务, 后者支持除 Amazon DynamoDB 外的服务,并且所支持的服务列表在不断完善中。其中,网关终端节点会在 VPC 的路由表里面进行路由配置,以通过终端节点访问相关的服务。而接口终端节点通过 DNS 访问相关的弹性网络接口 ENI,通过 PrivateLink,对服务方(终端节点服务)发起服务请求,因此需要能够在 VPC 中正确解析终端节点服务的 DNS。
一般情况下,只要 VPC 启用了私有 DNS(enableDnsHostnames = true, enableDnsSupport = true),终端节点启用私有 DNS 名称选项,服务本身默认的 DNS 主机名会被解析为终端节点网络接口的私有 IP 地址,以访问托管服务,因此不需要修改任何配置。另外,接口终端节点,由于是基于弹性网卡 ENI 进行工作,所以可以通过安全组(Security Group)来控制网络流量。
目前,在中国区支持的接口终端节点列表,参见如下链接:
- 北京区域(
cn-north-1
)支持的接口终端节点列表:https://docs.amazonaws.cn/en_us/aws/latest/userguide/endpoints-Beijing.html - 宁夏区域(
cn-northwest-1
)支持的接口终端节点列表:https://docs.amazonaws.cn/en_us/aws/latest/userguide/endpoints-Ningxia.html
在北京区域通过 Amazon CLI 执行如下的命令可以查看 cn-north-1
区域的终端节点服务:
该命令输出结果如下:
同样在宁夏区域通过 Amazon CLI 执行如下的命令可以查看 cn-northwest-1
区域的终端节点服务:
该命令输出结果如下:
通过比较发现,这两个区域中所支持的 Endpoint 列表并不是完全一样的。例如 cn.com.amazonaws.cn-northwest-1.account
只在宁夏区域存在,在北京区域并不存在该终端节点服务。而且这个列表还在不断完善中,所以在使用时,需要及时查看所支持的最新列表。
另外值得一提的是,在中国区,虽然访问这些终端节点的域名都为: ${name}.${region}.amazonaws.com.cn
。但是终端节点服务名称的命名方式却和全球区域的命名方式既有相同的地方,又有不同的地方。
- 极少部分和 Amazon SageMaker 相关的服务终端节点服务名称以 “aws.sagemaker” 开头,例如 Amazon SageMaker Notebook 的终端节点服务名称为
"aws.sagemaker.cn-northwest-1.notebook"
。 - 少部分服务的终端节点服务名称以 “com.amazonaws” 开头,例如 Amazon SNS, amazon SSM 的终端节点服务名称为
"com.amazonaws.cn-northwest-1.sns"
。 - 大部分服务的终端节点服务名称以 “cn.com.amazonaws” 开头,例如 Amazon SQS 的终端节点服务名称为
"cn.com.amazonaws.cn-northwest-1.sqs"
。
而在全球区域中,往往只按照前两种命名方式命名。因此如果在中国区 CloudFormation 来构建 VPC 终端节点资源,需要特别注意这一点。需要确保该终端节点在所在的区域受支持,而且服务名称正确。例如,下图所示在 CloudFormation 创建中国区 Amazon SQS 的终端节点:
配置实验环境
本实验中,我们将通过私有地连接 VPC 中私有子网中的 Amazon EC2 和 Amazon Systems Manager(SSM)服务,通过 SSM 的 Session Manager 来访问 EC2。
我们会在 VPC 中建立 SSM 的接口终端节点,这样私有子网中的 EC2 实例可以和 SSM 服务进行通信,将私有子网中的 EC2 直接纳入到 SSM 中进行管理和访问。这种方式不需要建立堡垒机,也不需要通过 NAT 网关访问互联网,因而增强了安全性。
VPC 中的 EC2 需要满足如下条件,才能够被 SSM 管理:
- EC2 已经安装了 Systems Manager Agent(SSM Agent),用以建立和 Systems Manager 的连接。
- EC2 有权限访问 Systems Manager,即分配给 EC2 的角色(IAM Role)的权限策略可以访问 “ec2messages:*”,“ssmmessages:*” 和 “ssm:*” 这些 APIs:
- “ssmmessages:*” APIs,用来创建和删除会话通道。
- “ec2messages:*” APIs,用来发送和接收 SSM 命令。
- “ssm:*” APIs,用来在 SSM 中注册托管实例和进行状态检测等。
- EC2 中的 SSM Agent 能够访问 SSM 相关的 API 服务。在不访问互联网的情况下,需要有如下几个终端节点来连接到 SSM 服务和 EC2 的终端节点服务:
- 服务名为 “com.amazonaws.cn-northwest-1.ssmmessages” 的接口终端节点,用于 SSM Agent 调用 Systems Manager 服务中的 “ssmmessages:*” APIs。
- 服务名为 “com.amazonaws.cn-northwest-1.ec2messages” 的接口终端节点,用于 SSM Agent 调用 Systems Manager 服务中的 “ec2messages:*” APIs。
- 服务名为 “com.amazonaws.cn-northwest-1.ssm” 的终端节点,用于 SSM Agent 调用 Systems Manager 服务中的 “ssm:*” APIs。
本实验中,EC2 实例 “TEST-EC2” 在公有子网 “TEST Public Subnet(AZ1)” 中,我们首先将其变成私有子网,然后我们通过为 VPC 添加访问 SSM 的终端节点来将私有子网中的 EC2 实例纳入到 SSM 中进行管理,如下图所示:
在实验之前,我们根据架构图创建或修改已有的安全组。由于 EC2 会通过终端节点和 Amazon SSM 服务进行通信,因此我们需要修改 EC2 实例的安全组,或者直接为其关联新的安全组 “ec2-ssm-sg”,新的安全组和终端节点关联的安全组 “endpoint-sg” 保持 443 端口畅通。如下所示:
Security Group “ec2-ssm-sg” Outbound Rule | |||
Protocol | Port range | Destination | Description |
TCP | 443 | endpoint-sg | 允许 ec2 发起的在端口 443 访问终端节点所在的安全组的出站流量。 |
Security Group “endpoint-sg” Inbound Rule | |||
Protocol | Port range | Source | Description |
TCP | 443 | ec2-ssm-sg | 允许来自 ec2 所在的安全组在端口 443 访问终端节点的入站流量。 |
在前一部分的实验的基础上,我们做如下的操作:
- 检查 EC2 实例的配置属性,该实例 “TEST-EC2” 在公有子网 “TEST Public Subnet(AZ1)” 中,操作系统为 “Amazon Linux”,因而已经预安装了 SSM Agent。
- 另外,该 EC2 实例绑定了实际例配置文件 “ec2-instance-profile-TEST”,该配置文件对应角色 “SSMECRole”,该角色包含了策略 “AmazonSSMManagedEC2InstanceDefaultPolicy”,该策略具有访问 “ec2messages:*”, “ssmmessages:*” 和 “ssm:* ” 这些 APIs 的权限。
- 由于实例在公有子网中,可以直接通过互联网访问相关托管服务的公有端点 API,因此是可以通过 Amazon SSM 进行访问的。我们将公有子网 “TEST Public Subnet(AZ1)” 关联的路由表 “TEST Public Routes” 中通向 Internet 互联网的路由删除,只剩下本地路由,这样该公有子网实际上就会变成一个私有子网。
- 这时,由于 EC2 实例上的 SSM Agent 无法访问调用 SSM 中的公有端点 API,因此无法通过 SSM 中的 Session Manager 进行访问。如下图所示:
下面我们通过创建 VPC 接口终端节点,来重新让该实例纳入到 SSM 的管控当中。
- 在该 VPC 中,新建 Systems Manager 的终端节点。在 VPC 服务左侧导航栏里选择【Endpoint】,点击按钮<创建终端节点>。
- 在【创建终端节点】导航中的【终端节点设置】区域 “Name 标签” 中输入名称
endpoint-SSM
,并选择 “服务类别” 为AWS 服务
。
- 在【服务】区域中选择
com.amazonaws.cn-northwest-1.ssm
。
- 在【VPC】和【子网】区域选择 EC2 所处的 VPC 和子网后,点击按钮<创建终端节点>。
- 在【安全组】区域可以选择前面创建的安全组 “endpoint-sg”,该安全组允许来自于 EC2 的 443 端口的入站流量,因而 EC2 可以通过相同的 DNS,将访问请求传给该终端节点的弹性网络接口,通过 PrivateLink 来调用托管服务 SSM 的终端节点服务。
- 可以看到终端节点已经创建成功,同时在该子网中新生成了一个弹性网络接口 ENI,并根据所在子网的 CIDR “10.192.10.0/24” 分配了 IP 地址。
- 我们依照同样的方法,可以创建服务名称为 “com.amazonaws.cn-northwest-1.ssmmessages” 的终端节点
endpoint-SSMMessage
和服务名称为 “com.amazonaws.cn-northwest-1.ec2messages” 的终端节点endpoint-EC2Message
,并等待状态变为可用状态,如下图所示:
- 这时,我们再次连接,就又可以通过 Amazon Systems Manager 中的 Session Manager 继续访问该实例了。
结论和总结
在 VPC 内的 EC2 上或者容器上运行的程序,往往根据业务需求,需要访问各种 VPC 外部的亚马逊云科技的托管服务。而 VPC 的终端节点,提供了在没有互联网连接的条件下,通过建立私有通道,来访问亚马逊云科技托管服务的终端节点服务的措施。由于 VPC 的终端节点还可以配置策略(IAM Policy),因此,无论从网络角度,还是从权限的角度,其安全性无疑更高,更能满足合规要求。
本实验中,在没有互联网的条件下,我们通过创建 VPC 接口终端节点,使得 EC2 能够私有地访问 SSM 相关的终端节点服务,进而可以在 SSM 的 Session Manager 中访问和管理这些 EC2 实例。对于 VPC 内部资源访问其他的 VPC 外部的亚马逊云科技托管服务时,也可以采用类似的方法创建 VPC 终端节点。
VPC 的终端节点有两类,包含网关终端节点和接口终端节点。网关终端节点只支持 Amazon S3 和 Amazon DynamoDB,网关终端节点可以看作是在 VPC 这堵隔离墙上开了一个专用的小门,这个专用门之外有秘密通道可以连接到托管服务,除了创建网关终端节点,还需要通过 VPC 中的路由设定,把相应的访问流量引导到这个专用门(网关终端节点),才能成功访问。另外对于 VPC 中实例的安全组出站规则(如有),也需要通过配置相应的前缀列表 ID 放行。 关于这一点我们会在讲“第四部分:从托管服务 Amazon Glue 访问客户 Amazon VPC 内部私有数据存储”中进行更加详细的介绍。
而接口终端节点则不同,是在 VPC 中按照子网配置生成弹性网络接口 ENI,这个弹性网络接口可以看作是 VPC 中连接托管服务的一个秘密地下通道入口。在 VPC 中是通过 DNS 将访问引导到该 ENI,进而通过 Private Link 访问到托管服务的私有终端节点服务。我们只需要保证 VPC 内部从发起服务请求的 EC2 的弹性网络接口 ENI 到接口终端节点的 ENI,允许在端口 443 传输流量,也即 EC2 所关联的安全组,所在子网关联的 Network ACL,以及 VPC 终端节点的 ENI 所配置的安全组及其所在的子网关联的 Network ACL 允许从 EC2 发起端口 443 的终端节点的请求并能返回即可。
特别提示:
接口类型的终端节点,会在指定的子网内生成弹性网络接口 ENI,并分配 IP, 因此在设计 VPC 和子网的 CIDR 时,需要预留 IP 空间。另外,我们在创建接口类型的终端节点时,为了方便实验,没有考虑在多个可用区设置接口终端节点的 ENI,而在实际的生产环境中,一般会选择不同可用区中的子网,来保证高可用。
接口终端节点在不同的区域,所受支持并不相同,所支持的列表也在不断完善当中。对于中国区域来说,命名规则和全球其他区域并不相同,因而,如果在通过 CloudFormation 中进行创建终端节点时,需要特别注意。
参考链接
Gateway endpoints
https://docs.thinkwithwp.com/vpc/latest/privatelink/gateway-endpoints.html
Interface Endpoint vs Gateway Endpoint vs Gateway Load Balancer Endpoint
https://tutorialsdojo.com/interface-endpoint-vs-gateway-endpoint-vs-gateway-load-balancer-endpoint/
Securely Access Services Over AWS PrivateLink
https://docs.thinkwithwp.com/whitepapers/latest/aws-privatelink/aws-privatelink.html
Amazon Services that integrate with Amazon PrivateLink
https://docs.thinkwithwp.com/vpc/latest/privatelink/aws-services-privatelink-support.html
Share your services through Amazon PrivateLink
https://docs.thinkwithwp.com/vpc/latest/privatelink/endpoint-service.html
Use Amazon PrivateLink to set up a VPC endpoint for Session Manager
Reference: ec2messages, ssmmessages, and other API operations
https://docs.amazonaws.cn/en_us/systems-manager/latest/userguide/systems-manager-setting-up-mess
Choosing Your VPC Endpoint Strategy for Amazon S3
https://thinkwithwp.com/cn/blogs/architecture/choosing-your-vpc-endpoint-strategy-for-amazon-s3/
Isolating network access to your Amazon Cloud9 environments
https://thinkwithwp.com/blogs/security/isolating-network-access-to-your-aws-cloud9-environments/