This post will describe something interesting that happens to traceroute
when you are doing NAT. The inspiration for this post came from a
thread at IEOC started by Nick O’neill. He was doing ip nat outside translation but I
have found that the same behavior is true also for inside translations.

We will use this topology:

NAT_traceroute

R1 has a loopback 1.1.1.1/32 on the inside. On the outside this will be known as
100.100.100.100. You can see the networks connecting the routers are 12.12.12.0/24,
23.23.23.0/24 and 34.34.34.0/24. R3 will be the router doing NAT and this is the
configuration of it:

This is not a post describing the basics but make sure that you have routing setup.
I am using static routing here. When doing static NAT like this there is bidirectional
communication setup. Remember that when the outside to inside translation is done NAT
is performed before the routing lookup so we must have a route to 1.1.1.1 on R3.

The command above translates the inside local address to an inside global address.
R4 will traceroute to 100.100.100.100 and we will see what happens.

Interesting. Hops 2 and 3 are the same and they have the inside global address as source.
What happened here? The first hop is correct. The ICMP TTL exceeded should come back from
the outgoing interface used to reach 34.34.34.4 which was the source of the UDP traceroute
packet sent. Hop 2 should have been 23.23.23.2.

If we compare it to MPLS this almost looks like some core hiding feature as it does not
reveal the internal addressing of our network. If we look at debug on R3 we will see
what is happening.

We clearly see that the inside addresses are being translated to 100.100.100.100
even though there is no matching NAT statement. The number 33435 is the source
port number and 49164 is the destination port number.

This is the IOS version used for this lab:

Now if we try it on mainline IOS instead…

As you can see with the mainline IOS we can see the real addresses as they are not
being translated.

Knowing me you know that I like to dig deep to find out what is going on. I reached
out to a contact at Cisco to see if he could find any reference to what is happening
here. It turns out that this is related to bug CSCsu37097. Basically the customer
didn’t want the internal addressing revealed and so this was incorporated into IOS.
The symptom was described as: “Symptom:
Traceroute/ICMP unreachable doesn’t translate properly and can cause security problem.”

The following quote is also available from Cisco: “In Cisco IOS Release 15.1(3)T and
later releases, when you configure the traceroute command, NAT returns the same
inside global IP address for all inside local IP addresses.”
The source is this
document.

So basically this was implemented as a security feature for NAT. I hope you
learned something interesting.

NAT translation – What happened to my traceroute?
Tagged on:                         

5 thoughts on “NAT translation – What happened to my traceroute?

  • May 29, 2013 at 1:32 pm
    Permalink

    Very interesting Daniel, nice find!

    Reply
  • May 29, 2013 at 9:26 pm
    Permalink

    Great post! Hope you write some more articles about these kind of bugs/errors. 🙂 debug/facts about how stuff works is frikkin awesome. 🙂

    Reply
  • August 21, 2014 at 6:50 pm
    Permalink

    I surely learnt something interesting after reading this. Thanks! I was doing some troubleshooting on a lab using similar IOS version (C3725-ADVENTERPRISEK9-M), Version 12.4(15)T14) and ran into the same challenge with the translated addresses and ICMP replies. In my case there were no replies after the first hop. I ended using a different IOS and was able to see the translations and ICMP replies as expected… what a mind job!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: