Cisco ASA Firewall NAT Types and Examples
NAT which is referred as Network Address Translation is
used not only for solving the depletion of IPv4address space but also to
hide internal networks from outside world, hence further hardening the security
when used with a firewall. Moreover its the NAT feature which allows us to
use any address-space in our internal network complying with RFC 1918 of Private
Address Space and Filtering.
Real IP Address is the untranslated IP address of the host in an
internal network connected to Inside interface of firewall which is
called Real Interface in NAT terminology. Similarly Mapped IP
Address is the one to which real IP address is translated to and usually
the Mapped Interface is Outside interface of a firewall.
4 Types of NAT Cisco ASA Firewall Support
There are 4 types of NAT which Cisco ASA and PIX firewall
support. These are Dynamic NAT, Dynamic PAT, Static NAT and Identity
NAT.
Dynamic NAT
Simple Dynamic NAT Translation
Dynamic NAT Translation of Two Internal Networks
Dynamic NAT Translation Involving Three Interfaces
(Inside, DMZ, Outside)
Dynamic Port Address Translation (PAT)
PAT Using Outside Interface IP
Mapping Different Internal Subnets to Different PAT
Addresses
Combining Dynamic NAT with PAT Translation
Per-Session PAT vs Multi-Session PAT
Static NAT
Static NAT to 2xDifferent Servers in DMZ
Static NAT for whole Network Range
Static (PAT) Port Address Translation| Port Redirection
Identity NAT or NAT 0
Configuring Identity NAT
Configuring Identity NAT with Dynamic NAT Using
Twice NAT
Dynamic NAT
Dynamic NAT actually allows us to translate source IP
address (range or single IP) of an inside interface (higher security interface)
to a range or single IP of an outside interface (less secure interface)
in outbound direction only. Prior to Cisco ASA version 8.3,
dynamic NAT was carried out using nat and global commands
but in version 8.3 and higher (including 9.x), Cisco completely revamped NAT
implementation using network object.
Prior to Cisco ASA Version 8.3:
Prior to version 8.3, nat command is used to
mention the real IP address subnet and global command is used to
specify the mapped IP address subnet. Remember that the nat_id in
below commands i-e nat and global should be same because it
binds the internal_network_IP_subnet to external_network_IP_subnet
ciscoasa(config)#nat (real_interface_name) nat_id int_network_IP_subnet
ciscoasa(config)#global (mapped_interface_name) nat_id ext_IP_1-ext_IP_2 netmask net_mask
Important Note: The IP range ext_IP_1-ext_IP_2 in
above command should exclude the P2P IP of outside interface when configuring
dynamic NAT. Moreover you can select all together new IP pool you have bought
for NATing instead of using IP pool from which P2P IP of outside interfaces are
given.
Cisco ASA Version 8.3 & Above:
In Cisco ASA 8.3 and above, nat-control, static and global commands
are not supported. Either Static NAT/PAT, Dynamic NAT/PAT, Identity NAT in
Cisco ASA, in version 8.3 to 9.x, following are the two ways we can implement
NAT:
Auto NAT or Network Object NAT
Manual NAT or Twice NAT -> Discussed in the
end
Policy NAT can only be implemented using Manual NAT however.
So first what is Network Object? It simply defines a single host or group of
host which can either be Real IP address/subnet or Mapped IP address/subnet. We
create two separate network objects for defining real and mapped IP subnets
respectively. However, nat statement is only included in network
object containing real IP subnet and in this nat statement, you
define inside and outside interfaces along with keyword dynamic (incase
of dynamic NAT) and then mapped IP subnet or mapped network object.
ciscoasa(config)#object network object_name
ciscoasa(config-network-object)#{host IP_Add | subnet IP_Add
Net_Mask | range IP_Add_1-IP_Add_2}
Incase network object is for defining real IP
address/subnet, it must have a nat statement which is as follows
ciscoasa(config-network-object)#nat (inside_if,
outside_if) dynamic {mapped_IP | mapped_net_object}
Here the inside_if and outside_if can be any,any as
well.
Example-1: Consider inside (nameif inside)
interface has an IP address of 192.168.1.1/24 and outside interface (nameif outside)
has 10.1.1.2/24, the dynamic nat which will be done in ASA running version
prior to 8.3 will be as follows:
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
Outside → Security-level (0) → Subnet: 10.1.1.0/24 with
if-IP: 10.1.1.2 → nameif outside
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3-10.1.1.50 netmask 255.255.255.0
I assume 10.1.1.2 is given on outside interface and 10.1.1.1
is given on remote end.
In version 8.3 to 9.x
ciscoasa(config)#object network mapped_obj
ciscoasa(config-network-object)#range 10.1.1.3
10.1.1.50
ciscoasa(config)#object network real_obj
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic mapped_obj
What if all real IP address overcome all the mapped IP
addresses? Means real IP address space is more than mapped IP addresses. In
that case, we can add mapped interface name exactly after mapped_obj name
in above command using the interface keyword.
ciscoasa(config)#nat (inside,outside) dynamic mapped_obj interface outside
Example-2: What if our internal network has two real IP
subnets (192.168.1.0/24 and 192.168.2.0/24) which needs to be translated to
mapped IP addresses but with different ranges i-e Range-1: 10.1.1.2-10.1.1.50
and Range-2: 10.1.1.51-10.1.1.100?
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
Inside → Security-level (100) → Subnet: 192.168.2.0/24 with
if-IP: 192.168.2.1 → nameif inside
Outside → Security-level (0) → Subnet: 10.1.1.0/24 with
if-IP: 10.1.1.2 → nameif outside
Prior to Version 8.3 or below:
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#nat (inside) 2 192.168.2.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3-10.1.1.50 netmask 255.255.255.0
ciscoasa(config)#global (outside) 2 10.1.1.51-10.1.1.100 netmask 255.255.255.0
In version 8.3 to 9.x
ciscoasa(config)#object network mapped_obj_1
ciscoasa(config-network-object)#range 10.1.1.3
10.1.1.50
ciscoasa(config)#object network mapped_obj_2
ciscoasa(config-network-object)#range 10.1.1.51
10.1.1.100
ciscoasa(config)#object network real_obj_1
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic mapped_obj_1
ciscoasa(config)#object network real_obj_2
ciscoasa(config-network-object)#subnet 192.168.2.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic mapped_obj_2
Example-3: In this 3rd example, we have three zones as
follows:
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
DMZ → Security-level (50) → Subnet: 172.16.1.0/24 with
if-IP: 172.16.1.1 → nameif dmz
Outside → Security-level (0) → Subnet: 10.1.1.0/24 with
if-IP: 10.1.1.2 → nameif outside
Rule is to NAT inside zone to outside zone and inside zone
to DMZ zone depending upon the flow of traffic. Similarly NAT DMZ to outside
when traffic flows from DMZ to outside. Remember, as per firewall general rule,
zones or interfaces with higher security level can access zones or interfaces
with lower security-level and vice-versa is not true unless specified
explicitly using ACLs etc.
Prior to Version 8.3 or below:
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#nat (dmz) 1 172.16.1.0 255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3-10.1.1.50 netmask 255.255.255.0
ciscoasa(config)#global (dmz) 1 172.16.1.100-172.1.1.254 netmask 255.255.255.0
You might have noticed that nat-id is same for
all nat and global commands above, so
which real-IP/subnet will be translated to which mapped-IP/subnet? It
depends on flow of traffic. Traffic going from inside to DMZ will be translated
as (192.168.1.0/24 to 172.16.1.100-254/24), traffic flowing from inside to
outside will be (192.168.1.0/24 to 10.1.1.2-50/24) and traffic flowing from DMZ
to outside will be translated as (172.16.1.0/24 to 10.1.1.2-50/24)
In version 8.3 to 9.x
ciscoasa(config)#object network mapped_outside
ciscoasa(config-network-object)#range 10.1.1.3 10.1.1.50
ciscoasa(config)#object network mapped_dmz
ciscoasa(config-network-object)#range 172.16.1.100
172.16.1.254
ciscoasa(config)#object network inside_to_outside
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic mapped_outside
ciscoasa(config)#object network inside_to_dmz
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,dmz) dynamic mapped_dmz
ciscoasa(config)#object network dmz_to_outside
ciscoasa(config-network-object)#subnet 172.16.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (dmz,outside) dynamic mapped_outside
Dynamic Port Address Translation (PAT)
What if you own an enterprise network and your company
bought a single IP only which you have configured on an outside interface? Now
all the internal network hosts connected on inside interface needs to use this
single IP. How? Using PAT, we can use many-to-one translation
mechanism. This way, we can NAT many internal network IPs to single IP but
using different source port number for each translation. Source port numbers
can range from 1024-approx. 64000 and remember that only source ports
are translated when we use PAT.
Prior to Version 8.3 or below:
ciscoasa(config)#nat (real_interface_name) nat_id internal_network_IP_subnet
ciscoasa(config)#global (mapped_interface_name) nat_id external_network_IP netmask 255.255.255.255
In version 8.3 to 9.x
ciscoasa(config)#object network real_obj
ciscoasa(config-network-object)#subnet IP_Add Net_Mask
ciscoasa(config-network-object)#nat (inside_if,
outside_if) dynamic external_network_IP (not object)
Example-1: Assume we have only single IP configured on
outside interface and we need to PAT 192.168.1.0/24 over it:
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
Outside → Security-level (0) → Subnet: 10.1.1.2/30 → nameif outside
Prior to Version 8.3 or below:
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3 netmask 255.255.255.255
INFO: Global 10.1.1.3 will be Port Address Translated
What if we get dynamic IP from our ISP on outside interface
using DHCP? Below, ip address dhcp will receive dynamic IP from ISP
and setroute will set default-route towards ISP. The interface keyword
will help us to PAT 192.168.1.0/24 internal network to the dynamic IP of
outside interface.
ciscoasa(config)#interface GigabitEthernet 0/0
ciscoasa(config-if)#ip address dhcp setroute
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3 interface
INFO: outside interface address added to PAT pool
In version 8.3 to 9.x
ciscoasa(config)#object network real_obj
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic 10.1.1.3
Using dynamic IP received via DHCP from ISP:
ciscoasa(config)#interface GigabitEthernet 0/0
ciscoasa(config-if)#ip address dhcp setroute
ciscoasa(config)#object network real_obj
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic interface
Example-2:
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
Inside → Security-level (100) → Subnet: 192.168.2.0/24 with
if-IP: 192.168.2.1 → nameif inside
Outside → Security-level (0) → Subnet: 10.1.1.0/29 with
if-IP: 10.1.1.2 → nameif outside
Goal is to PAT 192.168.1.0/24 to 10.1.1.3/32 and PAT 192.168.2.0/24
to 10.1.1.4/32
Prior to Version 8.3 or below:
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.3 netmask 255.255.255.255
ciscoasa(config)#nat (inside) 2 192.168.2.0
255.255.255.0
ciscoasa(config)#global (outside) 2 10.1.1.4 netmask 255.255.255.255
In version 8.3 to 9.x
ciscoasa(config)#object network real_obj_1
ciscoasa(config-network-object)#subnet 192.168.1.0
255.255.255.0
ciscoasa(config)#nat (inside,outside) dynamic 10.1.1.3
ciscoasa(config)#object network real_obj_2
ciscoasa(config-network-object)#subnet 192.168.2.0
255.255.255.0
ciscoasa(config)#nat (inside,outside) dynamic 10.1.1.4
Example-3: Using Dynamic NAT with PAT
Inside → Security-level (100) → Subnet: 192.168.1.0/24 with
if-IP: 192.168.1.1 → nameif inside
Outside → Security-level (0) → Subnet: 10.1.1.0/29 with
if-IP: 10.1.1.1 → nameif outside
Goal is to use dynamic NAT until all external subnet is
exhausted and then proceed to PAT on a single IP specified.
Prior to Version 8.3 or below:
ciscoasa(config)#nat (inside) 1 192.168.1.0
255.255.255.0
ciscoasa(config)#global (outside) 1 10.1.1.4-10.1.1.6 netmask 255.255.255.248
ciscoasa(config)#global (outside) 1 10.1.1.3 netmask 255.255.255.255
In version 8.3 to 9.x
ciscoasa(config)#object network mapped_obj_1
ciscoasa(config-network-object)#range 10.1.1.4 10.1.1.6
ciscoasa(config)#object network mapped_obj_2
ciscoasa(config-network-object)#host 10.1.1.3
ciscoasa(config)#object-group nat_pat
ciscoasa(config-network-object)#network-object object mapped_obj_1
ciscoasa(config-network-object)#network-object object mapped_obj_2
ciscoasa(config)#object network real_obj
ciscoasa(config-network-object)#subnet 192.168.1.0 255.255.255.0
ciscoasa(config-network-object)#nat (inside,outside) dynamic nat_pat
Difference Between Per-Session PAT and Multi-Session PAT in
ASA 9.x
Per-Session means at the end of each per-session connection,
firewall sends a reset and immediately terminates the respective TCP, UDP
or DNS connection, hence freeing up the resources. Per-session PAT is
enabled by default for TCP and UDP traffic and is quite efficient for hit and
run traffic like HTTP and HTTPS. Following commands in firewall configuration
proves that per-session
mechanism has been enabled:
xlate per-session permit tcp any4 any4
xlate per-session permit tcp any4 any6
xlate per-session permit tcp any6 any4
xlate per-session permit tcp any6 any6
xlate per-session permit udp any4 any4 eq domain
xlate per-session permit udp any4 any6 eq domain
xlate per-session permit udp any6 any4 eq domain
xlate per-session permit udp any6 any6 eq domain
Multi-Session PAT on the other hand terminates a session
after 30 seconds timeout. It is ideal if your network has H323, SIP, VoIP and
Skinny server installed. Lets say its IP is 192.168.1.1, then you need to
disable per-session PAT as follows by denying following staements
xlate per-session deny tcp any4 192.168.1.1 eq 1720
xlate per-session deny udp any4 192.168.1.1 range 1718 1719
Static NAT
Dynamic NAT and PAT are only used to translate
source inside IP/subnet to outside IP/subnet in outbounddirection
only. Whats the disadvantage? Clearly if a host from outside network try to
initiate a connection, it will fail. Why? Because of two reasons, that are:
xlate table will not have an entry for session since internal host never
intiated a session and there needs to configure an appropriate ACL.
Static NAT solves the issue by mapping an outside public IP
to a host on inside network. This means anyone over Internet can access a
server behind our firewall using the mapped IP.
Below is command syntax prior
to ASA version 8.3
ciscoasa(conf)#static (real_if,mapped_if) mapped_ip
real_ip netmask subnet_mask
Notice the catch here, the real_if comes first to mapped_if
in parenthesis but mapped_ip comes first after that and then real_ip is
mentioned.
In ASA 8.3 to 9.x under network object section:
ciscoasa(config-network-object)#nat (real_if,mapped_if) static {mapped_ip
| mapped obj}
Example-1: Lets say we have two servers in DMZ and all
hosts on inside zone. These servers on DMZ (10.0.0.1 and 10.0.0.2) needs to be
accessed beyond outside interface using mapped IPs as 100.1.1.1 and
100.1.1.2.
On Cisco ASA running version prior to 8.3
ciscoasa(conf)#static (dmz,outside)
100.1.1.1 10.0.0.1 netmask 255.255.255.255
ciscoasa(conf)#static (dmz,outside) 100.1.1.2 10.0.0.2 netmask 255.255.255.255
On ASA 8.3 or above
Its simple, instead of using dynamic keyword,
use static under network-object command section:
ciscoasa(config)#object network dmz_server_1
ciscoasa(config-network-object)#host 10.0.0.1
ciscoasa(config-network-object)#nat (dmz,outside) static 100.1.1.1
ciscoasa(config)#object network dmz_server_2
ciscoasa(config-network-object)#host 10.0.0.2
ciscoasa(config-network-object)#nat (dmz,outside) static 100.1.1.2
Example-2: Lets say we want to map whole subnet in
dmz statically i-e 10.0.0.0/24 to 100.1.1.0/24. Lets do it with one command.
On Cisco ASA running version prior to 8.3
ciscoasa(conf)#static (dmz,outside) 100.1.1.0 10.0.0.0 netmask 255.255.255.0
On ASA 8.3 or above
ciscoasa(config)#object network mapped_obj
ciscoasa(config-network-object)#subnet 100.1.1.0
255.255.255.0
ciscoasa(config)#object network dmz_obj
ciscoasa(config-network-object)#subnet 10.0.0.0
255.255.255.0
ciscoasa(config-network-object)#nat (dmz,outside) static mapped_obj
Example-3: Lets say we have single public outside IP
and two servers in DMZ. Web-server 10.0.0.1 listens on port 80 and mail server
10.0.0.2 listens on port 25. Lets mapped them on a single outside IP address.
On Cisco ASA running version prior to 8.3
ciscoasa(conf)#static (dmz,outside) tcp 100.1.1.1
80 10.0.0.1 80 netmask 255.255.255.255
ciscoasa(conf)#static (dmz,outside) tcp 100.1.1.1 25
10.0.0.2 25 netmask 255.255.255.255
What if mapped IP is assigned via DHCP by your ISP?
ciscoasa(conf)#static (dmz,outside) tcp interface 80
10.0.0.1 80 netmask 255.255.255.255
ciscoasa(conf)#static (dmz,outside) tcp interface 25
10.0.0.2 25 netmask 255.255.255.255
On ASA 8.3 or above
ciscoasa(config)#object network dmz_server_1
ciscoasa(config-network-object)#host 10.0.0.1
ciscoasa(config-network-object)#nat (dmz,outside) static 100.1.1.1
80 80
ciscoasa(config)#object network dmz_server_2
ciscoasa(config-network-object)#host 10.0.0.2
ciscoasa(config-network-object)#nat (dmz,outside) static 100.1.1.1
25 25
First port is real and 2nd is mapped one. Incase mapped IP
is attained via DHCP, use interface keyword.
Identity NAT or NAT 0
If you have servers with public IP in DMZ, why would you
NAT/PAT them? Incase you have applied nat-controlcommand, you must
have a match in NAT translations. NAT 0 or identity NAT can fix this issue.
Assuming we have a public IP pool of 15.0.0.0/24 and we have assigned to DMZ,
lets exclude it by NAT’ing this subnet to its ownself which is also known
as transparent mapping.
How to do it on Cisco ASA 7.x, 8.1, 8.2:
ciscoasa(config)#nat (dmz) 0 15.0.0.0 255.255.255.0
Or it can also be done via static mapping:
ciscoasa(config)#static (dmz,outside) 15.0.0.0
15.0.0.0 netmask 255.255.255.0
However there is a difference which I found in above two.
The difference is that when you do identity NAT using nat command,
you will be only able to communicate if you initiate a communication from
high-security-level zone to low-security-level zone but vice-versa is true only
if you do identity NAT with static command. I assume nat-control is
enabled.
On ASA 8.3 or above
ciscoasa(config)#object network mapped_obj
ciscoasa(config-network-object)#subnet 15.0.0.0
255.255.255.0
ciscoasa(config)#object network dmz_servers
ciscoasa(config-network-object)#subnet 15.0.0.0
255.255.255.0
ciscoasa(config-network-object)#nat (dmz,outside) static mapped_obj
You can specify host instead as well for identity
NAT. Remember, suitable entry in outside ACL needs to be made incase of
identity NAT.
Manual NAT or Twice NAT
Although, most of the NAT requirements are completed using
Dynamic NAT, Static NAT or Identity NAT but in some cases, we must use Dynamic
NAT with Identity NAT. What it means, that we must exclude an IP or range of
IPs from NAT rules and do the transparent mapping for them. In such cases, we
use Manual NAT or Twice NAT where we define NAT statement outside
network-object section incase of version 8.3 or above. Before that, its simple
as follows:
Assume we don’t want to NAT traffic of subnet 192.168.1.0/24
going towards subnet 192.168.2.0/24
ciscoasa(config)#access-list EXCLUDE extended permit ip
192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0
ciscoasa(config)#nat (dmz) 0 access-list EXCLUDE
On ASA 8.3 or above
ciscoasa(config)#object network source_obj
ciscoasa(config-network-object)#subnet 192.168.1.0 255.255.255.0
ciscoasa(config)#object network dest_obj
ciscoasa(config-network-object)#subnet 192.168.2.0 255.255.255.0
ciscoasa(config)#nat (dmz,outside) source static source_obj source_obj destination dest_obj dest_obj