One of the functions in IOS 12.4T is support for high availability NAT, to enable a pair of HSRP routers both running NAT to maintain state information and share it about both static and dynamic NAT translations. This means that should the active HSRP router fail, the standby router can continue to allow existing NAT sessions to succeed by already having the translation information passed to it by the active HSRP router.
What I’m going to show below is a simple setup for this scenario. Full configuration for each router (and the Catalyst switch) is available for download at the end of the post (so you can test it yourself).
I’m going to use four routers: R6, R7, R8 and R9. R7 and R8 are configured as an HSRP pair with sub-interfaces in VLAN 6 (inside) and VLAN 9 (outside). R6 is a member of VLAN 6 and R9 is a member of VLAN 9. R7 and R8 will be configured with HSRP on the inside interfaces. VLAN 6 uses the 10.0.0.0/24 network and VLAN 9 uses the 9.0.0.0/24 network.
In this example I’m configuring HSRP with R7 as the active router, by using a higher priority on R7 than R8. Additionally, I define the standby group name “HSRP” so that it can be referenced by the stateful NAT process in the “redundancy” command.
What I want to achieve is for all telnet traffic from the inside to the outside network to be matched against ACL 101 (referenced in route-map “SNAT”) and translated to an address in the NAT pool “SNATp”.
On R7, we configure HSRP and SNAT as follows:
interface FastEthernet0/1.6 encapsulation dot1Q 6 ip address 10.0.0.7 255.255.255.0 ip nat inside standby 1 ip 10.0.0.254 standby 1 priority 110 standby 1 preempt standby 1 name HSRP interface FastEthernet0/1.9 encapsulation dot1Q 9 ip address 9.0.0.7 255.255.255.0 ip nat outside ip nat Stateful id 1 redundancy HSRP mapping-id 10 protocol udp ip nat pool SNATp 9.0.0.20 9.0.0.29 prefix-length 24 ip nat inside source route-map SNAT pool SNATp mapping-id 10 access-list 101 permit tcp any any eq telnet route-map SNAT permit 10 match ip address 101
On R8, we configure HSRP and SNAT as follows:
interface FastEthernet0/1.6 encapsulation dot1Q 6 ip address 10.0.0.8 255.255.255.0 ip nat inside ip virtual-reassembly standby 1 ip 10.0.0.254 standby 1 preempt standby 1 name HSRPinterface FastEthernet0/1.9 encapsulation dot1Q 9 ip address 9.0.0.8 255.255.255.0 ip nat outside ip nat Stateful id 2 redundancy HSRP mapping-id 10 protocol udp ip nat pool SNATp 9.0.0.20 9.0.0.29 prefix-length 24 ip nat inside source route-map SNAT pool SNATp mapping-id 10 access-list 101 permit tcp any any eq telnet route-map SNAT permit 10 match ip address 101In the configuration, you’ll notice that each router is configured with a Stateful NAT ID: these values have to be unique to each router. In the configuration, the stateful NAT process is associated with a HSRP redundancy group and given a mapping ID. Linking to a redundancy group enables the stateful NAT process on each router to leverage HSRP to identify its stateful NAT peer address for the exchange of SNAT messages. The mapping ID is used to reference which NAT entries on the router need to have their state exchanged between the SNAT peers by the SNAT process.
You’ll notice that the inside policy-based NAT that I’ve configured references the mapping-id at the end of the command. Additionally, each router needs to have the same route-map, pool and access-list so that they can both provide the same services to clients.
To test my configuration, I’ll establish a telnet session from R6 to R9.
R6#telnet 9.0.0.9 Trying 9.0.0.9 ... Open User Access Verification Password: R9>en Password: R9#
Whilst that telnet session is open, we’ll look at the NAT translations and the SNAT information on R7 and R8. We see that R7 is showing as ACTIVE and that both routers have identical information showing in their NAT translations table.
R7#sh ip nat translations Pro Inside global Inside local Outside local Outside global tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23 R7#sh ip snat distributed ver Stateful NAT Connected Peers SNAT: Mode IP-REDUNDANCY :: ACTIVE : State READY : Local Address 10.0.0.7 : Local NAT id 1 : Peer Address 10.0.0.8 : Peer NAT id 2 : Mapping List 10 : InMsgs 400, OutMsgs 0, tcb 0xB8898888, listener 0x0 R8#sh ip nat tra Pro Inside global Inside local Outside local Outside global tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23
R8#sh ip snat distributed verbose Stateful NAT Connected Peers SNAT: Mode IP-REDUNDANCY :: STANDBY : State READY : Local Address 10.0.0.8 : Local NAT id 2 : Peer Address 10.0.0.7 : Peer NAT id 1 : Mapping List 10 : InMsgs 398, OutMsgs 0, tcb 0xB8898888, listener 0x0
When I shut down the F0/1.6 subinterface on R7, let’s look at the information shown on R8.
*Mar 11 17:17:18.767: %HSRP-5-STATECHANGE: FastEthernet0/1.6 Grp 1 state Standby -> Active R8#sh ip snat distributed verbose Stateful NAT Connected Peers R8#sh ip nat translations Pro Inside global Inside local Outside local Outside global tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23
On R8, we lose information about our connected SNAT peer (namely because the peer is dead) and we also see R8 become the active HSRP router. The telnet session from R6 to R9 is still available and working, too.
I’ll bring the R7 F0/1.6 link back up now, and we’ll look at R8 again:
*Mar 11 17:21:24.599: %HSRP-5-STATECHANGE: FastEthernet0/1.6 Grp 1 state Active -> Speak *Mar 11 17:21:35.447: %HSRP-5-STATECHANGE: FastEthernet0/1.6 Grp 1 state Speak -> Standby R8#sh ip snat distributed verbose Stateful NAT Connected Peers SNAT: Mode IP-REDUNDANCY :: STANDBY : State READY : Local Address 10.0.0.8 : Local NAT id 2 : Peer Address 10.0.0.7 : Peer NAT id 1 : Mapping List 10 : InMsgs 2, OutMsgs 0, tcb 0xB8898888, listener 0x0
We see that the SNAT relationship came back up. The telnet session from R6 to R9 is still up, too.
So now we’ve seen how to use HSRP to provide Stateful NAT services for dynamic entries. Before I finish, there’s one more function worth looking at: namely Stateful NAT for static entries. The process is slightly different as you’ll see.
What I’m going to create is a static entry translating R6 from its IP of 10.0.0.6 to 9.0.0.6 as it passes via either R7 or R8 (whichever is the active HSRP router). I’m going to leave the previous configuration on R7 and R8 (as the policy-based entry will retain precedence over the static entry).
R7(config)#ip nat inside source static 10.0.0.6 9.0.0.6 redundancy HSRP mapping-id 10 %NAT: System busy. Try later
Great – my command is correct, but the router errors. This, unfortunately, is normal when configuring SNAT – the solution is to either reboot the router or to shutdown the HSRP interface, configure the command, and bring the interface back up (which works sometimes but not always).
R7(config)#int f0/1.6 R7(config-subif)#sh SNAT: interface FastEthernet0/1.6 with address 10.0.0.7 is down R7(config-subif)#exi R7(config)# *Mar 11 17:39:48.475: %HSRP-5-STATECHANGE: FastEthernet0/1.6 Grp 1 state Active -> Init *Mar 11 17:39:48.479: %SNAT-5-PROCESS: Id 1, System fully converged R7(config)#ip nat inside source static 10.0.0.6 9.0.0.6 redundancy HSRP mapping-id 10 R7(config)#int f0/1.6 R7(config-subif)#no sh
Now to repeat this on R8. Note, I had to reload R8 as even shutting down the interfaces didn’t remove the NAT error, so I reloaded with the F0/1.6 subinterface on R8 shutdown so that the HSRP and SNAT process couldn’t start before I wanted it to.
R8(config)#ip nat inside source static 10.0.0.6 9.0.0.6 redundancy HSRP mapping-id 10 R8(config)#int f0/1.6 R8(config-subif)#no sh *Mar 11 17:39:22.967: %HSRP-5-STATECHANGE: FastEthernet0/1.6 Grp 1 state Speak -> Standby *Mar 11 17:39:29.007: %SNAT-5-PROCESS: Id 2, System starts converging *Mar 11 17:39:47.391: %SNAT-5-PROCESS: Id 2, System fully converged
Now I’ll start an SSH session from R6 to R9.
R6#ssh -l ipexpert 9.0.0.9 Password: R9>
Let’s look at the NAT entries on R7 and R8.
R7#clear ip nat translation * %NAT: System busy. Try later R7#sh ip nat translations Pro Inside global Inside local Outside local Outside global tcp 9.0.0.6:13931 10.0.0.6:13931 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23 tcp 9.0.0.6:44528 10.0.0.6:44528 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.6:46832 10.0.0.6:46832 9.0.0.9:22 9.0.0.9:22 --- 9.0.0.6 10.0.0.6 --- ---
You’ll notice the large number of entries on R7 and R8 – I setup the session a few times to test it and couldn’t clear the NAT table due to the error message (sure I could reload my router, but I think you’ll forgive the excess entries).
R7#sh ip snat distributed verbose Stateful NAT Connected Peers SNAT: Mode IP-REDUNDANCY :: ACTIVE : State READY : Local Address 10.0.0.7 : Local NAT id 1 : Peer Address 10.0.0.8 : Peer NAT id 2 : Mapping List 10 : InMsgs 59, OutMsgs 0, tcb 0xB8898888, listener 0x0
R8:
R8#sh ip nat translations Pro Inside global Inside local Outside local Outside global tcp 9.0.0.20:13842 10.0.0.6:13842 9.0.0.9:23 9.0.0.9:23 tcp 9.0.0.6:13931 10.0.0.6:13931 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23 tcp 9.0.0.6:44528 10.0.0.6:44528 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.6:46832 10.0.0.6:46832 9.0.0.9:22 9.0.0.9:22 --- 9.0.0.6 10.0.0.6 --- --- R8#sh ip snat distributed verbose Stateful NAT Connected Peers SNAT: Mode IP-REDUNDANCY :: STANDBY : State READY : Local Address 10.0.0.8 : Local NAT id 2 : Peer Address 10.0.0.7 : Peer NAT id 1 : Mapping List 10 : InMsgs 65, OutMsgs 0, tcb 0xB8898888, listener 0x0
Now to test by shutting down the F0/1.6 interface on R7. The SSH session is still up and on R8 we see the translations remain, but the SNAT peer entry is lost. To save space, I haven’t shown the failback (it does work), but I encourage you to lab this up and test it out.
R8#sh ip nat translations Pro Inside global Inside local Outside local Outside global tcp 9.0.0.20:13842 10.0.0.6:13842 9.0.0.9:23 9.0.0.9:23 tcp 9.0.0.6:13931 10.0.0.6:13931 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.20:24114 10.0.0.6:24114 9.0.0.9:23 9.0.0.9:23 tcp 9.0.0.6:44528 10.0.0.6:44528 9.0.0.9:22 9.0.0.9:22 tcp 9.0.0.6:46832 10.0.0.6:46832 9.0.0.9:22 9.0.0.9:22 --- 9.0.0.6 10.0.0.6 --- --- R8#sh ip snat distributed Stateful NAT Connected Peers R8#
So now we’ve seen how to implement both policy-based and static NAT leveraging HSRP for high availability. We’ve also seen the potential errors that may occur even when you do everything right (handy to know if they occur in the actual lab).
The configurations are available for you to test this out yourself. If you have any questions, post them in the comments or send me an email.
Tags: CCIE Security, HSRP, NAT








nice explanation.
regards
shivlu jain
nice explanation.
regards
shivlu jain
Nice one Jared!
Nice one Jared!
Great howto, works a treat! The %NAT: System busy. Try later message appears to be resolved using the following commands:
Router(config)#standby delay minimum 20 reload 20
Router(config)#standby 2 preempt delay minimum 20 reload 20 sync 10
Found on:
http://www.cisco.com/en/US/tech/tk648/tk361/technologies_tech_note09186a0080094c32.shtml#na
Great howto, works a treat! The %NAT: System busy. Try later message appears to be resolved using the following commands:
Router(config)#standby delay minimum 20 reload 20
Router(config)#standby 2 preempt delay minimum 20 reload 20 sync 10
Found on:
http://www.cisco.com/en/US/tech/tk648/tk361/technologies_tech_note09186a0080094c32.shtml#na
Great post Jared. It worked in my lab perfect!! Thanks!
Thanks, this worked well with our current router setup. Much appreciated…
Hi, is there any issue for SNAT with PAT? It work nice with a pool of IPs, but with one-IP pool and the overload statement it does not worked to me….