阿里云上如何使用VPC
绝大多数个人用户使用的都是阿里云的公有云,它的诸多限制决定了它只能服务于个人用户而非企业用户,这主要是因为:
- 公有云ECS导致服务器直接暴露在公网,而通常企业拥有很多内部服务,它们希望隐藏起来。
阿里云VPC(virtual private cloud)可以实现网络隔离,为企业创建一个私有的内部网络,就像家庭局域网一样,因此企业在私有网络内可以更加灵活的规划服务,而不必担心外网可以侵入进来。
VPC内的ECS默认无法访问外网也无法被外网访问,通过为ECS挂载公网IP并配置为SNAT,则其他ECS就可以借助它访问公网,另外也可以为该ECS配置DNAT从而允许外部访问VPC内部的服务。
以上功能足以满足绝大多数中小型企业的部署需求,下面我将花费几块钱人民币的代价,实际搭建一个这样的企业网络环境,希望对大家有帮助。
创建VPC
隔离一个私有网络出来,选择一个地址区间最大的A类网段10.0.0.0/8:
整个私有网络会提供1个路由器,用于管理多个网段。
划分网段,创建1个交换机
10.0.0.0/8这个IP池太大,最好能隔离成几个网段,用于未来不同目的的规划,做好2层(链路)隔离。
创建一个交换机,划出一个网段:前8位是私有网共享的前缀,9-22用于划分网段,每个网段内用23-32位划分主机。
当前这个交换机的网段是10.0.0.0/22,接下来几个交换机可以分别配置10.0.4.0/22、10.0.8.0/22、10.0.12.0/22….
创建完成:
查看路由器
因为我们配置了交换机的网段,因此它自动在路由器上加了1个路由项,将目标IP属于10.0.0.0/22的包发到与交换机相连的网口上。
查看当前网络拓扑
路由器下划分了1个网段,接了对应的交换机,现在交换机上还没有连接ECS(虚拟机)实例。
创建ECS实例
现在给这个交换机下面创建1个ECS:
让这个ECS接到上一个交换机上:
新的网络拓扑
现在交换机下有ECS了,但是ECS在VPC私有网内,无法访问公网。
申请弹性IP
为了让这个ECS可以访问公网,以及可以被公网访问,我申请一个弹性IP:
按流量计费,因为测试完就删了,包月就亏了:
绑定弹性IP到ECS
为了ECS上网,需要让阿里云将弹性IP关联到ECS:
阿里云是通过公网网关NAT(SNAT+DNAT)实现ECS上网的,因此在ECS上看不到什么公网网卡,只有内网网卡(连在交换机上的那块):
这个10.0.3.44是路由器DHCP分配下来的,属于10.0.0.0/22这个网段。
观察这台机器的路由表:
- 第一条:目标地址10.0.0.0/255.255.252.0(掩码22位),说明eth0连在10.0.0.0/22这个网段的交换机上,同网段的机器之间直接通过交换机通讯。
- 第二条:本地环回,没意义。
- 第三条:默认网关,也就是第一条没匹配的情况下将包发给路由器,这个10.0.3.253就是路由器与该网段交换机相连的那个网口的IP地址。
路由器的默认路由
- 路由器下的多个网段内的ECS互相通讯,都把路由器当作默认网关,因为路由器有所有网段的路由表,它知道如何交付数据包。
- 具有弹性IP的ECS,其包经过路由器时,会被阿里云的弹性IP NAT策略识别,从而经过阿里云的公网网关走到外网。
- 不具有弹性IP的ECS,其包经过路由器时,因为路由表没有相对应的路由项,因此无法路由到外网。
现在希望实现无弹性公网IP的ECS通过弹性IP的ECS访问外网的目标,可以这样实现:
- 在路由器上配置默认网关(也就是找不到路由项时)为具有弹性IP的那台ECS机器,因此发往外网的包将全部流量该ECS。
- 配置具有弹性IP的ECS,利用iptables增加一个SNAT规则,将包的源IP修改为本ECS的内网网卡IP,并重新发出。
- 经过修改的包,首先通过交换机到达路由器,因为源IP是弹性IP,因此被阿里云的弹性IP NAT策略识别,从而经过阿里云的公网网关走到外网。
- 当应答回到阿里云公网网关后,因为弹性IP NAT策略识别,最终将目标IP改为具有弹性IP的ECS的内网网卡IP,包经过路由器->交换机回到ECS。
- 弹性ECS收到包后,因为我们配置的iptables SNAT规则,会发现之前的映射会话,将包的目标IP改回到无弹性IP的ECS,再次交给交换机。
- 交换机将包直接转发给无弹性IP ECS,整个过程结束。
添加路由器的默认路由为弹性IP ECS:
为这个弹性IP ECS添加SNAT规则:
1 |
iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth0 -j MASQUERADE |
即所有来自私有网的来源IP,都改为本ECS的内网网卡IP。
创建内网ECS
再次创建一个ECS,只不过这次不再购买弹性IP给它,但是他依旧可以访问外网,因为我们在前面为路由器配置了默认路由指向到弹性IP ECS,而弹性IP ECS配置了SNAT。
新的拓扑中,交换机下有2个ECS,其中具有弹性IP的那个在通过路由器的时候由阿里云SNAT转出到公网,而不具有弹性IP的那个在通过路由器的时候由默认网关转发至弹性IP ECS,由弹性IP ECS的SNAT映射来源IP,最终再经过同样的阿里云SNAT转出到公网。
内网ECS访问外网
因为我们只配置了SNAT,因此内网ECS是无法被我们访问到的,它只能主动访问公网。但是,阿里云在页面上提供了一个控制台,因此我们可以连到该服务器上。
ping baidu.com成功,说明该ECS成功通过另外一台弹性IP ECS访问到外网:
为了确认一下,我在弹性IP ECS上执行如下命令抓访问80端的流量:
1 |
[root@iZbp11wvn1qznwpi9fxlsqZ ~]# tcpdump -i eth0 port 80 |
之后在内网ECS上访问百度:curl www.baidu.com,可以同时在弹性IP ECS上看到截获的流量,说明的确是这样工作的。
外网访问内网ECS
- 同样的道理,我们可以给弹性IP ECS配置一个DNAT规则,将公网到来的请求目标IP修改为内网ECS的IP,并经由交换机发给内网ECS处理。
- 当内网ECS回复应答的时候,按照默认网关发往路由器,路由器判定目标地址非私有网段后走它的默认网关发给了弹性IP ECS。
- 弹性IP ECS上的SNAT规则将识别会话,将应答的源IP改为弹性IP ECS的内网网卡IP,按照弹性IP ECS的默认网关将应答发给了路由器(经过交换机)。
- 路由器上的阿里云弹性IP SNAT规则会识别流量,将源IP改为公网IP发出到公网。
可见,实现外网访问内网ECS,需要SNAT+DNAT同时工作才行。
现在给弹性IP ECS添加DNAT规则,将发给它2222端口的TCP流量转发给内网ECS的22端口:
现在可以从任意公网连接弹性IP的2222端口,实际连接到的服务器是内网ECS的22端口:
上图中,我们通过弹性IP:2222端口到达弹性IP ECS,经它的DNAT转发到了内网ECS的22端口,通过ifconfig查看eth0的IP确认的确当前ssh连在了内网ECS上。
说在最后:自己搭建DNAT/SNAT只能单机,无法做到高可用,因为阿里云不给我们提供VIP。如果你考虑构建高可用的私有云,还是直接购买阿里云的负载均衡+NAT网关吧,它们分别对应DNAT和SNAT,但是可靠性更高。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~

我按照’路由器的默认路由’的部分坐下来, 第二个没有公网ip的ecs还是不能访问外网,
我的第一个ecs不是绑定的弹性ip, 而是在买的时候就绑定了公网ip, 这个有什么区别么?
另外我的vpc网段是192.168.0.0/16, 其中ecs使用的是192.168.1.0/24, 这样的话, 命令要怎么修改?
可以的话, 请说的详细些, 网络的相关知识我还在学习中, 非常感谢
我感觉可能是网段的问题,如果是不同网段应该加子路由才行。
你看我的例子,应该2个ECS都挂在一个路由器下面,属于同一个网段。
iptables -A FORWARD -d 172.16.1.0/24 -j ACCEPT
iptables -A FORWARD -s 172.16.1.0/24 -j ACCEPT
需要增加这两条之后网络才通了。
我的不需要呀,请问这两句是做什么的?
哪两句…
我是说这两句
iptables -A FORWARD -d 172.16.1.0/24 -j ACCEPT
iptables -A FORWARD -s 172.16.1.0/24 -j ACCEPT
好文,解决我的难题,谢谢!
客气了!
您好,学习了,想了解,有公网的主机发送数据包经过路由器,应该是直接进入公网网关没有经过自定义路由表中的下一跳(0.0.0.0->ecs实例)的吧(否则会出现路由环路)。
但是看了腾讯的路由表说明,比阿里云详细,就有点迷茫了,他提到。
“
路由规则优先级
当路由表中存在多条路由规则时,路由优先级由高至低分别为:
私有网络内流量:私有网络内流量最优先匹配。
最精确路由:非私有网络内流量根据最精确路由规则匹配。
公网IP:路由规则均匹配失效时,通过公网 IP 对 Internet 进行外访。
”。
那这样不久会经过自定义的路由,导致路由环路?
望指教。
网络领域我不太懂,建议找一位网络工程师咨询一下~
1