一、设计目标
设计一个双出口网络,使用BGP做到最优化路由选择,并且当某一个出口故障时,设备能自动将流量切换到剩下的那个出口;内网同样实现线路冗余和设备冗余;实现网关冗余。
二、设计拓扑
三、设计说明
根据前面的设计目标,我给出了如上图所示的拓扑方案。这个方案更多的只是我对已学过知识的梳理,并未在实际工作中应用过。就实际情况而言,它可能更多的也只适用于理论分析。
在这个方案中,我假设了有两个ISP提供商ISP1和ISP2,使用设备R5模拟ISP1,使用设备R6模拟ISP2。R5和R6建立EBGP邻接关系来模拟Internet网络环境(实际的Internet就是不同的BGP AS连接在一起的)。
除了R5和R6外的其它所有设备都属于企业内网的设备。
R3和R4为放置于出口线路中的防火墙,在本案例中,它们只用于提供NAT功能。在本案例中,我使用了172.16.6.0/24和172.16.7.0/24作为NAT地址池,而并没有使用公网地址段来作为NAT地址池,这里请不要觉得奇怪。我这里只是一个理论上的案例而已,使用公网或私网地址段都是一样的。好吧,其实是我懒得改了。
R1和R2为网络核心层设备,它们也运行BGP协议,分别与R5和R6建立EBGP邻接关系。R1和R2之间则为IBGP邻接关系。R1和R2分别接收来自R5和R6的Internet路由,然后R1和R2再彼此之间交互接收的路由,以实现最优路由选择。同时,R1和R2也会分别向R5和R6通告它们各自所在线路的NAT地址池。
R7和R8为网络汇聚层设备。R1和R2的所有物理接口,R7和R8的上行接口位于OSPFAREA 0中。R7和R8的下行接口位于OSPF AREA 1中。
设备IOU1为接入层设备。在我这个案例中,我只使用了一台接入层交换机,如果还有其它的接入层交换机,也可如图所示,将它们分别与R7和R8相连,再划入到不同的OSPFAREA中。在R7和R8的下行接口上,我使用了VRRP,以实现网关的冗余。
这个案例中,各设备接口的IP地址分配方面,对于横向的链路,左边的接口使用xxx.xxx.xxx.1,右边的接口则使用xxx.xxx.xxx.2;对于纵向的链路,上边的接口使用xxx.xxx.xxx.1,下边的接口则使用xxx.xxx.xxx.2。如R5和R6之间的链路,R5一端的接口使用的IP地址为172.16.3.1,R6一端的接口则使用IP地址172.16.3.2,其它链路以此类推。
四、设备配置
1. 配置R5和R6,以使用它们来模拟Internet和ISP的网络。
//给R5配置BGP,使其使用环回口与R6建立EBGP邻接关系。
R5(config)#routerbgp 64513
R5(config-router)#neighbor172.16.2.1 remote-as 64514
R5(config-router)#neighbor172.16.2.1 update-source loopback0
R5(config-router)#neighbor172.16.2.1 ebgp-multihop 2
R5(config)#iproute 172.16.2.1 255.255.255.255 172.16.3.2
//使用静态路由将地址池172.16.6.0/24分配给企业网络。R5广播其环回口地址172.16.1.1/32,以使其在模拟的Internet网络中可被访问。
R5(config)#iproute 172.16.6.0 255.255.255.0 172.16.4.2
R5(config)#routerbgp 64513
R5(config-router)#address-familyipv4
R5(config-router-af)#network172.16.1.1 mask 255.255.255.255
//给R6配置BGP,使其使用环回口与R5建立EBGP邻接关系。
R6(config)#routerbgp 64514
R6(config-router)#neighbor172.16.1.1 remote-as 64513
R6(config-router)#neighbor172.16.1.1 update-source loopback0
R6(config-router)#neighbor172.16.1.1 ebgp-multihop 2
R6(config)#iproute 172.16.1.1 255.255.255.255 172.16.3.1
//使用静态路由将地址池172.16.7.0/24分配给企业网络。R6广播其环回口地址172.16.2.1/32,以使其在模拟的Internet网络中可被访问。
R6(config)#iproute 172.16.7.0 255.255.255.0 172.16.5.2
R6(config)#routerbgp 64514
R6(config-router)#address-familyipv4
R6(config-router-af)#network172.16.2.1 mask 255.255.255.255
2. 配置R5、R3和R1,使R5和R1的环回口之间可以建立EBGP邻接关系。
//配置R5,使其使用环回口与R1建立EBGP邻接关系。同时,R5向R1下发默认路由。
R5(config)#routerbgp 64513
R5(config-router)#neighbor192.168.1.1 remote-as 64512
R5(config-router)#neighbor192.168.1.1 update-source loopback0
R5(config-router)#neighbor192.168.1.1 ebgp-multihop 3
R5(config-router)#address-familyipv4
R5(config-router-af)#neighbor192.168.1.1 default-originate
R5(config)#iproute 192.168.1.1 255.255.255.255 172.16.4.2
//配置R3,使其有去往R1环回口192.168.1.1的路由。R3使用默认路由出网。将地址池172.16.6.0/24指向null0接口以防止路由环路。
R3(config)#iproute 192.168.1.1 255.255.255.255 192.168.2.2
R3(config)#iproute 0.0.0.0 0.0.0.0 172.16.4.1
R3(config)#iproute 172.16.6.0 255.255.255.0 null0
//配置R1,使其使用环回口与R5建立EBGP邻接关系,同时广播地址池172.16.6.0/24。
R1(config)#routerbgp 64512
R1(config-router)#neighbor172.16.1.1 remote-as 64513
R1(config-router)#neighbor172.16.1.1 update-source loopback0
R1(config-router)#neighbor172.16.1.1 ebgp-multihop 3
R1(config-router)#address-familyipv4
R1(config-router-af)#network172.16.6.0 mask 255.255.255.0
R1(config)#iproute 172.16.1.1 255.255.255.255 192.168.2.1
R1(config)#iproute 172.16.6.0 255.255.255.0 null0
//对R1去往R5的路由更新进行过滤,以只允许广播地址池172.16.6.0/24。
R1(config)#ipprefix-list prefixlist1 permit 172.16.6.0/24
R1(config)#routerbgp 64512
R1(config-router)#address-familyipv4
R1(config-router-af)#neighbor172.16.1.1 prefix-list prefixlist1 out
3. 配置R6、R4和R2,使R6和R2的环回口之间可以建立EBGP邻接关系。
//配置R6,使其使用环回口与R2建立EBGP邻接关系。同时,R6向R2下发默认路由。
R6(config)#routerbgp 64514
R6(config-router)#neighbor192.168.1.2 remote-as 64512
R6(config-router)#neighbor192.168.1.2 update-source loopback0
R6(config-router)#neighbor192.168.1.2 ebgp-multihop 3
R6(config-router)#address-familyipv4
R6(config-router-af)#neighbor192.168.1.2 default-originate
R6(config)#iproute 192.168.1.2 255.255.255.255 172.16.5.2
//配置R4,使其有去往R2环回口192.168.1.2的路由。R4使用默认路由出网。将地址池172.16.7.0/24指向null0接口以防止路由环路。
R4(config)#iproute 192.168.1.2 255.255.255.255 192.168.3.2
R4(config)#iproute 0.0.0.0 0.0.0.0 172.16.5.1
R4(config)#iproute 172.16.7.0 255.255.255.0 null0
//配置R2,使其使用环回口与R6建立EBGP邻接关系,同时广播地址池172.16.7.0/24。
R2(config)#routerbgp 64512
R2(config-router)#neighbor172.16.2.1 remote-as 64514
R2(config-router)#neighbor172.16.2.1 update-source loopback0
R2(config-router)#neighbor172.16.2.1 ebgp-multihop 3
R2(config-router)#address-familyipv4
R2(config-router-af)#network172.16.7.0 mask 255.255.255.0
R2(config)#iproute 172.16.2.1 255.255.255.255 192.168.3.1
R2(config)#iproute 172.16.7.0 255.255.255.0 null0
//对R2去往R6的路由更新进行过滤,以只允许广播地址池172.16.7.0/24。
R2(config)#ipprefix-list prefixlist1 permit 172.16.7.0/24
R2(config)#routerbgp 64512
R2(config-router)#address-familyipv4
R2(config-router-af)#neighbor172.16.2.1 prefix-list prefixlist1 out
4. 配置R1和R2以建立IBGP邻接关系。
R1和R2使用环回口建立IBGP邻接关系。R1和R2去往彼此环回口的路由采用静态路由,而不使用OSPF,并且,还需要指定下一跳为自身(next-hop-self)。
R1(config)#routerbgp 64512
R1(config-router)#neighbor192.168.1.2 remote-as 64512
R1(config-router)#neighbor192.168.1.2 update-source loopback0
R1(config-router)#address-familyipv4
R1(config-router-af)#neighbor192.168.1.2 next-hop-self
R1(config)#iproute 192.168.1.2 255.255.255.255 192.168.4.2
!
R2(config)#routerbgp 64512
R2(config-router)#neighbor192.168.1.1 remote-as 64512
R2(config-router)#neighbor192.168.1.1 update-source loopback0
R2(config-router)#address-familyipv4
R2(config-router-af)#neighbor192.168.1.1 next-hop-self
R2(config)#iproute 192.168.1.1 255.255.255.255 192.168.4.1
5. 配置R3和R4防火墙。
在实际生产网络中,防火墙应该是担当NAT和防攻击的功能的。但在我这个案例中,我是用路由器来模拟防火墙的(虽然图标也是防火墙的)。所以下面的NAT配置还是按照在路由器上配置NAT的步骤来的。只是说,在实际生产网络中,一般是使用真正的防火墙来进行NAT转换和防攻击,而不是使用路由器来进行NAT(具体原因应该跟设备性能参数有关,我也不是很确定~_~)。
另外,ISP分配过来的地址池应该是公网IP地址池,而不是应该图中所示的172.16.6.0/24或172.16.7.0/24这两个私网IP地址段,只不过我这里用了私网地址段来作为地址池,大家知道就好。
还应该注意的是,在下面配置设备时,我并没有使用整个C类的地址段(如172.16.6.0/24),而是去掉了该地址段前面的两个地址和后面的两个地址,这是因为在实际网络中,使用这些地址(如172.16.6.254)作为源地址去访问某些服务器可能会有问题,所以最好把它们去掉。
//需要注意,因为R1要与R5建立EBGP,所以不能对源192.168.1.1进行NAT转换
R3(config)#ipaccess-list extended acl1
R3(config-ext-nacl)#denyip host 192.168.1.1 any
R3(config-ext-nacl)#permitip 192.168.0.0 0.0.255.255 any
R3(config)#ipnat pool natpool1 172.16.6.2 172.16.6.253 netmask 255.255.255.0
R3(config)#interfaceg2/0
R3(config-if)#ipnat inside
R3(config)#interfaceg1/0
R3(config-if)#ipnat outside
R3(config)#ipnat inside source list acl1 pool natpool1 overload
//需要注意,因为R2要与R6建立EBGP,所以不能对源192.168.1.2进行NAT转换
R4(config)#ipaccess-list extended acl1
R4(config-ext-nacl)#denyip host 192.168.1.2 any
R4(config-ext-nacl)#permitip 192.168.0.0 0.0.255.255 any
R4(config)#ipnat pool natpool1 172.16.7.2 172.16.7.253 netmask 255.255.255.0
R4(config)#interfaceg1/0
R4(config-if)#ipnat inside
R4(config)#interfaceg2/0
R4(config-if)#ipnat outside
R4(config)#ipnat inside source list acl1 pool natpool1 overload
6. 查验路由表
上面配置完后,就可以看到R1和R2通过BGP获取到了正确的路由,并且根据BGP选路原则,它们的所选择的路径也是正确的。
到这里,出口的路由就基本做好了。接下来,要解决内网路由问题。
7. 设置R3和R4上的回程路由
要给R3和R4添加指向内网的路由(假设内网使用的地址范围为192.168.0.0/16)。
R3(config)#iproute 192.168.0.0 255.255.0.0 192.168.2.2
!
R4(config)#iproute 192.168.0.0 255.255.0.0 192.168.3.2
8. 给R1、R2、R7和R8配置OSPF
//将R1的所有接口都加入到OSPF AREA 0中,但不包括环回口
R1(config)#routerospf 1
R1(config-router)#network192.168.2.2 0.0.0.0 area 0
R1(config-router)#network192.168.4.1 0.0.0.0 area 0
R1(config-router)#network192.168.5.1 0.0.0.0 area 0
R1(config-router)#network192.168.7.1 0.0.0.0 area 0
//将R2的所有接口都加入到OSPF AREA 0中,但不包括环回口
R2(config)#routerospf 2
R2(config-router)#network192.168.3.2 0.0.0.0 area 0
R2(config-router)#network192.168.4.2 0.0.0.0 area 0
R2(config-router)#network192.168.6.1 0.0.0.0 area 0
R2(config-router)#network192.168.8.1 0.0.0.0 area 0
//将R7与核心层交换机相连的接口都加入到OSPF AREA 0中,与接入层交换机相连的接口则加入到OSPF AREA 1中
R7(config)#routerospf 7
R7(config-router)#network192.168.5.2 0.0.0.0 area 0
R7(config-router)#network192.168.8.2 0.0.0.0 area 0
R7(config-router)#network192.168.9.252 0.0.0.0 area 1
R7(config-router)#passive-interfaceg3/0 //本案例中,该接口与接入层交换机相连
//将R8与核心层交换机相连的接口都加入到OSPF AREA 0中,与接入层交换机相连的接口则加入到OSPF AREA 1中
R8(config)#routerospf 8
R8(config-router)#network192.168.6.2 0.0.0.0 area 0
R8(config-router)#network192.168.7.2 0.0.0.0 area 0
R8(config-router)#network192.168.9.253 0.0.0.0 area 1
R8(config-router)#passive-interfaceg3/0 //本案例中,该接口与接入层交换机相连
9. 设置R1和R2下发OSPF默认路由
对于R1和R2,都需要设置为下发OSPF默认路由。至于这两条默认路由的初始度量值,个人觉得可以不进行修改,让它们保持一样。如果为了排错时能更加简便,也可以将它们的初始度量值修改为不一样,同时设置metric-type为2,这样流量路径就会保持一致,而不会在上行路径间负载均衡。
R1(config)#routerospf 1
R1(config-router)#default-informationoriginate metric-type 1
!
R2(config)#routerospf 2
R2(config-router)#default-informationoriginate metric-type 1
10. 配置网关冗余协议VRRP
我将网关设置在汇聚层交换机上,并使用公有网关冗余协议VRRP。就实际配置情况来说,我将R7和R8的g3/0口都加入到VRRP Group 1,并修改R7和R8的g3/0接口的VRRP优先级,使R7成为Master,R8为Backup。
//配置R7的g3/0接口
R7(config)#interfaceg3/0
R7(config-if)#noshutdown
R7(config-if)#ipaddress 192.168.9.252 255.255.255.0
R7(config-if)#vrrp1 ip 192.168.9.254
R7(config-if)#vrrp1 priority 102
//配置R8的g3/0接口
R8(config)#interfaceg3/0
R8(config-if)#noshutdown
R8(config-if)#ipaddress 192.168.9.253 255.255.255.0
R8(config-if)#vrrp1 ip 192.168.9.254
R8(config-if)#vrrp1 priority 101
五、补充说明
配置完上面的一堆后,这个网络基本就实现了故障冗余自动切换的功能了。但实际使用时,还需要进一步深化配置,因为可能会存在因路由协议收敛导致的切换不及时的问题。比如,正常情况下,R8去往172.16.2.1是通过R2那个出口出去,假设此时R2出故障挂掉了,那么R8会把所有流量都发往R1,然而由于R1此时还没有意识到R2挂了,只有等R1和R2之间的BGP会话超时后,R1才会意识到R2挂了。在这之前,R1还是会把R8发过来的流量都转发给R2,但由于R2出故障了,因此这些流量就无法顺利地被转发到172.16.2.1。也就是说,在这段时间内,是会有丢包的。只有当BGP重新收敛后,数据包的转发才能恢复正常。也有一些技术可以加快BGP的收敛速度,不过我没研究过,所以暂时就这样了。
接入层交换机部分,没有什么必须要进行的配置。接入层交换机可以使用傻瓜交换机,也可以是可网管交换机。最好是可网管交换机,就可以部署各种接入控制特性,这样就可以少去很多麻烦。当然,接入层交换机这里其实还是存在单点失效的问题,可能使用具有冗余引擎和冗余电源的设备可以稍微缓解这个问题,但实际上应该没有企业这么有钱吧,也没有这么做的必要吧。
关于DNS的设置问题。在我这个设计方案中未涉及到DNS的问题,但实际网络中,DNS的设置会影响到网络出口的选择,不同出口上流量的多少,及网络的体验问题。一般来说,ISP1会给你两个DNS地址,ISP2也会给你两个DNS地址。我个人是认为,要么主用ISP1提供的线路,要么主用ISP2提供的线路。也就是说,要么只使用ISP1提供的DNS地址,要么只使用ISP2提供的DNS地址。如果要让两条出口线路上的流量更加均衡一点,可能可以在一部分区域中使用ISP1提供的DNS地址,在另一部分区域中使用ISP2提供的DNS地址,不过因为没有实际这样做过,所以也不确定是否的确可行。