亚马逊AWS官方博客
客户 Amazon VPC 内部资源和服务的相互访问
内容摘要
本文是“在亚马逊云科技上围绕 Amazon VPC 打造内外兼修的合适架构”系列主题的第一部分,我们从客户 VPC 内部讲起,主要讲述在 VPC 中,亚马逊云科技如何设计其网络部分,如何在满足安全管控的条件下,达到内部资源和服务的相互访问。
对 Amazon VPC 中内部网络的理解,是理解 VPC 内部资源和外部托管服务相互访问的重要前提。这是由于无论是客户 VPC 内部资源访问外部托管服务,还是外部的托管服务访问客户 VPC 内部的资源,大部分情况下都是通过在 VPC 内部生成弹性网络接口 ENI 进行通信交互的。
本系列专题由如下几部分组成:
- 引论部分:在亚马逊云科技上围绕 Amazon VPC 打造内外兼修的合适架构。
- 第一部分(本篇):客户 Amazon VPC 内部资源和服务的相互访问。
- 第二部分:从客户 Amazon VPC 内部访问外部亚马逊云科技托管服务。
- 第三部分:从托管服务 Amazon Lambda 访问客户 Amazon VPC 内部私有资源。
- 第四部分:从托管服务 Amazon Glue 访问客户 Amazon VPC 内部私有数据存储。
- 第五部分:从托管服务 Amazon API Gateway 集成 Amazon VPC 内部私有服务。
- 第六部分:在亚马逊云科技上打造无服务器 Serverless 应用。
- 第七部分:从客户 Amazon VPC 访问其他客户 Amazon VPC 内的服务或资源。
- 第八部分(总结):在亚马逊云科技上打造合规的应用架构。
场景介绍
客户在 Amazon VPC 可以定义自己完全控制的私有虚拟网络环境。为了更好的对内部的网络环境进行控制,可以对 VPC 内部进行区域的划分,不同的区域有不同的网络安全标准,这个区域叫做子网(Subnet)。这些子网,通过本地路由实现互联互通。通过子网中的 Network ACL 还可以对进出该子网的网络进行安全控制,以达到对子网区域的网络统一管控。处于该子网中的 EC2 实例的网络交互,都会受到子网 Network ACL 的控制。对于 VPC 中的 EC2 或 RDS 来说,除了子网,还可以通过设定安全组(Security Group),进一步提高 EC2 实例的网络安全性。
如果我们把 VPC 比做一个公园,那么子网 Subnet 更像是这个公园中的不同区域,这些区域由于重要性的不同因而会有不同的访问策略(有的年票可以进入,有的则不可以,有的暂不开放)。 VPC 中的路由表(Route Table)定义了网络转发的规则,确保了网络的畅通。就像的公园中的道路指示牌一样,标识出到某个景点(Destination)需要走哪条路,搭哪辆旅游车(Target)。因此,路由决定着网络在访问的时候流量的走向。路由表中的路由中,最重要的信息就是目的地和目标:
- 目的地(Destination): 希望流量传输到的 IP 地址范围,例如目的地 CIDR。
- 目标(Target): 用于发送目的地流量的网关、网络接口或连接,例如互联网网关 IGW-ID,或者 VGW-ID 等。
VPC 在创建后,会包含有一个主路由表,该主路由表包含了一条缺省的本地路由,和 VPC 内部所有的子网隐式关联,因而确保了在 VPC 内部底层网络的相互联通。我们也可以创建新的路由表,并和子网进行显式关联。当子网没有显式地和任何路由表关联的时候,默认会采用主路由表。
配置实验环境
本章节中,我们通过详细的实验步骤来探究 VPC 中的网络安全配置。而且该实验环境是我们进行本专题后续一系列实验的基础。
如下图所示,我们在 VPC “TEST” 中创建了公有子网 “TEST Public Subnet(AZ1)” 和私有子网 “TEST Private Subnet(AZ1)”。同时,我们创建了路由表 “TEST Public Routes” 和 “TEST Private Routes” 分别和子网 “TEST Public Subnet(AZ1)” 以及子网 “TEST Private Subnet(AZ1)” 关联。
如下图所示,由于主路由表和各个子网隐式关联,因此,上述两个路由表中都可以看到一条本地路由,这条本地路由的目的地(Destination)为 VPC 关联的 CIDR 10.192.0.0/16
,目标(Target)为 local
, 这里 local 代表一个用于在 VPC 内部通信的本地路由。公有子网 “TEST Public Subnet(AZ1)” 中的路由表除了这条本地路由,还有一条通向互联网网关 IGW 的路由可以和互联网进行直接通信。
私有子网 “TEST Private Subnet(AZ1)” 中的路由表只有这条本地路由。
由于上述两个路由表都隐式含有本地可以通信的路由,因而公有子网 “TEST Public Subnet(AZ1)” 中的 EC2 实例可以访问私有子网 “TEST Private Subnet(AZ1)” 中的数据库 Amazon RDS 实例。
在 VPC 内部,还可以通过定义网络控制列表(Network ACLs)和安全组(Security Group)来达到对网络流量的进一步控制。
- Network ACL 和子网关联,允许或拒绝子网级别的特定入站或出站流量,这样为子网中的实例提供了有一层网络保护。不同的子网有不同的路由配置,也面临着不同的风险,因此可以配置不同的 Network ACL 来防范不同的风险。Network ACL 默认允许所有流量,支持创建允许和拒绝的规则,按照规则号的排序进行评估。Network ACL 是无状态的,所以要返回网络请求,除了出站规则,还需要单独配置入站规则以允许返回流量。
- 和 Network ACL 不同,安全组作用于实例本身,默认为拒绝,只有显式配置允许的规则,方可允许流量通过。同时安全组是有状态的,允许出站就意味着可以返回网络请求。 另外安全组还可以将别的安全组作为配置安全规则中的源或目标。
如下图所示,VPC 中的 EC2 若要访问 RDS,需要经过多重的网络安全检查。VPC 中的两个子网,子网 “TEST Public Subnet(AZ1)” 的 CIDR 为 10.192.10.0/24
,子网 “TEST Private Subnet(AZ1)” 的 CIDR 为 10.192.20.0/24
,分别和网络控制列表 “Network ACL 1”,以及网络控制列表 “Network ACL 2” 相关联。位于子网 “TEST Public Subnet(AZ1)” 中的 EC2 实例和安全组 “ec2-sg” 相关联,位于子网 “TEST Private Subnet(AZ1)” 中的 RDS 实例和安全组 “rds-sg” 关联。
EC2 实例要访问 RDS 实例的端口 3306 时,需要依次满足如下安全组和 Network ACL 的规则配置。
- 安全组 “ec2-sg” 的 Outbound Rule,允许在端口 3306,目标为安全组 “rds-sg” 的出站流量。
Security Group “ec2-sg” Outbound Rule | ||||||
Protocol | Port range | Destination | Description | |||
TCP | 3306 | rds-sg | 允许 ec2 发起在端口 3306 的出站流量访问 RDS MySQL。 |
- “Network ACL 1” 的 Outbound Rule,允许在端口 3306,目标为子网 “TEST Private Subnet(AZ1)” 的 CIDR 块
10.192.20.0/24
的出站流量。
“Network ACL 1” Outbound Rule | ||||||
Rule # | Type | Protocol | Port range | Destination | Allow/Deny | Comments |
100 | HTTP | TCP | 3306 | 10.192.20.0/24 | ALLOW | 允许发送到子网 TEST Private Subnet(AZ1) 在端口 3306 的全部出站流量。 |
* | All traffic | All | All | 0.0.0.0/0 | DENY | 拒绝前面的规则尚未处理的所有出站 IPv4 流量(不可修改)。 |
- “Network ACL 2” 的 Inbound Rule,允许在端口 3306,来自子网 “TEST Public Subnet(AZ1)” 的 CIDR 块为
10.192.10.0/24
的访问入站流量。
“Network ACL 2” Inbound Rule | ||||||
Rule # | Type | Protocol | Port range | Source | Allow/Deny | Comments |
100 | HTTP | TCP | 3306 | 10.192.10.0/24 | ALLOW | 允许来自于子网 TEST Public Subnet(AZ1)在端口 3306 的全部入站流量。 |
* | All traffic | All | All | 0.0.0.0/0 | DENY | 拒绝前面的规则尚未处理的所有入站 IPv4 流量(不可修改)。 |
- 安全组 “rds-sg” 的 Inbound Rule,允许在端口 3306,来自安全组 “ec2-sg” 的入站流量。
Security Group “rds-sg” Inbound Rule | |||
Protocol | Port range | Source | Description |
TCP | 3306 | ec2-sg | 允许来自 ec2 所在的安全组中的实例在 3306 端口访问 RDS MySQL 的入站流量。 |
- “Network ACL 2” 的 Outbound Rule,允许端口从 1024 到 65535,目标为子网 “TEST Public Subnet(AZ1)” 的 CIDR 块为
10.192.10.0/24
的返回出站流量。
“Network ACL 2” Outbound Rule | ||||||
Rule # | Type | Protocol | Port range | Destination | Allow/Deny | Comments |
100 | HTTP | TCP | 1024-65535 | 10.192.10.0/24 | ALLOW | 允许返回给子网 TEST Public Subnet(AZ1)的范围从 1024 到 65535 的临时端口的全部出站流量。 |
* | All traffic | All | All | 0.0.0.0/0 | DENY | 拒绝前面的规则尚未处理的所有出站 IPv4 流量(不可修改)。 |
- “Network ACL 1” 的 Inbound Rule,允许端口从 1024 到 65535,来自子网 “TEST Private Subnet(AZ1)” 的 CIDR 块为
10.192.20.0/24
的返回入站流量。
“Network ACL 1” Inbound Rule | ||||||
Rule # | Type | Protocol | Port range | Source | Allow/Deny | Comments |
100 | HTTP | TCP | 1024-65535 | 10.192.20.0/24 | ALLOW | 允许从子网 TEST Private Subnet(AZ1) 返回的范围从 1024 到 65535 的临时端口的全部入站流量。 |
* | All traffic | All | All | 0.0.0.0/0 | DENY | 拒绝前面的规则尚未处理的所有入站 IPv4 流量(不可修改)。 |
从上面的配置可以看到,我们不需要配置安全组 “ec2-sg” 的 Inbound Rule,也不需要配置安全组 “rds-sg” 的 Outbound Rule,因为安全组是有状态的,流量能进来就可以出去,反之亦然。而网络控制列表 “network ACL 1” 和 “network ACL 2” 是无状态的,需要分别配置 Inbound Rule 和 Outbound Rule。对于访问流量,需要配置访问目标的端口,对于返回流量则需要配置返回流量可能用到的临时端口范围。
以上配置是在极尽严苛条件下的实例配置,在实际应用中,可以根据实际情况选择配置,或者配置较大范围的规则。
初始化 RDS 数据库
我们通过 SSH 命令连接到 EC2,并执行如下的命令来创建数据库和表,创建的数据会作为我们系列专题中的实验数据源。这里注意,若要通过 SSH 命令连接到 EC2 需要在安全组 “ec2-sg” 的 Inbound Rule 和网络控制列表 “Network ACL 1” 的. Inbound Rule 以及 Outbound Rule 中增加新的规则,以允许从访问地址 IP 能够访问 EC2 的 22 端口,并获得返回网络流量。当然在本系列的“第二部分:从客户Amazon VPC内部访问外部亚马逊云科技托管服务”中,我们还会讲到如何通过 Amazon SSM 服务访问 EC2。
- 在 EC2 实例中运行如下命令安装 MySQL 客户端:
- 执行如下的命令通过用户
dbuser
连接到创建的 RDS,并输入密码dbpassword
。
- 执行如下的命令创建数据库 “myDatabase”:
- 执行如下的命令创建表 “employees”:
- 执行如下脚本,在数据表 “employees” 中插入初始化数据:
可见,在设定的网络条件下,EC2 可以成功地访问 RDS,并创建数据库,初始化数据表,我们也可以修改 Network ACL 或安全组,来进行测试这些安全管控措施的有效性。
在实际部署中,为了高可用,EC2 和 RDS 都可能会采用多可用区部署,因而会在不同 AZ 的不同子网中,在设置 Network ACL 时需要特别注意。
结论和总结
本篇验证了 VPC 内部通过路由表,实现网络联通,通过子网的 Network ACL 和实例的安全组实现网络管控,进而达到网络风险的可控。
VPC 中默认的路由表,保证了 VPC 中的实例可以通过弹性网络接口 ENI 进行相互访问,并在访问的过程中会受到网络访问控制列表 Network ACL 和安全组 Security Group 的安全控制。VPC 中 ENI 之间的相互连接访问是我们后面其他部分专题分析的基础。
本实验中,我们成功的在 VPC 中配置了较高安全防护措施,通过精确设置,确保只有被允许的流量能够通行。在配置 Network ACL 和安全组的时候需要特别注意:Network ACL 默认是允许的,而且是无状态的,所以需要注意同时配置 Inbound 和 Outbound 的允许规则,才能真正允许网络通行。而安全组默认是拒绝的,而且是有状态的,因此只需要根据实例是网络请求的发起者还是接受者的实际情况,配置 Outbound 或 Inbound 的规则。
在后面的部分中,为了方便实验,我们假设子网配置允许所有的入站和出站流量,所以对于网络的连接,我们重点考虑安全组的配置即可。
参考链接
Internetwork traffic privacy in Amazon VPC
https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html#VPC_Security_Comparison
Control traffic to subnets using Network ACLs
https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html
Security group rules for different use cases
Configure route tables
https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Route_Tables.html