Stateful NAT Failover
Problem
You want to use NAT in a high availability configuration, allowing a second router to take over NAT functionality if the first fails.
Solution
Stateful NAT allows you to combine NAT functionality with HSRP using two routers in a high availability configuration:
Router-A#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router-A(config)#access-list 11 permit any
Router-A(config)#ip nat pool NATPOOL 172.17.100.100 172.17.100.150 netmask 255.255.255.0
Router-A(config)#ip nat inside source list 11 pool NATPOOL mapping-id 1
Router-A(config)#interface FastEthernet0/0
Router-A(config-if)#ip address 192.168.1.3 255.255.255.0
Router-A(config-if)#ip nat inside
Router-A(config-if)#standby 1 ip 192.168.1.1
Router-A(config-if)#standby 1 preempt
Router-A(config-if)#standby 1 name SNATGROUP
Router-A(config-if)#exit
Router-A(config)#interface Serial0/0
Router-A(config-if)#ip address 172.17.55.2 255.255.255.252
Router-A(config-if)#ip nat outside
Router-A(config-if)#exit
Router-A(config)#ip nat Stateful id 1
Router-A(config-ipnat-snat)#redundancy SNATGROUP
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#exit
Router-A(config)#end
Router-A#
The second router's configuration is nearly identical:
Router-B#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router-B(config)#access-list 11 permit any
Router-B(config)#ip nat pool NATPOOL 172.17.100.100 172.17.100.150 netmask 255.255.255.0
Router-B(config)#ip nat inside source list 11 pool NATPOOL mapping-id 1
Router-B(config)#interface FastEthernet0/0
Router-B(config-if)#ip address 192.168.1.2 255.255.255.0
Router-B(config-if)#ip nat inside
Router-B(config-if)#standby 1 ip 192.168.1.1
Router-B(config-if)#standby 1 priority 90
Router-B(config-if)#standby 1 preempt
Router-B(config-if)#standby 1 name SNATGROUP
Router-B(config-if)#exit
Router-B(config)#interface Serial0/0
Router-B(config-if)#ip address 172.17.55.6 255.255.255.252
Router-B(config-if)#ip nat outside
Router-B(config-if)#exit
Router-B(config)#ip nat Stateful id 1
Router-B(config-ipnat-snat)#redundancy SNATGROUP
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#exit
Router-B(config)#end
Router-B#
Discussion
When you use NAT with a router failover protocol such as HSRP, the backup router must be able to take over NAT functionality as well as the IP address of the primary router. The problem is that this necessarily includes the entire dynamic NAT translation table. Simply running NAT and HSRP on a pair of routers is not sufficient because any existing NAT session information will be lost when the backup router takes over.
Stateful Network Address Translation (SNAT) solves this problem. The key command, which must be present on both routers is the ip nat Stateful command, which became available in IOS Version 12.2(13)T:
Router-A(config)#ip nat Stateful id 1
Router-A(config-ipnat-snat)#redundancy SNATGROUP
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#exit
There are a couple of things to notice here. First, the keyword Stateful will appear in your configuration capitalized like this. When you enter the command, it is case insensitive, however it can be slightly confusing because one usually expects IOS configuration keywords to be all lowercase. We often take advantage of this fact by deliberately capitalizing user-defined strings like SNATGROUP in this example, making the distinction from keywords obvious.
Entering the ip nat Stateful command puts you into a new configuration mode that allows you to associate a particular SNAT mapping ID with an HSRP group name. You can give the HSRP group a name with the standby name command as follows:
Router-A(config)#interface FastEthernet0/0
Router-A(config-if)#ip address 192.168.1.3 255.255.255.0
Router-A(config-if)#ip nat inside
Router-A(config-if)#standby 1 ip 192.168.1.1
Router-A(config-if)#standby 1 preempt
Router-A(config-if)#standby 1 name SNATGROUP
For more information on HSRP, please refer to Chapter 22.
In this example we have used a simple dynamic NAT configuration by using a pool called NATPOOL:
Router-A(config)#access-list 11 permit any
Router-A(config)#ip nat pool NATPOOL 172.17.100.100 172.17.100.150 netmask 255.255.255.0
Router-A(config)#ip nat inside source list 11 pool NATPOOL mapping-id 1
We could have just as easily used other NAT configuration methods such as static NAT, or PAT address overloading, as described elsewhere in this chapter.
With this configuration, one of the routers will take the virtual IP address, 192.168.1.1, acting as the default gateway for the interior network. The second router will operate in a passive backup mode, waiting to take over this virtual IP address in case the first router fails. The first router will maintain the NAT table for all connections. This means that you have to be very careful to ensure that inbound traffic uses the same path as outbound traffic, or the NAT table may not be able to rewrite the inside global IP address to the correct inside local address.
When the primary router fails, HSRP allows the backup router to transparently take over the virtual IP address. At the same time, SNAT ensures that the NAT translation table is also up to date, allowing the backup router to take over all NAT functions.
You can also use SNAT to create a dual redundancy active/active configuration in which both routers are passing HSRP and NAT traffic. We discuss the HSRP side of this technique in more detail in Chapter 22. The key is to create two HSRP groups, each representing a different virtual IP address. We then assign different priorities to each group so that during normal operation, the first router is active for the first virtual IP address and the second is active for the other address. However, in case of a failure of either router, the other one can take over functionality for both:
Router-A#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router-A(config)#interface FastEthernet0/0
Router-A(config-if)#ip address 192.168.1.3 255.255.255.0
Router-A(config-if)#ip nat inside
Router-A(config-if)#standby 1 ip 192.168.1.1
Router-A(config-if)#standby 1 preempt
Router-A(config-if)#standby 1 name SNAT1
Router-A(config-if)#standby 2 ip 192.168.1.2
Router-A(config-if)#standby 2 priority 90
Router-A(config-if)#standby 2 preempt
Router-A(config-if)#standby 2 name SNAT2
Router-A(config-if)#exit
Router-A(config)#interface Serial0/0
Router-A(config-if)#ip address 172.17.55.2 255.255.255.252
Router-A(config-if)#ip nat outside
Router-A(config-if)#exit
Router-A(config)#ip nat Stateful id 1
Router-A(config-ipnat-snat)#redundancy SNAT1
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#redundancy SNAT2
Router(config-ipnat-snat-red)#mapping-id 2
Router(config-ipnat-snat-red)#exit
Router-A(config)#access-list 11 permit any
Router-A(config)#access-list 12 permit any
Router-A(config)#ip nat pool NATPOOL1 172.17.100.100 172.17.100.150 netmask 255.255.255.0
Router-A(config)#ip nat inside source list 11 pool NATPOOL mapping-id 1
Router-A(config)#ip nat pool NATPOOL2 172.17.100.151 172.17.100.200 netmask 255.255.255.0
Router-A(config)#ip nat inside source list 12 pool NATPOOL mapping-id 2
Router-A(config)#end
Router-A#
And the second router's configuration is similar:
Router-B#configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
Router-B(config)#interface FastEthernet0/0
Router-B(config-if)#ip address 192.168.1.4 255.255.255.0
Router-B(config-if)#ip nat inside
Router-B(config-if)#standby 1 ip 192.168.1.1
Router-B(config-if)#standby 1 preempt
Router-B(config-if)#standby 1 name SNAT1
Router-B(config-if)#standby 1 priority 90
Router-B(config-if)#standby 2 ip 192.168.1.2
Router-B(config-if)#standby 2 preempt
Router-B(config-if)#standby 2 name SNAT2
Router-B(config-if)#exit
Router-B(config)#interface Serial0/0
Router-B(config-if)#ip address 172.17.55.6 255.255.255.252
Router-B(config-if)#ip nat outside
Router-B(config-if)#exit
Router-B(config)#ip nat Stateful id 1
Router-B(config-ipnat-snat)#redundancy SNAT1
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#redundancy SNAT2
Router(config-ipnat-snat-red)#mapping-id 1
Router(config-ipnat-snat-red)#exit
Router-B(config)#access-list 11 permit any
Router-B(config)#ip nat pool NATPOOL 172.17.100.100 172.17.100.150 netmask 255.255.255.0
Router-B(config)#ip nat inside source list 11 pool NATPOOL mapping-id 1
Router-B(config)#end
Router-B#
Here we have mapped both HSRP groups to the same NAT mapping-id on both routers. Now they can freely allocate addresses from the same pool, and update one another in case either fails. Note that HSRP is the only high-availability protocol that works with SNAT. Other protocols such as VRRP and GLBP are not currently supported.