blog
    A Curious NAT Scenario
    15 July 08

    A Curious NAT Scenario

    Posted byPetr Lapukhov
    facebooktwitterlinkedin
    news-featured

    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.

    Hey! Don’t miss anything - subscribe to our newsletter!

    © 2022 INE. All Rights Reserved. All logos, trademarks and registered trademarks are the property of their respective owners.
    instagram Logofacebook Logotwitter Logolinkedin Logoyoutube Logo