NAT 101

1. Inside, Outside, Local, Global

When defining NAT it is important to understand what Inside/Outside and Local/Global mean. When we use NAT, our router will be at the border between the Inside and the Outside zones. Hosts on the Inside are configured with addresses from the LOCAL Address Space and hosts on the Outside are configured with addresses from the GLOBAL Address Space. The router is the only device that is directly connected to both the Inside and the Outside.

  • Hosts
    • Inside – hosts on the Inside
    • Outside – hosts on the Outside
  • Addresses
    • Local – addresses used on the Inside (usually private addresses)
    • Global – addresses used on the Outside (usually public addresses)

2.1 Choose the sides: Inside and Outside

The basic idea with NAT is to change the Layer 3 address (either source or destination) of a packet. (You can change also the Layer 4 information, but this will come up later).

In most common scenarios you have 2 sides, called Inside and Outside and you will have to chose were your interfaces belong to.

R(config)# interface INSIDE-INTERFACE
R(config-if)# ip nat inside
R(config)# interface OUTSIDE-INTERFACE
R(config-if)# ip nat outside

Usually, you will have at least one interface on each side, but actually, this is not necessary. It all comes down to how the interface that is receiving the packet is configured for NAT:
When packets arrive on an Inside interface they are first routed (based on destination IP address), and then translation occurs for either the source or the destination address. When packets arrive on the Outside interface, they are first translated (either the source or the destination address) and then they are routed based on the destination address (which may have just been translated).

2. NAT Inside Source

When translating the Inside Source, we tell the router to translate the Source address of the packets that arrive on the Inside. So we first need to define an inside interface:

R(config)# interface INSIDE-INTERFACE
R(config-if)# ip nat inside

When the packet arrives, the router will first route it (based on the destination – OUTSIDE_GLOBAL) and then it will translate the source IP. An entry is created into the NAT Translation table that maps the INSIDE_LOCAL address to an INSIDE_GLOBAL address.
When the Outside Host replies, it sends return packets to the INSIDE_GLOBAL destination address. If you want to get this traffic to the Inside Host, you have to make sure you receive it on an Outside interface

R(config)# interface OUTSIDE-INTERFACE
R(config-if)# ip nat outside

When the outside interface receives a packet, it will first translate it (based on the same entry into the NAT Translation table) and then it will route it (based on the new destination – INSIDE_LOCAL)

NAT inside source

There are different options when implementing inside source NAT:

2.1 Host Static NAT

Used to map one INSIDE_LOCAL address to one INSIDE_GLOBAL address:

R(config)# ip nat inside source static INSIDE_LOCAL INSIDE_GLOBAL

This command maps the INSIDE_LOCAL address to the INSIDE_GLOBAL address when performing source inside NAT. All IP packets sourced by the INSIDE_LOCAL address get their source translated to the INSIDE_GLOBAL, and all IP packets destined to the INSIDE_GLOBAL address get their destination translated to INSIDE_LOCAL.
You can’t map the same INSIDE_GLOBAL address to multiple INSIDE_LOCAL addresses, or the other way around. Since this is a 1-to-1 mapping that is always present in the NAT table, connection can be initiated by any side (Inside and Outside).

2.2 Port Static NAT

This configuration is similar with the one before, except that instead of translating all IP traffic, only traffic for 1 UDP or TCP port is translated. This allows the router to use the same INSIDE_GLOBAL address for multiple INSIDE_LOCAL addresses, as long as they use different GLOBAL_PORTs

R(config)# ip nat inside source static {tcp|udp} INSIDE_LOCAL LOCAL_PORT INSIDE_GLOBAL GLOBAL_PORT

2.3 Network Static NAT

Usually used when dealing with overlapping networks, this command allows translating the INSIDE_LOCAL network to an INSIDE_GLOBAL network. However, both networks have to have the same NETMASK.

R(config)# ip nat inside source static network INSIDE_LOCAL_NETWORK INSIDE_GLOBAL_NETWORK [/PREFIXLEN|NETMASK]

2.4 Dynamic NAT

A dynamic map is used to enable translation for multiple hosts on the inside, and uses a many-to-many mapping, where multiple INSIDE_LOCAL addresses are mapped to multiple INSIDE_GLOBAL addresses.

For this, we must first define a pool of addresses to use as INSIDE_GLOBAL and an ACL for the INSIDE_LOCAL addresses:

R(config)# ip nat pool INSIDE_GLOBAL_POOL START-IP END-IP {netmask NETMASK|prefix-length LEN}
R(config)# access-list INSIDE_LOCAL_ACL permit INSIDE_LOCAL_ADDR [WILDCARD]
! It also works with an extended ACL

Then, enable Dynamic NAT with:

R(config)# ip nat inside source list INSIDE_LOCAL_ACL pool INSIDE_GLOBAL_POOL

Dynamic translations generate entries in the NAT table only when traffic comes on the Inside interface and is routed to the Outside Interface. This is when the router takes one address from the INSIDE_GLOBAL_POOL and maps it to the INSIDE_LOCAL address that sourced the traffic. Traffic on the reverse path is dropped if there is no translation generated by traffic on the inside. If the translation times out, the INSIDE_GLOBAL address is returned to the pool. But with enough active translations you can empty the INSIDE_GLOBAL_POOL, and conversations from new hosts on the INSIDE will not be allowed.

2.5 Dynamic NAT with overload – PAT

When using Dynamic NAT without overload you could only have a small number of translations limited by the size of the INSIDE_GLOBAL_POOL. If the pool was empty, conversations from new hosts on the INSIDE were not allowed. With overloading, the source port is dynamically translated into a unique global port, so the router differentiate between inside hosts and uses fewer (even one) INSIDE_GLOBAL addresses for many hosts on the inside.
For this, we must again define a pool of addresses to use as INSIDE_GLOBAL and an ACL for the INSIDE_LOCAL addresses:

R(config)# ip nat pool INSIDE_GLOBAL_POOL INSIDE_GLOBAL_START INSIDE_GLOBAL_END {netmask NETMASK|prefix-lenght LEN}
R(config)# access-list INSIDE_LOCAL_ACL permit INSIDE_LOCAL_ADDR [WILDCARD]
! It also works with an extended ACL

Then, enable NAT with overloading:

R(config)# ip nat inside source list INSIDE_LOCAL_ACL pool INSIDE_GLOBAL_POOL overload

3. NAT Outside Source

This type of NAT is used when you want the Outside Hosts to appear as Local Hosts. However, there are some more problems to take care of.

NAT outside source

With Outside Source NAT, when a packet sourced by OUTSIDE_GLOBAL and destined to an INSIDE_LOCAL address arrives on the Outside interface, it is first translated and then routed. This means that first we translate the source address (OUTSIDE_GLOBAL to OUSIDE_LOCAL) and then we should route based on the destination IP. The destination is the INSIDE_LOCAL address so traffic should arrive to the Inside Host. However, return traffic will be packets sourced by the INSIDE_LOCAL address and destined to the OUTSIDE_LOCAL address. This is where things get tricky, because the destination is from the Local Address Space and we should send the packet back on the Inside interface. And this is exactly what happens unless we define a static route that forces the router to forward the packet on the Outside interface. You can see this by looking at the command debug ip nat and you will see that the traffic is returned to the incoming interface. One way to resolve this is by adding a more specific static route that points to the actual destination.
Another way is to perform another Static NAT Translation for the return traffic. You will need a translation that takes the destination address
You can make the router add the static route by itself if you use the add-route keyword but personally I have seen it fail, so a better way to do it is by using static routes.
In some funky configuration you can even make another NAT Outside Source translation on the return path, which will result in have 2 outside interface defined and no inside interface.
Now, based on the requirements, you may have to use both inside source and outside source translation, for example when dealing with overlapping networks and you may even have to use more static routes.
As with inside NAT we have multiple ways of configuring the outside NAT

3.1 Host Static NAT

R(config)# ip nat outside source static OUTSIDE_GLOBAL OUTSIDE_LOCAL

3.2 Port Static NAT

R(config)# ip nat outside source static {tcp|udp} OUTSIDE_GLOBAL GLOBAL_PORT OUTSIDE_LOCAL LOCAL_PORT

3.3 Network Static NAT

R(config)# ip nat outside source static network OUTSIDE_GLOBAL_NETWORK OUTSIDE_LOCAL_NETWORK {/PREFIXLEN|NETMASK}

3.4 Dynamic NAT

R(config)# ip nat pool OUTSIDE_LOCAL_POOL START_IP END_IP {netmask NETMASK | prefix-length LEN}

[/cisco]

R(config)# ip nat outside source list OUTSIDE_GLOBAL_ACL pool OUTSIDE_LOCAL_POOL 

4. Inside Destination Address Translation – NAT for Server Load Balancing

Use it to redirect traffic for a SERVER-IP to a pool of real servers behind NAT. The process is somewhat similar to the Inside Source Address Translation, only this time traffic from Outside generates entries in the NAT table so the perspective changes:
First define a pool that contains the INSIDE_LOCAL servers, and an ACL that matches the OUTSIDE_GLOBAL addresses of the server:

R(config)#ip nat pool REAL_SERVER_POOL START_IP END_IP {netmask NETMASK | prefix-length LEN} type rotary
R(config)# ip access-list GLOBAL_SERVER_ACL GLOBAL_ADDR [WILDCARD]

Then, enable the translation with:

R(config)# ip nat inside destination list GLOBAL_SERVER_ACL pool REAL_SERVER_POOL

The router will choose a new address from the REAL_SERVER_POOL, whenever a new Outside Host tries to access an IP from the GLOBAL_SERVER_ACL

Leave a Reply

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