假造专用云(Virtual Private Cloud ,VPC)在云盘算技术中扮演了重要角色。VPC能让两个云实例之间举行私有通讯,将网络流量与其他互联网用户隔离开,从而进步安全性。换句话说,作为一种假造网络环境,VPC能在公有云基础设施中创建一个隔离且私密的网络空间,为用户提供一个安全、灵活、可定制的网络环境,帮助他们构建和管理各种范例的应用和服务。
也就是说,就像是“套娃”一样,我们可以借助这种技术,在公共互联网的基础上构建一个规模更小,更私密的专用“Internet”来。想想是不是还挺激动?
请收下这份教程,祝你玩得愉快!
配景
下文我们将通过一个仪表板为例举行先容。为此我们将摆设两个应用程序,每个应用程序由一个应用服务器和一个数据库服务器组成(共四个服务器)。第一个应用程序和对应的数据库服务器接纳正常方式来摆设,第二组则设置为在VPC中运行。
每个应用的前端都使用Qwik构建,并使用Tailwind举行样式设计。服务器端由Qwik City(Qwik的官方元框架)提供支持,并在Node.js上运行,托管在共享的Linode VPS上。这些应用还使用PM2举行历程管理,并使用Caddy作为反向署理和SSL供应商。数据存储在PostgreSQL数据库中,该数据库也在共享的Linode VPS上运行。应用程序使用Drizzle与数据库举行交互,Drizzle是JavaScript的对象关系映射器(ORM)。
两个应用程序的整个基础架构都由Terraform管理,详细来说,使用了Terraform的Linode提供程序举行管理。初次接触Linode的童鞋对此大概感觉有些陌生,但只要学会了操纵方法,就能快速轻松地举行基础架构的设置和烧毁。
如果感爱好,大家也可以在这里找到下文涉及的所有代码:http://github.com/AustinGil/linode-vpc-demo
Demo
正如上文所述,本例将摆设两个雷同的应用程序。这方面并没有什么特别需要注意的,相应的内容如下图所示。
整个技术栈没有什么特别之处。之以是选择这些工具也没什么特别的原因,大家完全可以联合自己的需求和习惯选择自己觉得最恰当的工具。
真正有趣的部门在于基础架构。
首先看看一号应用程序,它基本上由两个托管在Akamai云中的服务器组成,一个用于应用程序,另一个用于数据库。当用户加载应用程序时,应用程序服务器将从数据库中提取数据,构建HTML,并将结果返回给用户。
这里的问题在于数据库连接的设置。某些情况下,我们大概会摆设一个数据库服务器,但并不能事先知道需要允许哪些IP所在的装备(如应用服务器)访问。此时很多人惯用的做法是简朴粗暴地直接允许具备正确根据的任何盘算机连接。但这会带来安全隐患,由于攻击者有大概借此连接到数据库并窃取敏感数据。
虽然攻击者仍然需要知道数据库主机、端口、用户名和密码才能获取访问权限,因此看起来这个隐患其实也并不是很大。毕竟刚才也说了,这种做法在业内其实很常见。但其实还有更好的做法!
如果已经知道每台需要访问的盘算机的IP所在,那么一种比较好的解决方案是设置防火墙或VLAN。但如果基础架构更加动态,服务器会频繁启动和关闭,IP所在列表的维护工作大概会显得非常麻烦。这就到了VPC的用武之地。我们可以将服务器设置到VPC中,并允只允许位于同一个VPC网络中的盘算机相互自由通讯。
这就是二号应用程序的设置方式。用户可以连接到应用服务器,该服务器位于VPC中,但允许处理来自公共互联网的流量。该应用服务器可以连接到数据库,数据库也位于同一个VPC中,而且只允许来自同一网络的访问。然后,应用服务器就可以照常从数据库获取数据,构建HTML,并将页面返回给用户。
对于平凡用户,两个应用的访问体验没有任何差异。浏览器可以很好地加载任何一个应用的界面。对平凡用户来说,VPC使用与否都不会对自己产生一丝一毫的影响。
然而对于攻击者来说,体验就截然差异了。即便攻击者想法获取了数据库访问根据,他们也无法连接,由于VPC的网络是被隔离的。此时,VPC充当了假造防火墙的角色,确保只有位于同一个网络中的装备才能访问数据库。(这个概念偶然也被称为“分割[segmentation]”)
Talk is cheap,show you the证据
通过参加emoji图标的示意图来展示技术概念,这固然是一种可爱的做法,但为了更有说服力,最好照旧能给出实证。因此我们将实验着使用数据库客户端DBeaver直接连接两个数据库,然后看看会发生什么。
对于一号数据库,我们设置了一个Postgres连接:使用从Akamai仪表板获取的主机IP所在以及在Terraform脚本中设置的端口、用户名和密码。发现连接可以按预期工作。
对于二号数据库,我们只需要更改IP所在,由于所有数据库设置都是由雷同Terraform脚本处理的,唯一的区别是:二号数据库服务器被放在与二号应用服务器雷同的VPC中,而且设置为只允许来自同一网络内的盘算机访问。
毫不意外,当我们实验连接时,尽管提供了所有正确信息,但依然收到了一个错误:
错误信息中完全没有提到任何关于VPC的内容。它只是说我们的IP所在不在设置文件的允许访问列表中。这是合理的。如果需要,我们可以明确地添加自己的IP所在并获得对数据库的访问权限,但这不是重点。
这里的重点是:我们并没有明确将任何IP所在添加到Postgres的允许列表中。然而应用服务器可以或许正常连接,但其他所有人都被VPC阻止了。
接下来,上代码
为了便于大家自行实验和练习,我们提供了摆设上述应用程序的Terraform代码。干系文件请访问:http://github.com/AustinGil/linode-vpc-demo/blob/main/terraform/terraform.tf
需要注意的是,我们已经尽最大努力让这个Terraform文件对其他人可重用。这需要更多的变量和基于tfvars文件的设置设置:http://github.com/AustinGil/linode-vpc-demo/blob/main/terraform/terraform.tfvars.example。
接下来一起看看其中的关键部门。
1.设置Terraform提供程序
首先,由于使用了Linode Terraform提供程序,因此有须要了解这是怎样设置的:
- terraform {
- required_providers {
- linode = {
- source = "linode/linode"
- version = "2.13.0"
- }
- }
- }
- variable "LINODE_TOKEN" {}
- provider "linode" {
- token = var.LINODE_TOKEN
- }
复制代码 这部门设置了提供程序以及Terraform要求我们提供的变量,大概大家也可以使用tfvars文件提供。
2.设置VPC和VPC子网
接下来需要设置实际的VPC资源以及子网资源。
- resource "linode_vpc" "vpc" {
- label = "${local.app_name}-vpc"
- region = var.REGION
- }
- resource "linode_vpc_subnet" "vpc_subnet" {
- vpc_id = linode_vpc.vpc.id
- label = "${local.app_name}-vpc-subnet"
- ipv4 = "${var.VPC_SUBNET_IP}"
- }
复制代码 服务器只能添加到同一地区的VPC中。在撰写本文时,Akamai云平台支持VPC的地区有13个。最新信息请参阅Akamai官网。
有三个IPv4所在范围是专门保留可用于私有网络(如VPC)的:
- 10.0.0.0 – 10.255.255.255
- 172.16.0.0 – 172.31.255.255
- 192.168.0.0 – 192.168.255.255
因此在设置子网时,我们必须从这三个选项中选择一个,而且必须使用CIDR格式来指定想使用的IP范围。这里我们使用了10.0.0.0/24。
私有网络中的每台服务器都将拥有该范围内的一个IPv4所在。
3. 设置应用服务器
为了让Terraform摆设我们的应用服务器,我们使用了linode_instance资源,此外还使用了stackscript资源来创建一个可重复使用的摆设脚本,用于安装和设置软件。这就像一个位于Akamai云仪表板中的Bash脚本,我们可以直接将其用于新的服务器。
干系代码就不放在这里了,但需要通过NVM安装Node.js 20,安装PM2,克隆项目代码库,运行应用,并设置Caddy。StackScript的内容请自行参阅源代码,下文想简朴说说Terraform的部门。
- resource "linode_instance" "application1" {
- depends_on = [
- linode_instance.database1
- ]
- image = "linode/ubuntu20.04"
- type = "g6-nanode-1"
- label = "${local.app_name}-application1"
- group = "${local.app_name}-group"
- region = var.REGION
- authorized_keys = [ linode_sshkey.ssh_key.ssh_key ]
- stackscript_id = linode_stackscript.configure_app_server.id
- stackscript_data = {
- "GIT_REPO" = var.GIT_REPO,
- "START_COMMAND" = var.START_COMMAND,
- "DOMAIN" = var.DOMAIN1,
- "NODE_PORT" = var.NODE_PORT,
- "DB_HOST" = linode_instance.database1.ip_address,
- "DB_PORT" = var.DB_PORT,
- "DB_NAME" = var.DB_NAME,
- "DB_USER" = var.DB_USER,
- "DB_PASS" = var.DB_PASS,
- }
- }
- resource "linode_instance" "application2" {
- depends_on = [
- linode_instance.database2
- ]
- image = "linode/ubuntu20.04"
- type = "g6-nanode-1"
- label = "${local.app_name}-application2"
- group = "${local.app_name}-group"
- region = var.REGION
- authorized_keys = [ linode_sshkey.ssh_key.ssh_key ]
- stackscript_id = linode_stackscript.configure_app_server.id
- stackscript_data = {
- "GIT_REPO" = var.GIT_REPO,
- "START_COMMAND" = var.START_COMMAND,
- "DOMAIN" = var.DOMAIN2,
- "NODE_PORT" = var.NODE_PORT,
- "DB_HOST" = var.DB_PRIVATE_IP,
- "DB_PORT" = var.DB_PORT,
- "DB_NAME" = var.DB_NAME,
- "DB_USER" = var.DB_USER,
- "DB_PASS" = var.DB_PASS,
- }
- interface {
- purpose = "public"
- }
- interface {
- purpose = "vpc"
- subnet_id = linode_vpc_subnet.vpc_subnet.id
- }
- }
复制代码 这两个资源的设置过程险些雷同,只有一些重要的事情需要注意:
- 二号应用程序包罗了将应用添加到VPC的干系设置。
- StackScript 需要数据库的IP所在。一号应用程序使用一号数据库的公共IP所在(linode_instance.database1.ip_address),二号应用程序则使用了一个变量(var.DB_PRIVATE_IP)。这个变量稍后会用到,它是分配给VPC中运行的二号数据库的私有IP所在。该所在也可以手动分配,以是我们将其设置为10.0.0.3。
另外还要注意,应用服务器要摆设到与VPC雷同的地区,原因如上文所述。
4. 设置数据库服务器
数据库也使用linode_instance和linode_stackscript资源举行设置。同样,StackScript的内容就直接略过了,感爱好的同学请直接参阅代码。接下来我们需要安装Postgres,设置数据库和根据,并提供一些设置选项。
- resource "linode_instance" "database1" {
- image = "linode/ubuntu20.04"
- type = "g6-nanode-1"
- label = "${local.app_name}-db1"
- group = "${local.app_name}-group"
- region = var.REGION
- authorized_keys = [ linode_sshkey.ssh_key.ssh_key ]
- stackscript_id = linode_stackscript.configure_db_server.id
- stackscript_data = {
- "DB_NAME" = var.DB_NAME,
- "DB_USER" = var.DB_USER,
- "DB_PASS" = var.DB_PASS,
- "PG_HBA_ENTRY" = "host all all all md5"
- }
- }
- resource "linode_instance" "database2" {
- image = "linode/ubuntu20.04"
- type = "g6-nanode-1"
- label = "${local.app_name}-db2"
- group = "${local.app_name}-group"
- region = var.REGION
- authorized_keys = [ linode_sshkey.ssh_key.ssh_key ]
- stackscript_id = linode_stackscript.configure_db_server.id
- stackscript_data = {
- "DB_NAME" = var.DB_NAME,
- "DB_USER" = var.DB_USER,
- "DB_PASS" = var.DB_PASS,
- "PG_HBA_ENTRY" = "host all all samenet md5"
- }
- interface {
- purpose = "public"
- }
- interface {
- purpose = "vpc"
- subnet_id = linode_vpc_subnet.vpc_subnet.id
- ipv4 {
- vpc = var.DB_PRIVATE_IP
- }
- }
- }
复制代码 与应用程序服务器一样,这两个数据库服务器大抵雷同,但有一些关键区别:
- 第二个数据库包罗将自己添加到VPC的设置。
- 客户端身份验证文件(pg_hba.conf)中会被写入差异的设置。一号数据库允许所有的互联网连接("host all all all md5"),而二号数据库只允许来自雷同网络的访问("host all all samenet md5")。
另外需要注意,在设置VPC设置时,我们明确分配了服务器的私有IP所在(var.DB_PRIVATE_IP)。这与应用程序服务器所获得的静态值雷同,因此可以从VPC内部连接到数据库。
总结
盼望本文能让大家了解到VPC是什么,有什么用,以及何时应该思量使用。这就像拥有了自己的小型私有互联网。严格意义上来说,VPC并不是为了替代VLAN或防火墙,但它是现有安全实践很好的增补。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |