Jul
15

Look at the following NAT scenario (thanks to Huan Pham on Groupstudy for the example). R2 is configured to translate R1 Loopback0 IP address to one of it’s own Loopback0 IP addresses:

R2:
ip nat inside source static 150.1.1.1 150.1.2.100
!
interface Serial 0/1
 ip nat inside
!
inerface FastEthernet 0/0
 ip nat outside

All hosts behind Ethernet segment can reach R1 using the IP address “150.1.2.100”. Now the question is to make a user logged in R2 to telnet to “150.1.2.100” and reach R1 Loopback0. Lets start straight with the final working configuration:

R2:
interface Loopback0
 ip nat outside
!
ip nat inside source static 150.1.1.1 150.1.2.100
ip nat outside source static 150.1.2.2 155.1.23.22

!
! Route returning packets from R1 over Loopback0
!
ip route 155.1.23.22 255.255.255.255 150.1.2.254

To verify it, enable the following debugging and telnet to 150.1.2.100 from R2:

Rack1R2#debug ip nat detailed
IP NAT detailed debugging is on

Rack1R2#telnet 150.1.2.100
Trying 150.1.2.100 ... Open

User Access Verification

Password: 

!
! NAT on the outside direction
!
NAT: o: tcp (150.1.2.2, 39064) -> (150.1.2.100, 23) [22225]
NAT: s=150.1.2.2->155.1.23.22, d=150.1.2.100 [22225]
NAT: s=155.1.23.22, d=150.1.2.100->150.1.1.1 [22225]

!
! NAT on the inside direction
!

NAT: i: tcp (150.1.1.1, 23) -> (155.1.23.22, 39064) [0]
NAT: s=150.1.1.1->150.1.2.100, d=155.1.23.22 [0]
NAT: s=150.1.2.100, d=155.1.23.22->150.1.2.2 [0]

As we can see from this output, the packet leaving Loopback0 is looped back and uses the both static NAT translation: first, to translate it’s source from “150.1.2.2” to “155.1.23.22” and the second to translate it’s destination from “150.1.2.100” to “150.1.1.1”. The resulting packet has src=”155.1.23.22” and dst=”150.1.1.1”.

Then a packet from R1 (src=”150.1.1.1”, dst=”155.1.23.22”) comes back. Since this packet enters NAT inside interface, a routing lookup is performed first, and the static route configured is used to route incoming packet to Loopback0 interface. Without the static route, R2 will attempt to route the packet either to itself (by default) or back to R3 (with no-alias keyword configured for NAT entry). So the static route saves the day, and packet source is translated using NAT inside rule (from “150.1.1.1” to “150.1.2.100”). After that, packet loops back to R2 and has it’s destination translated using NAT outside rule (from “155.1.23.22” to “150.1.2.2”). Looks fine.

Now what would happen if we remove the static route?

R2:
access-list 100 permit tcp any any eq telnet
access-list 100 permit tcp any eq telnet any

Rack1R2#debug ip packet detail 100
IP packet debugging is on (detailed) for access list 100
Rack1R2#debug ip nat detailed
IP NAT detailed debugging is on
Rack1R2#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Rack1R2(config)#no ip route 155.1.23.22 255.255.255.255 150.1.2.254
Rack1R2(config)#^Z

Rack1R2#telnet 150.1.2.100
Trying 150.1.2.100 ...
!
! TCP SYN packet leaves R2, destination/source translated
!
NAT: o: tcp (150.1.2.2, 45879) -> (150.1.2.100, 23) [14437]
NAT: s=150.1.2.2->155.1.23.22, d=150.1.2.100 [14437]
NAT: s=155.1.23.22, d=150.1.2.100->150.1.1.1 [14437]

IP: tableid=0, s=155.1.23.22 (local), d=150.1.1.1 (Serial0/1), routed via FIB
IP: s=155.1.23.22 (local), d=150.1.1.1 (Serial0/1), len 44, sending
    TCP src=45879, dst=23, seq=1022925953, ack=0, win=4128 SYN
IP: tableid=0, s=150.1.1.1 (Serial0/1), d=155.1.23.22 (Serial0/1), routed via RIB

!
! Reply packet comes back from R1, destined to 155.1.23.22. Since we don’t have
! a static route to send this packet for NAT translation, but we have a local alias
! the router accepts the packet. But the destination address if 155.1.23.22, while
! the TCP session was sourced from 150.1.2.2. Therefore, the router sends an RST.
!
IP: s=150.1.1.1 (Serial0/1), d=155.1.23.22 (Serial0/1), len 44, rcvd 3
    TCP src=23, dst=45879, seq=3088708722, ack=1022925954, win=4128 ACK SYN
IP: tableid=0, s=155.1.23.22 (local), d=150.1.1.1 (Serial0/1), routed via FIB

IP: s=155.1.23.22 (local), d=150.1.1.1 (Serial0/1), len 40, sending
    TCP src=45879, dst=23, seq=1022925954, ack=0, win=0 RST

% Connection timed out; remote host not responding

!
! ICMP pings still work! This is because router will accept reply to any of it’s IP addresses
!

Rack1R2#ping 150.1.2.100

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.2.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 64/85/173 ms

With the two translations but no static route, the “inside” translation never kicks in (no “NAT: i” message) since the packet is routed to router itself. This is the way inside NAT works, and this breaks TCP connections, but ICMP is still working.

Okay but maybe that special outside translation that changes the IP address of R2 from “150.1.2.2” to “155.1.23.22” is not needed at all? Let’s remove it too, leaving ourselves with just one translation, and test connectivity again:

Rack1R2(config)#no ip nat outside source static 150.1.2.2 155.1.23.22
Rack1R2(config)#^Z
Rack1R2#
NAT: deleting alias for 155.1.23.22
NAT: deleting alias from redundancy list for 155.1.23.22
ipnat_remove_static_cfg: id 35, flag A

Rack1R2#telnet 150.1.2.100
Trying 150.1.2.100 ...
!
! Packet is translated using outside direction.. TCP session to 150.1.2.100
! is redirected to 150.1.1.1
!
NAT: o: tcp (150.1.2.2, 42616) -> (150.1.2.100, 23) [62052]
NAT: s=150.1.2.2, d=150.1.2.100->150.1.1.1 [62052]

IP: tableid=0, s=150.1.2.2 (local), d=150.1.1.1 (Serial0/1), routed via FIB
IP: s=150.1.2.2 (local), d=150.1.1.1 (Serial0/1), len 44, sending
    TCP src=42616, dst=23, seq=874820746, ack=0, win=4128 SYN
IP: tableid=0, s=150.1.1.1 (Serial0/1), d=150.1.2.2 (Loopback0), routed via RIB

!
! A reply arrives.. but it’s sourced from 150.1.1.1 and destined to 150.1.2.2.
! What that means is that R2 attempts to accept packet to it’s own IP address,
! but since it never initiated a connection to 150.1.1.1 (only to 150.1.2.100)
! the response is dropped and RST is sent!
!
IP: s=150.1.1.1 (Serial0/1), d=150.1.2.2, len 44, rcvd 4
    TCP src=23, dst=42616, seq=2431427125, ack=874820747, win=4128 ACK SYN

IP: tableid=0, s=150.1.2.2 (local), d=150.1.1.1 (Serial0/1), routed via FIB
IP: s=150.1.2.2 (local), d=150.1.1.1 (Serial0/1), len 40, sending
    TCP src=42616, dst=23, seq=874820747, ack=0, win=0 RST

% Connection timed out; remote host not responding

!
! Pings still work, since router accepts responses from any IP
!
Rack1R2#ping 150.1.2.100

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.2.100, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 64/64/65 ms
Rack1R2#

Now you see, that in order to make router perform “loopback NAT” you need two NAT rules and a static route. All this is pretty explainable if you look at the way inside and outside NAT work. And if you want more NAT scenarios, watch out for our soon-to-be released “IP Services” section of IEWB-RS VOL1 v5 Beta.

About Petr Lapukhov, 4xCCIE/CCDE:

Petr Lapukhov's career in IT begain in 1988 with a focus on computer programming, and progressed into networking with his first exposure to Novell NetWare in 1991. Initially involved with Kazan State University's campus network support and UNIX system administration, he went through the path of becoming a networking consultant, taking part in many network deployment projects. Petr currently has over 12 years of experience working in the Cisco networking field, and is the only person in the world to have obtained four CCIEs in under two years, passing each on his first attempt. Petr is an exceptional case in that he has been working with all of the technologies covered in his four CCIE tracks (R&S, Security, SP, and Voice) on a daily basis for many years. When not actively teaching classes, developing self-paced products, studying for the CCDE Practical & the CCIE Storage Lab Exam, and completing his PhD in Applied Mathematics.

Find all posts by Petr Lapukhov, 4xCCIE/CCDE | Visit Website


You can leave a response, or trackback from your own site.

5 Responses to “A Curious NAT Scenario”

 
  1. Margo says:

    Keep a good work man!,

  2. uri says:

    Hi Petr!

    Thank you for this outstanding example — it makes many internal IOS mechanisms much easier to understand! Btw, here’s another (a bit more optimized) solution:

    !
    hostname R2
    !
    interface Serial0/1
    ip nat outside
    !
    ip route 150.1.2.100 255.255.255.255 155.1.23.3
    !
    ip nat outside source static 150.1.1.1 150.1.2.100
    !

    HTH!

  3. Mike says:

    It’s still a great example, thanks!
    BTW, I think Uri’s solution lacks “no-alias” thing in outside NAT rule, because without it packets seem never leave R2.

  4. Aaron says:

    Hi,

    I have been trying to set something like this up for ages.

    In my case clients inside have to resolve the IP address of the server using an exteranly DNS server. So will always recive a “public IP address”

    S I want to get the inside client talking to the “Inside Server” talking via the servers “outside IP address”

    Now not being a CCIE (not yet) or indeed anywhere near, from what I can tell I would is.

    One nat rule to send the outgoing packet to the out side ip address of the loopback interface

    And a second to translate the outside address of the server to the inside address.

    With a static route in there some where, to insure the packets get Nat’ed correctly.

    At least thats what I think is happening? I am just confused where the static route gets involved, on the outgoing or incomming packets.

    Also with the newer NVI on the more recent routers and the “nat enababled” configurations rather than “inside” and “outside”, is there any other way to do NAT loopback?

    Cheers

    Aaron

 

Leave a Reply

Categories

CCIE Bloggers