High Availability NAT with HSRP

VN:F [1.9.6_1107]
Rating: 5.0/5 (2 votes cast)
By Jared Scrivener on April 27th, 2009

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 HSRP


interface 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 101

In 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.

Configuration Files

High Availability NAT with HSRP, 5.0 out of 5 based on 2 ratings
Share and Enjoy:
  • RSS
  • Twitter
  • Facebook
  • Google Bookmarks
  • Digg
  • Print
  • Technorati
  • Slashdot
  • LinkedIn
  • del.icio.us
  • Reddit
  • Sphinn
  • Mixx
  • Blogplay
  • Netvibes
  • NewsVine
  • Live
  • Ping.fm
  • MySpace
  • Yahoo! Bookmarks
  • Yahoo! Buzz

Tags: , ,

9 Responses to “High Availability NAT with HSRP”

  1. shivlu jain says:

    nice explanation.

    regards
    shivlu jain

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  2. shivlu jain says:

    nice explanation.

    regards
    shivlu jain

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  3. Darby Weaver says:

    Nice one Jared!

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  4. Darby Weaver says:

    Nice one Jared!

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  5. Wil Bowes says:

    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

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  6. Wil Bowes says:

    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

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  7. Juan says:

    Great post Jared. It worked in my lab perfect!! Thanks!

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  8. Tyrone says:

    Thanks, this worked well with our current router setup. Much appreciated…

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)
  9. Rolando says:

    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….

    VA:F [1.9.6_1107]
    Rating: 0.0/5 (0 votes cast)

Leave a Reply