网络架构综述
安全性是架构设计考虑的重点,所以必须要求所有的机器都放置在VPC当中,而且在VPC当中还需要将不同的部门的不同功能的机器(如应用机器,Web服务器,RDS)划分成不用的子网进行单独管理。
总原则:
- 安全原则:所有的机器都必须放在在VPC当中,以部门和机器功能再细分子网,部门之间以及不同功能的服务器之间访问都是采取最小访问原则。
- 可用原则:生产系统都采取多可用区部署,保证在出现整个机房故障的时候业务系统也能正常运行
VPC设计
在VPC设计上面所遵循的原则是一个区域一个VPC,而不是多个VPC存在于一个区域,目的是为了减少网络的复杂性,但是为了保证VPC内部的机器 还具有更灵活的安全管理,我们需要根据部门、服务器业务类型或者功能的不同在划分子网络进行管理,同时用安全组来保证每一类服务器都能拥有我们想要的安全 策略。
另外访问安全的角度来说,测试系统会开放较大的权限,也就是说开发人员需要有完全的测试系统的登录权限以方便系统开发,所以在设计上同一个区域至少会存在2个VPC,一个生产系统用,另外一个测试系统用。
考虑到各个区域可能在以后可能会有互通的需求,因此在VPC的CIDR设计上也要能区分开来,以保证互通之后不会出现IP地址冲突的情形,根据目前区域情况分配如下:
网络拓扑
+ - - - - - - - - -+ +- - - - - - - - - +
' Infra ' ' Prod '
' ' ' '
' +--------------+ ' ' +--------------+ '
' | 10.25.0.0/16 | ' ----------> ' | 10.20.0.0/16 | '
' +--------------+ ' ' +--------------+ '
' ' ' '
+ - - - - - - - - -+ +- - - - - - - - - +
| ^
| |
| |
v |
+ - - - - - - - - -+ |
' NonProd ' |
' ' |
' +--------------+ ' Deny |
' | 10.21.0.0/16 | ' <---------------+
' +--------------+ '
' '
+ - - - - - - - - -+
阿里云
- 10.20.0.0/16 生产系统, 生产环境相关的服务部署网段
- 10.21.0.0/16 非生产系统, 开发、测试相关服务部署网段
- 10.25.0.0/16 基础设施, 运维基础服务部署网段
VPC 可用区
考虑北京早期的可用区机房比较老可选择的主机类型不多,所以选取H、G、F三个可用区, 多可用区的设计是为了防止 阿里云单独可用区故障时其它可用区的主机可以正常的对外提供服务
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
' DMZ '
' '
' +------------------++------------------++------------------+ '
' | dmz-cn-beijing-h || dmz-cn-beijing-g || dmz-cn-beijing-f | '
' +------------------++------------------++------------------+ '
' '
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
|
|
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
' Applicaiton '
' '
' +------------------++------------------++------------------+ '
' | app-cn-beijing-h || app-cn-beijing-g || app-cn-beijing-f | '
' +------------------++------------------++------------------+ '
' '
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
|
|
|
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
' Database '
' '
' +------------------++------------------++------------------+ '
' | db-cn-beijing-g || db-cn-beijing-h || db-cn-beijing-f | '
' +------------------++------------------++------------------+ '
' '
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
+-----+ +-------------+ +----------+
| DMZ | --> | Application | --> | Database |
+-----+ +-------------+ +----------+
- DMZ类:DMZ区放置的是所有需要直接对外提供服务的机器,也就是说需要直接分配外部IP的,另外诸如NAT、VPN等机器划分到另外一个功能的DMZ区。
- 部门业务类:每个业务部门都按照Application、database功能来划分子网,同一部门的子网之间权限限制更宽松,部门之间的访问遵循最小访问原则。
- 公共业务类:对于运维部署的运维监控等公共服务的机器单独划分不同的VPC。
子网CIDR分配方案
使用部门+功能来进行子网划分会导致子网的数据变得很庞大,所以在确定子网CIDR的时候要确保有足够的子网的数量。
- 使用10.20.0.0/20作为子网CIDR
- 总子网数量
2^(20-16)=128
- 每个子网可用的IP数量
2^(32-20)-2=4094
详细设计
VPC内机器访问模式及应对方法
部门内部分层访问
访问情景:
+ - - - - - -+ +- - - - - - - - - - - - - - - - - - - - - - - -+
' Internet ' ' Aliyun '
' ' ' '
' +--------+ ' ' +----------+ +---------+ +----------+ '
' | user | ' --> ' | Frontend | --> | Backend | --> | Database | '
' +--------+ ' ' +----------+ +---------+ +----------+ '
' ' ' '
+ - - - - - -+ +- - - - - - - - - - - - - - - - - - - - - - - -+
- 同部门前端对于后端的访问
- 同部门后端对于数据库的访问
应对方案:
- 子网内部自由访问
- 同部门子网之间只开放必要的端口
部门之间访问
访问情景:
+-------------+ API Access +-------------+
| departmentA | Database Access | departmentB |
| | <-----------------> | |
+-------------+ +-------------+
- 存在数据库被别的部门调用的情况
- 部门之间API调用的情况
应对方案:
- 在实践当中推广部门之间走API访问而不是直接做数据库调用
- 部门之间的API调用通过防火墙限定访问源和目的,防止滥用的情况发生
运维部门管理机器访问
访问情景:
- 运维人员登录机器进行系统安装配置等操作
- 部分开发人员自己维护的机器需要分配给开发人员登录的权限
应对方案:
- 通过堡垒机做跳板再登录相应的机器进行访问
- 通过连接VPN之后再登录相应的机器进行访问
对外提供服务访问
访问情景:对外提供的Web服务,对外提供的API服务。
+ - - - - - -+ + - - - - - - - - - - - - - - -+
' Internet ' ' Aliyun '
' ' ' '
' +--------+ ' Api ' +------+ +-------------+ '
' | User | ' Web ' | SLB | | Real Server | '
' | | ' -----> ' | | --> | | '
' +--------+ ' ' +------+ +-------------+ '
' ' ' '
+ - - - - - -+ + - - - - - - - - - - - - - - -+
应对方案:所有对外的服务原则上都是使用SLB来提供服务,而不是单独分配外部IP出网,这样提供服务的服务器将不需要放置在DMZ,而是放在私网区,可以加强保障;另外SLB的使用可以很方便的扩展或者迁移提供服务的服务器,提高整个系统的可用性和安全性。
对内提供服务访问
访问情景:
VPN
----->
+ - - - - -+ + - - - - - - - - - - - - - - -+
' Office ' ' Aliyun '
' ' ' '
' +------+ ' Api ' +------+ +-------------+ '
' | User | ' Web ' | SLB | | Real Server | '
' | | ' -----> ' | | --> | | '
' +------+ ' ' +------+ +-------------+ '
' ' ' '
+ - - - - -+ + - - - - - - - - - - - - - - -+
- 供公司员工使用的部署在VPC内部的管理系统
- Jenkins、gitlab、监控等系统的内部访问
应对方案:需要使用相应服务的人员在登录VPN之后可以自由的访问到相应的系统,原则上开发给公司内部人员的系统也是要使用最小访问原则:只开放哪些需要开放的IP及端口。
使用terraform初始化
目录结构
.
├── infra.tf
├── non-prod.tf
├── prod.tf
└── provider.tf
0 directories, 7 files
provider.tf
provider "alicloud" {
access_key = ""
secret_key = ""
region = "cn-beijing"
}
prod.tf
这部分是生成生产环境的terraform脚本,Nonprod和Infra按照下面的脚本修改对应的信息即可
resource "alicloud_vpc" "prod_vpc" {
name = "生产"
cidr_block = "10.20.0.0/16"
description = "VPC for production environment"
}
resource "alicloud_vswitch" "vsw_prod_dmz_f" {
name = "生产-DMZ-F"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.0.0/20"
availability_zone = "cn-beijing-f"
}
resource "alicloud_vswitch" "vsw_prod_dmz_g" {
name = "生产-DMZ-G"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.16.0/20"
availability_zone = "cn-beijing-g"
}
resource "alicloud_vswitch" "vsw_prod_dmz_h" {
name = "生产-DMZ-H"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.32.0/20"
availability_zone = "cn-beijing-h"
}
resource "alicloud_vswitch" "vsw_prod_application_f" {
name = "生产-应用-F"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.48.0/20"
availability_zone = "cn-beijing-f"
}
resource "alicloud_vswitch" "vsw_prod_application_g" {
name = "生产-应用-G"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.64.0/20"
availability_zone = "cn-beijing-g"
}
resource "alicloud_vswitch" "vsw_prod_application_h" {
name = "生产-应用-H"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.80.0/20"
availability_zone = "cn-beijing-h"
}
resource "alicloud_vswitch" "vsw_prod_database_f" {
name = "生产-数据库-F"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.96.0/20"
availability_zone = "cn-beijing-f"
}
resource "alicloud_vswitch" "vsw_prod_database_g" {
name = "生产-数据库-G"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.112.0/20"
availability_zone = "cn-beijing-g"
}
resource "alicloud_vswitch" "vsw_prod_database_h" {
name = "生产-数据库-H"
vpc_id = "${alicloud_vpc.prod_vpc.id}"
cidr_block = "10.20.128.0/20"
availability_zone = "cn-beijing-h"
}
resource "alicloud_nat_gateway" "prod_nat_gateway" {
vpc_id = "${alicloud_vpc.prod_vpc.id}"
specification = "Small"
name = "生产-NAT"
# bandwidth_packages = [
# {
# ip_count = 1
# bandwidth = 5
# # internet_charge_type = "PayByTraffic"
# }
# ]
depends_on = [
"alicloud_vswitch.vsw_prod_dmz_f",
"alicloud_vswitch.vsw_prod_dmz_g",
"alicloud_vswitch.vsw_prod_dmz_h",
"alicloud_vswitch.vsw_prod_application_f",
"alicloud_vswitch.vsw_prod_application_g",
"alicloud_vswitch.vsw_prod_application_h",
"alicloud_vswitch.vsw_prod_database_f",
"alicloud_vswitch.vsw_prod_database_g",
"alicloud_vswitch.vsw_prod_database_h",
]
}
resource "alicloud_hip" "prod_nat" {
bandwidth = 30
}
resource "alicloud_hip" "prod_host_gcal-tnkt" {
bandwidth =5
}
resource "alicloud_hip_association" "prod_nat" {
allocation_id = "${alicloud_hip.prod_nat.id}"
instance_id = "${alicloudHnat_gateway.prod_nat_gateway.id}"
}
resource "alicloud_hip_association" "prod_host_gcal-tnkt" {
allocation_id = "${alicloud_hip.prod_host_gcal-tnkt.id}"
instance_id = "${alicloudHinstance.gcal-tnkt.id}"
}
resource "alicloud_snat_hntry" "snat_prod_application_f" {
snat_table_id = "${alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_application_f.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_application_g" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_application_g.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_application_h" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_application_h.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_addressH"
resource "alicloud_snat_hntry" "snat_prod_database_f" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_database_f.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_database_g" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_database_g.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_database_h" {
snat_table_id = "H{alicloud_nat_gateway.prodnat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_database_h.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_dmz_f" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_dmz_f.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_dmz_g" {
snat_table_id = "H{alicloud_nat_gateway.prod_nat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_dmz_g.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"
resource "alicloud_snat_hntry" "snat_prod_dmz_h" {
snat_table_id = "H{alicloud_nat_gateway.prodnat_gateway.snat_table_ids}"
source_vswitch_id = "${alicloud_vswitch.vsw_prod_dmz_h.id}"
snat_ip = "${alicloud_hip.prod_nat.ip_address}"