引言:

上一篇提到双ISP使用双链路接入时,本地网关需要使用SLA、Track和Route-map等手段实现链路切换时NAT转换的切换。但有些时候,某些供应商只通过一条链路(如图中R1到SW4),提供接入到两个更高级运行商的服务(如电信、联通等)。这个时候,在R1只有一个逻辑出口的情况下(即不考虑trunk等多逻辑接口的方式)时,之前的route-map将无法以出接口作为NAT转换的判断条件。本文提供一种方法,虽然在执行效率、反应速度上没有之前双链路的方法高,但也不失为一种权衡之计。这里就要祭出Cisco的高级管理工具:EEM(嵌入式事件管理)
双ISP单链路接入NAT配置问题探讨_第1张图片
如图所示,只讨论R1的情况。R1作为本地网络12.0.0.0/24、21.0.0.0/24的网关,为连接远端R5上的网段5.0.0.0/24,向某ISP(SW4)申请了1条Internet线路。该ISP只是简单的桥接到两个上游ISP处(R3、R4)。R3、R4分别给R1一个独立的公网地址(R3分配R1:123.0.0.1;R4分配R1:124.0.0.1)。由于R1为Stub AS,故考虑使用浮动静态路由+负载均衡的方式对外访问。其中R1主路由下一跳指向R3;浮动备用路由下一跳指向R4。

方法:

双ISP单线接入时,网关所使用的nat内部全局地址应为所选线路对应的IP地址(或者该端口所对应的pool)。由于不同ISP均对应同一个出端口,而route-map的match条件没有支持track的返回结果,因此NAT无法通过route-map判断使用哪个地址池。那如何把track的结果和NAT联系起来呢?既然控制层无法满足本文的需求,那我们就提高一些,在管理层的角度考虑这个问题。这就需要用到直接操纵running-configuration的工具:EEM。通过EEM的event track,可以跟踪到任何track的state,并触发相应的action。而这些action,就是我们的nat转换命令。

配置文件

单线接入:
R1:
track 3 ip sla 3
track 4 ip sla 4
interface FastEthernet0/0
 ip address 124.0.0.1 255.255.255.0 secondary
 ip address 123.0.0.1 255.255.255.0
 ip nat outside
interface FastEthernet1/0
 ip address 12.0.0.1 255.255.255.0
 ip nat inside
interface FastEthernet1/1
 ip address 21.0.0.1 255.255.255.0
 ip nat inside
ip nat pool NAT_POOL_R3 123.0.0.101 123.0.0.200 prefix-length 24
ip nat pool NAT_POOL_R4 124.0.0.101 124.0.0.200 prefix-length 24
ip route 5.0.0.0 255.255.255.0 123.0.0.3 50 track 3
ip route 5.0.0.0 255.255.255.0 124.0.0.4 100 track 4
ip access-list standard VLAN_12
 permit 12.0.0.0 0.0.0.255
ip access-list standard VLAN_21
 permit 21.0.0.0 0.0.0.255
ip sla 3
 icmp-echo 123.0.0.3 source-ip 123.0.0.1
 frequency 30
ip sla schedule 3 life forever start-time now
ip sla 4
 icmp-echo 124.0.0.4 source-ip 124.0.0.1
 frequency 30
ip sla schedule 4 life forever start-time now
route-map NAT_SOURCE permit 10
 match ip address VLAN_12 VLAN_21
event manager applet SET_NAT_POOL 
  event track 3 state down
 action 1.0 cli command "enable"
 action 2.0 cli command "configure terminal"
 action 3.0 cli command "do clear ip nat translations *"
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 6.0 cli command "end"
event manager applet RESET_NAT_POOL 
  event track 3 state up
 action 1.0 cli command "enable"
 action 2.0 cli command "configure terminal"
 action 3.0 cli command "do clear ip nat translations *"
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
 action 6.0 cli command "end"
R2配置基本一样,R3、R4、R5请参考上篇。
上述配置中,EEM生成了两个应用,一个触发条件为track 3的状态为down,执行action即把running-config中的nat配置替换成使用R4地址池的NAT转换;同样,触发条件为track 3状态up的action为把running-config中的nat配置替换为使用R3地址池的NAT转换。注意,上述配置文件中,没有具体的ip nat inside source转换

实验结果

首先,启动R1时,可以看到EEM已经开始初始化NAT:
*Dec  6 00:58:04.079: %SYS-5-CONFIG_I: Configured from console by  on vty0 (EEM:RESET_NAT_POOL)
确认启动配置并无ip nat inside source语句:
*R1#show start | in ip nat inside source
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
运行配置已经由该语句,证明EEM运作正常:
R1#show run | in ip nat inside source
ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
由于NAT是正常的,因此内网工作站可正常访问外网
VPCS[1]> ping 5.0.0.1
5.0.0.1 icmp_seq=1 ttl=253 time=212.000 ms
5.0.0.1 icmp_seq=2 ttl=253 time=80.000 ms
5.0.0.1 icmp_seq=3 ttl=253 time=88.000 ms
5.0.0.1 icmp_seq=4 ttl=253 time=76.000 ms
5.0.0.1 icmp_seq=5 ttl=253 time=90.000 ms
检查R1的NAT配置,可以看到,R1使用R3所分配的地址池作NAT转换,同时路由表指向R3;
R1#
*Dec  6 01:03:44.807: NAT*: s=12.0.0.101->123.0.0.101, d=5.0.0.1 [32369]
*Dec  6 01:03:45.027: NAT*: s=5.0.0.1, d=123.0.0.101->12.0.0.101 [32369]
R1#
*Dec  6 01:03:46.055: NAT*: s=12.0.0.101->123.0.0.101, d=5.0.0.1 [32370]
*Dec  6 01:03:46.119: NAT*: s=5.0.0.1, d=123.0.0.101->12.0.0.101 [32370]
R1#
*Dec  6 01:03:47.135: NAT*: s=12.0.0.101->123.0.0.101, d=5.0.0.1 [32371]
*Dec  6 01:03:47.195: NAT*: s=5.0.0.1, d=123.0.0.101->12.0.0.101 [32371]
R1#
*Dec  6 01:03:48.227: NAT*: s=12.0.0.101->123.0.0.101, d=5.0.0.1 [32372]
*Dec  6 01:03:48.287: NAT*: s=5.0.0.1, d=123.0.0.101->12.0.0.101 [32372]
R1#
*Dec  6 01:03:49.291: NAT*: s=12.0.0.101->123.0.0.101, d=5.0.0.1 [32373]
*Dec  6 01:03:49.371: NAT*: s=5.0.0.1, d=123.0.0.101->12.0.0.101 [32373]
这时,验证自动切换的功能是否正常。关闭R3相应端口,使R1到R3连接实效:
R3(config)#in f0/0
R3(config-if)#shut
可以看到,R1的EEM已经检测到event track的情况发生改变,并触发新的NAT语句:
*Dec  6 01:05:39.083: ipnat_add_dynamic_cfg_common: id 2, flag 5, range 1
*Dec  6 01:05:39.083: id 2, flags 0, domain 0, lookup 0, aclnum 0, aclname , mapname NAT_SOURCE idb 0x0
*Dec  6 01:05:39.087: poolstart 124.0.0.101   poolend 124.0.0.200
R1#
*Dec  6 01:05:39.199: %SYS-5-CONFIG_I: Configured from console by  on vty0 (EEM:SET_NAT_POOL)
这时运行配置中关于NAT POOL的使用已改为R4所分配的地址池了。
R1#show run | sec ip nat inside source
ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 4.0 cli command "no ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R4"
 action 5.0 cli command "ip nat inside source route-map NAT_SOURCE pool NAT_POOL_R3"
连通性测试,毫无压力:
VPCS[1]> ping 5.0.0.1
5.0.0.1 icmp_seq=1 ttl=253 time=212.000 ms
5.0.0.1 icmp_seq=2 ttl=253 time=80.000 ms
5.0.0.1 icmp_seq=3 ttl=253 time=92.000 ms
5.0.0.1 icmp_seq=4 ttl=253 time=86.000 ms
5.0.0.1 icmp_seq=5 ttl=253 time=80.000 ms
最后,检查NAT转换的结果:
R1#
*Dec  6 01:07:31.523: NAT*: s=12.0.0.101->124.0.0.101, d=5.0.0.1 [32596]
*Dec  6 01:07:31.739: NAT*: s=5.0.0.1, d=124.0.0.101->12.0.0.101 [32596]
R1#
*Dec  6 01:07:32.755: NAT*: s=12.0.0.101->124.0.0.101, d=5.0.0.1 [32597]
*Dec  6 01:07:32.803: NAT*: s=5.0.0.1, d=124.0.0.101->12.0.0.101 [32597]
R1#
*Dec  6 01:07:33.851: NAT*: s=12.0.0.101->124.0.0.101, d=5.0.0.1 [32598]
*Dec  6 01:07:33.919: NAT*: s=5.0.0.1, d=124.0.0.101->12.0.0.101 [32598]
R1#
*Dec  6 01:07:34.943: NAT*: s=12.0.0.101->124.0.0.101, d=5.0.0.1 [32599]
*Dec  6 01:07:35.019: NAT*: s=5.0.0.1, d=124.0.0.101->12.0.0.101 [32599]
R1#
*Dec  6 01:07:36.011: NAT*: s=12.0.0.101->124.0.0.101, d=5.0.0.1 [32600]
*Dec  6 01:07:36.107: NAT*: s=5.0.0.1, d=124.0.0.101->12.0.0.101 [32600]

讨论:

本方法使用Cisco路由器管理层的EEM软件进行配置文件的修改,进而使得NAT能够根据track的结果进行地址池切换,但效率偏低,一方面配置文件的修改需要一定的生效时间,且存在语句的翻译等问题;另一方面,track object有一定的时间延迟,无法做到电信级网络中断的要求。如果有更好的方式,欢迎指导。