Exempting Static Translations in IOS NAT

Last week I wrote an article that defined the need for NAT exemption. This article used the example of a single device that terminated a VPN to a network that used the RFC1918 private address on the remote side. Additionally, the same device utilized NAT (Network Address Translation) to allow inside hosts to access the public Internet. We showed the issues that arise when traffic flowing back out to the remote VPN is translated. We also demonstrated the solution to this problem with both IOS and ASA devices. So what is left? As I eluded to, all is well unless an IOS device is used that utilizes static NAT Translations.

To demonstrate this, we will start out with a base configuration that is where we left off with the NAT Exemption article.

Inside Host Base Configuration

!
hostname InsideHost
!
interface FastEthernet0/0
 ip address 192.168.1.2 255.255.255.0
!
no ip routing
!
ip default-gateway 192.168.1.1
!
line vty 0 15
 privilege level 15
 password cisco

FW Configuration

hostname FW
!
crypto isakmp policy 10
 encr 3des
 authentication pre-share
crypto isakmp key cisco address 9.9.9.1
!
crypto ipsec transform-set MYSET esp-3des esp-sha-hmac
!
crypto map MYMAP 10 ipsec-isakmp
 set peer 9.9.9.1
 set transform-set MYSET
 match address 101
!
interface FastEthernet0/0
 ip address 192.168.1.1 255.255.255.0
 ip nat inside
!
interface Serial0/0
 ip address 9.9.9.2 255.255.255.0
 ip nat outside
 crypto map MYMAP
!
ip route 0.0.0.0 0.0.0.0 9.9.9.1
!
ip nat inside source list NAT interface Serial0/0 overload
!
ip access-list extended NAT
 deny   ip 192.168.1.0 0.0.0.255 192.168.100.0 0.0.0.255
 permit ip 192.168.1.0 0.0.0.255 any
!
access-list 101 permit ip 192.168.1.0 0.0.0.255 192.168.100.0 0.0.0.255
!

Outside Configuration

hostname Outside
!
crypto isakmp policy 10
 encr 3des
 authentication pre-share
crypto isakmp key cisco address 9.9.9.2
!
crypto ipsec transform-set MYSET esp-3des esp-sha-hmac
!
crypto map MYMAP 10 ipsec-isakmp
 set peer 9.9.9.2
 set transform-set MYSET
 match address 101
!
interface Loopback1
 ip address 192.168.100.1 255.255.255.0
!
interface Loopback2
 ip address 5.5.5.5 255.255.255.0
!
interface Serial0/0
 ip address 9.9.9.1 255.255.255.0
 crypto map MYMAP
!
ip route 192.168.1.0 255.255.255.0 9.9.9.2
!
access-list 101 permit ip 192.168.100.0 0.0.0.255 192.168.1.0 0.0.0.255

As an initial test, let’s make sure we can still reach 192.168.1.2 through the tunnel.

Outside#telnet 192.168.1.2 /source-interface loopback 1
Trying 192.168.1.2 ... Open

User Access Verification

Password:
InsideHost#

Well, that seems to work. Now let’s assume your boss decides that you are supposed to allow telnet access to inside host from public internet hosts. This access will not go through the VPN. While unencrypted telnet is a very bad idea, the concept would be the same for any other static PAT or static NAT configuration. In this example, we will do a static PAT configuration on FW and test it.

FW Configuration

FW(config)#
FW(config)#ip nat inside source static tcp 192.168.1.2 23 9.9.9.2 23
FW(config)#

Testing from Outside (source of 5.5.5.5)

Outside#telnet 9.9.9.2 /source-interface loopback 2
Trying 9.9.9.2 ... Open

User Access Verification

Password:
InsideHost#exit

[Connection to 9.9.9.2 closed by foreign host]
Outside#

Now let’s go back to our initial test, telnet through the VPN to InsideHost.

Outside#
Outside#telnet 192.168.1.2 /source-interface loopback 1
Trying 192.168.1.2 ...
% Connection timed out; remote host not responding

Outside#

Obviously that is no longer working, so we have introduced a problem into our configuration. Let’s look at the NAT table on FW.

FW#show ip nat translations
Pro Inside global      Inside local       Outside local      Outside global
tcp 9.9.9.2:23         192.168.1.2:23     192.168.100.1:47119 192.168.100.1:47119
tcp 9.9.9.2:23         192.168.1.2:23     ---                ---

Notice that there is no criteria that qualifies the translation in the second entry. Traffic sourced from 192.168.1.2:23 is translated to 9.9.9.2:23 unconditionally. Even if we had conditionally performed static NAT, there are not enough fields in the above output to see those restrictions. However, we can see the extended translation just above it. That is additional evidence that our traffic going to the remote VPN is being translated. But why?

If you recall, we only really exempted traffic that was dynamically translated. This was a carryover from our last article and listed in the base configuration above. Our new static translation is just that, static. So how can we fix this and make our InsideHost available to both public Internet hosts (as 9.9.9.2) and to VPN sources (as 192.168.1.2)? The answer is attaching a route-map to the static entry.

//delete the current static translation
FW(config)#no ip nat inside source static tcp 192.168.1.2 23 9.9.9.2 23

//create an acl that matches only traffic not destined to VPN Destinations
//we actually created this in the previous article and can reuse it
ip access-list extended NAT
 deny   ip 192.168.1.0 0.0.0.255 192.168.100.0 0.0.0.255
 permit ip 192.168.1.0 0.0.0.255 any

//create a route-map that permits only traffic that is not destined to the VPN
route-map NATMAP permit 10
 match ip address NAT

//recreate the static nat configuration
FW(config)#ip nat inside source static tcp 192.168.1.2 23 9.9.9.2 23 route-map NATMAP

Now Let’s attempt both tests again.

Test from a public address to 9.9.9.2

Outside#telnet 9.9.9.2 /source-interface loopback 2
Trying 9.9.9.2 ... Open

User Access Verification

Password:
InsideHost#exit

[Connection to 9.9.9.2 closed by foreign host]

Test through the VPN to 192.168.1.2

Outside#telnet 192.168.1.2 /source-interface loopback 1
Trying 192.168.1.2 ... Open

User Access Verification

Password:
InsideHost#exit

[Connection to 192.168.1.2 closed by foreign host]
Outside#

As you can see, NAT and VPN configurations can create some challenges. After configuring a few VPNs on IOS, most people remember the need to exempt NAT. However, static translations are added on an as needed basis. In many cases, the need to exempt the static translations is overlooked. By fully understanding and thinking through the packet flow, we can avoid unexpected outages and maintain a happy user base.

About Paul Stewart, CCIE 26009 (Security)

Paul is a Network and Security Engineer, Trainer and Blogger who enjoys understanding how things really work. With over 15 years of experience in the technology industry, Paul has helped many organizations build, maintain and secure their networks and systems.
This entry was posted in How-To. Bookmark the permalink.

3 Responses to Exempting Static Translations in IOS NAT

  1. Many thanks, I helped me uderstand why I have issues with RDP ( one way). as I did n’t created the nat exemption on router hence when I RDP behind the routers over IPsec tunnel, DRP was failing but RDP was working in other direction as I had NAT O for VPN traffic on ASA. thanks

    Salman

  2. jason in London says:

    Your NAT exemption with a translation route-map example has ended a quest I’ve

    ignored friends and family for days on. Thanks for taking the time to write up your

    experience. Iwant to post my Cisco 857 config somewhere now with nat inbound, outbound, and Cisco VPN Client setup.. Web server still accessible from outside, and locally to the adjacent floating VPN addresses.. to save others tearing their hair out..

  3. Ed Robbins says:

    I can’t thank you enough for this. Straight and to the point and it solved my problem.

Comments are closed.