Saturday, September 18, 2010

Cisco IOS Destination-NAT

Throughout my career in networking, I’ve often implemented Source-NAT translation on Cisco routers (the practice of replacing the source IP address in packets) to either hide the private address or because the subnet overlapped with another location.  However, I’ve rarely implemented Destination-NAT (the practice of replacing the destination IP address in packets).  Destination-NAT, it turns out is not as self-explanatory as Source-NAT when it comes to CLI commands.  And, the materials I found on CCO and Google searches did not clearly explain how to do this simple task in Cisco IOS.  So, I think it warrants a quick article in case others need!

Why would you want to Destination-NAT?  It is needed when a service provider assigns private addressing (RFC 1918) to a service you need to target and you already have a route in your network for that subnet, which goes elsewhere.  Or, you need to direct certain lines of business (LOB) to use one circuit over another, to reach the same service.  In this case, you can have one LOB target the real IP to reach the service over a specific circuit, and another LOB would target the Destination-NAT IP.  This way, the two LOBs don’t have to share the circuit.

If you are translating one IP to one IP, there is no need for a pool, or an ACL, for either source OR destination-NAT.  You would use the “ip nat inside source static” or “ip nat outside source static”.  I’ll explain which one to use for which scenario.  I just depends of the direction the session is initiated.  I usually assign the interface for my network (the one closer to the network core) as the “inside” interface using the “ip nat inside”.  And the interface facing the other network as “outside” using the “ip nat outside” command.  This also happens to be the way zone based firewalls work, although NAT has nothing to do with security or firewalls, and you could very well do the opposite.

Before I give a Destination-NAT example, let’s do a Source-NAT because that’s more common.  Here is the topology:

Core network where sessions get initiated (10.1.1.0/24) –> NAT router –> Other network (172.16.1.0/24)

In this scenario, we hide the core network’s real host IP address (10.1.1.1) for that flow with the NAT range IP address of 192.168.1.1.  So, the “other network” sees our traffic coming from the NAT address.

The IOS CLI command to do this is:

ip nat inside source static 10.1.1.1 192.168.1.1

Of course, you have to ensure there is a route for the translated address in the routing tables along the path for any router to reach that destination. 

Now, let’s say we also need to use this NAT router to translate the destination of our packet.  In other words, there is a LOB who needs to reach 172.16.1.1 via a different path, or we simply cannot advertise 172.16.1.0/24 into our core, for various reasons.  We need the host on our core to be able to target 172.16.1.1 by using destination address 172.18.222.222.

At the NAT router, you can’t use “ip nat inside destination static” because there is no such command in IOS.  Instead, you would use the following:

ip nat outside source static 172.18.222.222 172.16.1.1 add-route

As you can see, we are dealing with the outside NAT interface, which means we NAT in the return direction, which is why we have to reverse the order of the translation and use “source” instead of “destination”!

The “add-route” keyword may be needed if there is no route (or a route with an incorrect next-hop) in the routing table for the old “not-translated” destination.

Again, you have to ensure the 172.18.222.222 route is advertised inside your core, so the hosts can reach it.

Note- not all applications are tolerant to NAT, so make sure you test!

13 comments:

  1. Thank you so much.. (Commented even before trying....) I have been looking for article like yours the whole day.

    Just as a question, wouldn't the "ip nat inside destination" do the same thing?

    I have been trying th=o get that one setup for a long time now..!

    ReplyDelete
    Replies
    1. @akshayd2006, you are welcome! I am glad this article helped. "ip nat inside destination list" (list is a required keyword) requires an address pool, which isn't what we want here.

      Delete
  2. Thanks for the article, helped me a lot to find the right syntax for destination nat.

    ReplyDelete
  3. Thanks so much. This helped me out. I couldn't find the correct solution anywhere else. This made my day!

    ReplyDelete
  4. Hi Thanks for the article. And I found that when I ping from inside to outside, I do not see in the debug that translation occurs. May it be true that translation only occurs when traffic from outside initiated?

    ReplyDelete
  5. Please help not sure doing it correctly, I could not get CLI 'ip nat outside source static 172.18.222.222 172.16.1.1 add-route' to work.

    (INT router 10.1.1.1/24) –> (10.1.1.254 NAT router 172.16.1.254) –> (172.16.1.1/24 EXT router)

    CLI added for 'ip nat inside source static 10.1.1.1 192.168.1.1'
    From Ext router when I ping 192.168.1.1 destination is translated to 10.1.1.1

    CLI added for 'ip nat outside source static 172.18.222.222 172.16.1.1 add-route'
    From Ext router I could not ping to NAT Router 172.16.1.254 and from NAT router I could not ping to Ext router 172.16.1.1.

    ReplyDelete
  6. CLI added for 'ip nat inside source static 10.1.1.1 192.168.1.1'
    From Ext router when I ping 192.168.1.1 destination is translated to 10.1.1.1 (Where I am accessing INT from EXT)

    I am confused is this source NAT? As based on the definition I found for Juniper SRX (see below) it seems to be Destination NAT.

    http://www.mustbegeek.com/configure-destination-nat-in-juniper-srx/

    Destination NAT is a type of NAT that is configured when you want to get access to your internal network from outside. This type of NAT is also called destination PAT because in this type of NAT, you simply translate different ports to reach various services with same IP address.

    ReplyDelete