You are on page 1of 25

Introduction

The ASA is relatively new to me. I was not one of those RS CCIEs that did a lot of security work on the old PIX and the ASA when I was coming up the ranks of the routing and switching track. I mainly stuck to learning routing and switching really well and usually there was a dedicated team of guys doing the security stuff. Time for that to change. I have to admit that NAT and PAT on the ASA has been an intimidating topic for me for a long time. I have spent a lot of time this week trying to straighten things out. I understand all of the basic concepts. Some of the more advanced things and weird rule restrictions are a bit fuzzy to me but I am confident they will come with time, experience and practice like anything. My goal in this post is to cover every basic type of NAT or PAT I can think of on the ASA and configure each of them individually. Keep in mind this is all based on < 8.3 ASA code since that is what we currently care about for CCIE security v3.0

Lab Topology

OK boys, time to pop the cherry on that fancy new security vrack : ) I tried to come up with a simple topology that would allow me to test all the NAT features I wanted to play with. Here is what I came up with. Note, all the different NAT types are going to be tested independently so we wont be worrying about NAT order of operations here. The goal is to just get a strong fundamental knowledge of the technology at this stage.

NAT Control

A quick word on nat-control. Back in the day on the PIX, it was absolutely necessary to NAT between interfaces. The ASA does not have this requirement. The default command no nat-control makes this happen. With no nat control configured, we have no requirement to NAT. We can still do so if we want, but there is nothing saying we have to. If we want the ASA to act more like the old PIX firewall we can add nat-control to make that happen. I am going to do that here, since it is a lab specifically on NAT and I want to make sure it is always enforced. Basically, the rule is If traffic is flowing from a higher security to a lower security interface, you MUST NAT the traffic. What confused me for a while was the question Well what about traffic from low to high, like a DMZ accessing the inside? Is an ACL rule on the DMZ enough to permit this traffic? The answer is no, you still need a NAT rule in place. Why? The return traffic. Say a host in the DMZ with security level 50 pings a host on the inside with security level 100. Since it is low to high the initial ping does not require a NAT rule, only an ACL exeption on the DMZ interface. When the ping hits the host on the inside

and the ICMP echo-reply comes back the traffic is now high to low. Without a NAT in place, the return traffic will be dropped by the ASA.

Initial Configurations

R1
interface Loopback0 ip address 1.1.1.1 255.255.255.255 ! interface FastEthernet0/0 ip address 10.10.10.1 255.255.255.0 speed 100 full-duplex ! ip route 0.0.0.0 0.0.0.0 10.10.10.12

R2
interface Loopback0 ip address 2.2.2.2 255.255.255.255 ! interface FastEthernet0/0 ip address 123.123.123.2 255.255.255.0

speed 100 full-duplex ! ip route 0.0.0.0 0.0.0.0 123.123.123.12

R3
interface Loopback0 ip address 3.3.3.3 255.255.255.255 ! interface FastEthernet0/0 ip address 123.123.123.3 255.255.255.0 speed 100 full-duplex ! ip route 0.0.0.0 0.0.0.0 123.123.123.12

ASA1
interface Ethernet0/1 nameif inside security-level 100 ip address 10.10.10.12 255.255.255.0 !

interface Ethernet0/3 nameif outside security-level 0 ip address 123.123.123.12 255.255.255.0 ! nat-control route inside 1.1.1.1 255.255.255.255 10.10.10.1 1 route outside 2.2.2.2 255.255.255.255 123.123.123.2 1 route outside 3.3.3.3 255.255.255.255 123.123.123.3 1 ! access-list OUTSIDE permit icmp any any access-list OUTSIDE permit tcp any any eq telnet access-group OUTSIDE in interface outside ! policy-map global_policy class inspection_default inspect icmp

Lets get started. How about an initial ping from R1 to R2s loopback?
R1#ping 2.2.2.2

Type escape sequence to abort.

Sending 5, 100-byte ICMP Echos to 2.2.2.2, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)

Not good. Why? Remember, we have NAT control enabled on the ASA and have not setup any translations. If we examine the ASA console logs we see:
%ASA-3-305005: No translation group found for icmp src inside:10.10.10.1 dst outside:2.2.2.2 (type 8, code 0)

Fair enough. That brings us to our first topic, bypassing NAT

Bypassing NAT

There are three ways to skin this cat, but it is important to be aware of the differences.
NAT exemption Purpose: Conditionally bypass NAT based on ACL Direction: Communication can be initiated from either the higher or lower security level interface Syntax: nat (interface) 0 access-list <ACL>

We will start our labbing by configuring NAT exemption. We will simply configure an access-list that defines traffic moving from the inside to the outside and then apply the NAT exemption on the ASA
access-list NAT-EXEMPTION-INSIDE extended permit ip 10.10.10.0 255.255.255.0 123.123.123.0 255.255.255.0 access-list NAT-EXEMPTION-INSIDE extended permit ip 10.10.10.0 255.255.255.0 host 2.2.2.2

access-list NAT-EXEMPTION-INSIDE extended permit ip 10.10.10.0 255.255.255.0 host 3.3.3.3 ! nat (inside) 0 access-list NAT-EXEMPTION-INSIDE

Lets test
R1#ping 123.123.123.2

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

R1#ping 123.123.123.3

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

R1#ping 2.2.2.2

Type escape sequence to abort.

Sending 5, 100-byte ICMP Echos to 2.2.2.2, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 228/337/416 ms

R1#ping 3.3.3.3

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

R1#ping 123.123.123.2 so lo0

Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 123.123.123.2, timeout is 2 seconds: Packet sent with a source address of 1.1.1.1 ..... Success rate is 0 percent (0/5)

As expected, everything worked fine except the last ping. Why? We sourced it from 1.1.1.1 and that source was not included in the NAT exemption. The ASA tells us very clearly:

%ASA-3-305005: No translation group found for icmp src inside:1.1.1.1 dst outside:123.123.123.2 (type 8, code 0)

Does it work the other way (low to high) ?


R2#ping 10.10.10.1

Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.10.10.1, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 128/183/248 ms R3#ping 10.10.10.1

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

Good! Moving on to static identity NAT then

Static identity NAT Purpose: Bypass NAT by translating a real IP address to the same IP address Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) real_IP real_IP netmask <mask>

On the surface the point of this looks very similar to our NAT exemption. One key difference is with NAT exemption we only specify the inbound interface, then let the ACL decide where the traffic is going. That means we can bypass NAT for a certain source going to multiple different places like the outside or a DMZ. With static identity NAT we specifically tie things to an inbound and outbound interface. It is basically a special version of a static NAT and the static NAT stays in the translation table indefinitely I have removed the previous NAT configuration. We apply the following to the ASA ciscoasa(config)# static (inside,outside) 10.10.10.1 10.10.10.1 This has the same effect as what we just did with NAT exemption in this specific scenario. Notice, the static translation is always present in the ASA:
ciscoasa# sh xlate detail | b NAT NAT from inside:10.10.10.1 to outside:10.10.10.1 flags s

Static policy identity NAT Purpose: Conditionally bypass NAT by translating a real IP address to the same IP address based on ACL Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) real_IP access-list <ACL>

This can be used to bypass NAT in certain situations but NAT as usual in other situations. For example, if we want R1 to bypass NAT when accessing R2 but NAT as usual when accessing R3 we can do something like this:
access-list STATIC-IDENTITY-NONAT extended permit ip host 10.10.10.1 host 123.123.123.2 access-list STATIC-IDENTITY-NAT extended permit ip host 10.10.10.1 host 123.123.123.3 !

static (inside,outside) 10.10.10.1 access-list STATIC-IDENTITY-NONAT static (inside,outside) 123.123.123.13 access-list STATIC-IDENTITY-NAT

When pinging from R1 to R2 the ASA shows us the following. Notice the gaddr field is 10.10.10.1 ..we did not NAT.
%ASA-6-302020: Built outbound ICMP connection for faddr 123.123.123.2/0 gaddr 10.10.10.1/19 laddr 10.10.10.1/19 %ASA-6-302021: Teardown ICMP connection for faddr 123.123.123.2/0 gaddr 10.10.10.1/19 laddr 10.10.10.1/19

However, when pinging from R1 to R3 the ASA NATs 10.10.10.1 to 123.123.123.13. Notice the gaddr field here is 123.123.123.13. R2 can ping 10.10.10.1 as expected with no NAT happening. The interesting thing is that so can R3. R3 is able to ping 10.10.10.1 without any issues. Even though we are specifying a NAT from R1 to R3 with an ACL it seems the reverse is not true. I believe the reason is because the destination portion of the ACL is not considered when traffic moves from the lower to higher security level interface during static policy NAT. Because the connection is initiated from the outside, when the return traffic comes back from high to low there is already a connection in the state table and it goes through without NAT. This means that in effect, ANYTHING on the outside could access 10.10.10.1. If somebody knows for sure, let me know!
%ASA-6-302020: Built outbound ICMP connection for faddr 123.123.123.3/0 gaddr 123.123.123.13/20 laddr 10.10.10.1/20 %ASA-6-302021: Teardown ICMP connection for faddr 123.123.123.3/0 gaddr 123.123.123.13/20 laddr 10.10.10.1/20

Identity NAT Purpose: Bypass NAT by translating a real IP address to the same IP address Direction: Higher security can initiate to lower security level interface only. Also identity NAT is applied for ALL outbound interfaces. You cannot translate a real address to itself when going out one outbound interface but do something else with it going out another interface. Syntax: nat (interface) 0 <network> <mask>

This is essentially a special version of dynamic NAT. Note, when you do identity NAT it is valid for ALL outbound interfaces. Lets configure it.
ciscoasa(config)# nat (inside) 0 10.10.10.0 255.255.255.0 nat 0 10.10.10.0 will be identity translated for outbound

Basically what we are saying is that if traffic comes in on the inside interface from 10.10.10.0/24 it will be identity NATd. Remember, this is regardless of where it is destined to. Also remember, since it is effectively a dynamic NAT that means the traffic can only be initiated from the inside because the entry in the NAT table is only added when the inside initiates the connection.

Static NAT

There are two basic kinds of static NAT Regular static NAT and static policy NAT. They both essentially do the same thing, but with static policy NAT we can make our static NAT conditional by tying it to an ACL
Static NAT Purpose: Translate a single real IP address or subnet to a single mapped IP address or subnet in a 1-1 fashion Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) <mapped_IP> <real_IP> netmask <mask>

A static NAT is relatively straight forward. On the ASA we can actually translate a single address or an entire subnet. In this case, lets test the basic f unctionality by static NATing 10.10.10.1 to the 123.123.123.13
static (inside,outside) 123.123.123.13 10.10.10.1 netmask 255.255.255.255

Lets telnet from R1 to R2

R1#telnet 2.2.2.2 Trying 2.2.2.2 ... Open

User Access Verification

Password: R2>who Line 0 con 0 * 98 vty 0 User Host(s) idle idle Idle 00:05:21 00:00:00 123.123.123.13 Location

We can see that from R2s perspective we are logged in from 123.123. 123.13 because the NAT was successful!
Static Policy NAT Purpose: Conditionally translate a single real IP address or subnet to a single mapped IP address or subnet in a 1-1 fashion based on ACL Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) <mapped_IP> access-list <ACL>

With this variation of static NAT we can do different things with the ASA depending on where the traffic is coming from and going to by typing the NAT to an ACL. For example, lets say if I telnet from R1 to R2s loopback I want to NAT to 123.123.123.22 but if I telnet from R1 to R3s loopback I want to NAT to 123.123.123.33
access-list STATIC-NAT-22 extended permit ip host 10.10.10.1 host 2.2.2.2 access-list STATIC-NAT-33 extended permit ip host 10.10.10.1 host 3.3.3.3

! static (inside,outside) 123.123.123.22 static (inside,outside) 123.123.123.33 R1#telnet 2.2.2.2 Trying 2.2.2.2 ... Open access-list STATIC-NAT-22 access-list STATIC-NAT-33

User Access Verification

Password: R2>who Line 0 con 0 * 98 vty 0 R1#telnet 3.3.3.3 Trying 3.3.3.3 ... Open User Host(s) idle idle Idle 00:12:05 00:00:00 123.123.123.22 Location

User Access Verification

Password: R3>who Line User Host(s) Idle Location

0 con 0 * 98 vty 0

idle idle

00:05:21 00:00:00 123.123.123.33

Remember, the destination of the ACL is not checked for traffic coming from the lower security to higher security interface. This effectively means that anybody on the outside can access the mapped addresses 123.123.123.22 or .33 in this case. Lets prove that by telnetting from R2 to 123.123.123.22. When R2 telnets to R1 traffic will be sourced from the fa0/0 interface of 123.123.123.2 which is not specified in the ACL
R2#telnet 123.123.123.22 Trying 123.123.123.22 ... Open

User Access Verification

Password: R1>who Line 0 con 0 * 98 vty 0 User Host(s) idle idle Idle 00:02:38 00:00:00 123.123.123.2 Location

Static PAT

There are two basic kinds of static PAT Regular static PAT and static policy PAT. They both essentially do the same thing, but with static policy PAT we can make our static PAT conditional by tying it to an ACL. With static PAT we are basically manually doing port mapping / port forwarding.

Static PAT Purpose: Translate a single real IP address or subnet and TCP/UDP port to a single mapped IP address or subnet and TCP/UDP port Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) <tcp|udp> <mapped_IP> <mapped_port> <real_IP> <real_port> netmask <mask>

Lets say when we telnet to 123.123.123.12 on port 2323 from the outside, we want our traffic to hit 1.1.1.1 port 23 on the inside.
static (inside,outside) tcp interface 2323 1.1.1.1 telnet netmask 255.255.255.255 R2#telnet 123.123.123.12 2323 Trying 123.123.123.12, 2323 ... Open

User Access Verification

Password: R1>

Perfect!
Static Policy PAT Purpose: Conditionally translate a single real IP address or subnet and TCP/UDP port to a single mapped IP address or subnet and TCP/UDP port Direction: Communication can be initiated from either the higher or lower security level interface Syntax: static(inside,outside) <tcp|udp> <mapped_IP> <mapped_port> access-list <ACL>

This is basically static PAT but done conditionallyLets say that when R2 telnets to 123.123.123.12 port 2323 we want it redirected to R1 port 23but ONLY if it comes from 123.123.123.2, no other address. To me, this is particularly tricky for a few reasons. First, because the ACL must specify the traffic flow from the perspective of the real IP address. Secondly, because there is a nasty feature that goes along with it.
access-list STATIC-POLICY-PAT extended permit tcp host 1.1.1.1 eq telnet host 123.123.123.2 ! static (inside,outside) tcp interface 2323 access-list STATIC-POLICY-PAT

This worksR2 can access 123.123.123.12:2323 and be redirected to R1:23 no problem. The issue is that again, ANYBODY that accesses 123.123.123.12:2323 is redirected. This is a known issue CSCso79009. The bug basically says that when traffic hits the mapped address/port the source IP address of the packet is not checked. Similar to what we saw with regular static policy NAT earlier. This was fixed in 8.3 code but since I am running 8.0(2) I am screwed on this feature :P Oh wellwe get the basic idea here.

Dynamic NAT

Again, we have two basic kinds of dynamic NAT Regular and policy based with the policy based version giving us a bit more granularity by using an ACL. Dynamic NAT in and of itself can allow us to translate a pool of real addresses to a pool of mapped addresses completely dynamically. One big difference between this and static NATing an entire subnet is that with dynamic NAT the translation is not in the xlate table foreverit is as the name implies dynamic. This means the real host has to initiate the communication.

Dynamic NAT

Purpose: Translate a group of real IP addresses to a dynamic pool of mapped addresses Direction: Communication must be initiated by the real host Syntax: nat (interface) <ID> <network> <mask> global (interface) <ID> <mapped IP range>

Alrighty then, lets configure our little network to dynamically NAT the 10.10.10.0/24 and the 1.1.1.1/32 to 123.123.123.20 123.123.123.30.
nat (inside) 1 10.10.10.0 255.255.255.0 nat (inside) 1 1.1.1.1 255.255.255.255 global (outside) 1 123.123.123.20-123.123.123.30

Lets telnet from R1 to R2 and see what we get


R1#telnet 2.2.2.2 Trying 2.2.2.2 ... Open

User Access Verification

Password: R2>who Line 0 con 0 * 98 vty 0 User Host(s) idle idle Idle 00:00:48 00:00:00 123.123.123.20 Location

Good, now from R1 to R3but this time we will source things from 1.1.1.1
R1#telnet 3.3.3.3 /source-interface lo0 Trying 3.3.3.3 ... Open

User Access Verification

Password: R3>who Line 0 con 0 * 98 vty 0 User Host(s) idle idle Idle 00:01:39 00:00:00 123.123.123.21 Location

Good! Notice we were mapped to two different global addresses. Rock on.

Dynamic Policy NAT

Purpose: Conditionally translate a group of real IP addresses to a dynamic pool of mapped addresses based on ACL Direction: Communication must be initiated by the real host Syntax: nat (interface) <ID> access-list <ACL> global (interface) <ID> <mapped IP range>

Lets say we want to translate 10.10.10.0/24 to the pool 123.123.123.20 30 but ONLY if it is telnet traffic destined for 3.3.3.3

access-list DYN-POLICY-NAT extended permit tcp 10.10.10.0 255.255.255.0 host 3.3.3.3 eq telnet ! nat (inside) 1 access-list DYN-POLICY-NAT global (outside) 1 123.123.123.20-123.123.123.30

Lets try a simple ping from R1 to R3s loopback


R1#ping 3.3.3.3

Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 3.3.3.3, timeout is 2 seconds: .....

Nopethat was not specified in the ACL so it is not being NATd. Since we have nat control on, and there is no NAT the packet is dropped by the ASA. How about telnet to 2.2.2.2?
R1#telnet 2.2.2.2 Trying 2.2.2.2 ... % Connection refused by remote host

Same reasonnow the magic connection, R1 telnet to 3.3.3.3


R1#telnet 3.3.3.3 Trying 3.3.3.3 ... Open

User Access Verification

Password: R3>

Booya! While the connection is open check out the ASA xlate table
ciscoasa(config)# sh xlate detail 1 in use, 2 most used Flags: D - DNS, d - dump, I - identity, i - dynamic, n - no random, r - portmap, s - static NAT from inside:10.10.10.1 to outside(DYN-POLICY-NAT):123.123.123.20 flags i

Notice it is specified as a dynamic translation. After you disconnect eventually the NAT xlate gets torn down, as it is dynamic. The default is 3 hours.

Dynamic PAT

Again, we have two basic kinds of dynamic PAT Regular and policy based with the policy based version giving us a bit more granularity by using an ACL. Dynamic PAT allows us to do a 1 to many type mapping where we map many real IP addresses to a single mapped IP address. This works by multiplexing your traffic based on the TCP and UDP port numbers. So, say we had 10 hosts on the 10.10.10.0/24 inside network but we only had a single public IP address of 123.123.123.12. We could still allow everybody on the inside to access the outside so long as the traffic is TCP or UDP. Everybody would get mapped to the same outside address of 123.123.123.12. How does the ASA know what to do with return traffic then? Port numbers. When the ASA does the outbound translation, it looks at the source IP and port number, then generates a new source port and does the IP translation. So, a flow from

10.10.10.1:45678 > 123.123.123.3:23 ends up looking like 123.123.123.12:xxxxx > 123.123.123.3:23 where the xxxxx is a randomly generated source port. This makes the flow unique from say another inside host like 10.10.10.2 accessing 123.123.123.123:23 at the same time because the source port will be different.

Dynamic PAT Purpose: Translate a group of real addresses to a single mapped address by multiplexing TCP/UDP ports Direction: Communication must be initiated by the real host Syntax: nat (interface) <ID> <network> <mask> global (interface) <ID> <mapped IP|interface>

Notice the syntax is essentially the same as dynamic NAT but instead of specifying a mapped IP range we give it a single IP address. We will configure dynamic PAT for VLAN 10 so that traffic sourced from there will be PATd to the ASA outside interface
nat (inside) 1 10.10.10.0 255.255.255.0 global (outside) 1 interface R1#telnet 3.3.3.3 Trying 3.3.3.3 ... Open

User Access Verification

Password: R3>who Line User Host(s) Idle Location

0 con 0 * 98 vty 0

idle idle

00:04:02 00:00:00 123.123.123.12

Perfect!

Dynamic Policy PAT Purpose: Conditionally translate a group of real addresses to a single mapped address by multiplexing TCP/UDP ports Direction: Communication must be initiated by the real host Syntax: nat (interface) <ID> access-list <ACL> global (interface) <ID> <mapped IP|interface>

Finally we have the conditional version of dynamic PAT where we can control things down with an ACL. Lets say we want to dynamic PAT VLAN 10 to the ASA outside interface only if traffic is sourced from 1.1.1.1 and destined to 3.3.3.3. Again, unless the traffic is sourced from 1.1.1.1 and destined to 3.3.3.3, traffic trying to pass through the ASA will be dropped with a log similar to this:
%ASA-3-305005: No translation group found for tcp src inside:10.10.10.1/64496 dst outside:2.2.2.2/23

This is successful because it matches the ACL:


R1#telnet 3.3.3.3 /source lo0 Trying 3.3.3.3 ... Open

User Access Verification

Password: R3>

NAT Order Of Operations

What if you have multiple NAT rules going on and something overlaps? There is an order of operations. 1. NAT exemption (nat 0 access-list)In order, until the first match. Identity NAT is not included in this category; 2. Static NAT and Static PAT (regular and policy) (static) In order, until the first match. Static identity NAT is included in this category. 3. Policy dynamic NAT (nat access-list)In order, until the first match. Overlapping addresses are allowed. 4. Regular dynamic NAT (nat)Best match. Regular identity NAT is included in this category.

Summary

When you really look at it and break things down you essentially have:
Static NAT/PAT (regular and policy) Dynamic NAT/PAT

Essentially everything is a derivative of those things. I know there are some things I probably missed (namely outside NAT) and I know there are probably much more insane topologies and scenarios to get into, but I feel much more confident now in understanding the basics of NAT and PAT on the ASA.

Tonight I am starting INE WB1 ASA labs. Between that and IPX Volume 1 I am certain I will see all the various insane situations.

You might also like