Showing posts with label NAT. Show all posts
Showing posts with label NAT. Show all posts

Monday, August 28, 2017

Cisco ASA -- Intro to NAT, Auto NAT and Twice NAT

A couple of years ago, I first started working with Cisco ASA firewalls. One of the things that has driven me nuts about the ASA is how complicated it makes NAT. From my experience with Linux, I was aware of Source NAT, Destination NAT and Masquerading. However, the ASA added several other variations on the theme: Single NAT, Auto NAT, Twice NAT, and most bizarre of all, Identity NAT. Cisco documentation and most other network references I consulted didn't clear things up much (if at all). Since I tend to learn best by being hands-on, I fired up GNS3 and started playing around with an emulated ASA.

First, single NAT. In this scenario, you manually create a NAT translation. In most cases, you have a private network using IP addresses defined in RFC-1918 on the inside of your firewall. Since this address space is not routable on the public Internet, you must rewrite the source address of any packet originating on your private network if you want to reach a host outside of your network. Likewise, if you have a server inside your private network that should be reachable from the Internet, incoming packets must have the destination IP address rewritten as they cross your firewall. This is pretty straightforward on the ASA. Given the following interface configuration...:

interface GigabitEthernet0.10
description INSIDE
vlan 10
nameif INSIDE
security-level 100
ip address 192.168.1.1 255.255.255.0
!
interface GigabitEthernet0.300
description OUTSIDE
vlan 300
nameif OUTSIDE
security-level 0
ip address 100.64.1.53 255.255.255.248
!

Next, we will define the client PC's "real" and "mapped" IP addresses (the IP address actually configured on the client, and the IP address that Internet hosts will see, respectively):

object network CLIENT
host 192.168.1.3
object network CLIENT-OUTSIDE
host 100.64.1.129

Finally, we create the NAT statement to translate the client's real IP to the mapped IP:

nat (INSIDE,OUTSIDE) source static CLIENT CLIENT-OUTSIDE

Now, when the client tries to reach a host on the public Internet, the firewall will rewrite incoming and outgoing packets as described above. To test this, I created a simple CGI script on a web server that displays the "environment variables" passed to the CGI in an HTTP session:



As you can see, the web server sees the client PC's IP address as 100.64.1.3 (okay, yes, technically, that is not a publicly routable IP address either, but is instead a "Carrier-grade NAT" address, a special private IP space address, but even in my labs in GNS-3, I don't like to use real public IP address space). Pretty simple, right?

Next up, Auto NAT (or Object-NAT, IIRC -- if I'm wrong, please leave a comment below!). Object-NAT looks very simple, and in many on-line tutorials I've seen, is described as one of the simplest ways of setting up NAT on a firewall. However, I have found it to be quite finicky, at least on the version of ASA code that I'm using in GNS3. More than once, I have copied an existing config, changing IP addresses and object names as required, but finding one config works while the other does not. Even more frustrating, the ASA code that I'm using in GNS3 is much older than the code I'm using in the real world, and the object-NAT configuration is slightly different between the two versions. Despite these differences, let's give object-NAT a try.

For the object-NAT example, we'll use the following network:



...and the following network objects:

1. The Knoppix Clone's real (RFC-1918) IP address:
object network CLONE-REAL-IP
host 192.168.1.2
!

2. The Knoppix Clone's NAT (i.e., "public") IP address:
object network CLONE-NAT-IP
host 100.64.1.2
!

3. The Knoppix Host's real (RFC-1918) IP address:
object network K32-REAL-IP
host 10.0.0.2
!

4. The Knoppix Host's NAT IP address:
object network K32-NAT-IP
host 100.64.0.2
!

The Knoppix Clone will be on our "inside" network, and Knoppix-32 will be on the "public" network. Yes, I know -- I am using private IP addresses for everything, but just play along, okay? ;) Auto-NAT is sometimes called Object-NAT because the NAT statement exists inside of an "object network ..." statement:
object network CLONE-NAT-IP
nat (Side_B,Side_A) nat (SIDE_B,SIDE_A) source dynamic CLONE-REAL-IP CLONE-NAT-IP
!

Just for giggles, try this after setting up the object NAT shown above:

sho run | begin CLONE-NAT-IP

Most likely, you saw something like this:

object network CLONE-NAT-IP
host 100.64.1.2
object network K32-REAL-IP
host 10.0.0.2
object network K32-NAT-IP
host 100.64.0.2
...

Wait a minute...what happened to our NAT statement? Well, if you keep scrolling, you'll see it somewhere down near the end of the config. For whatever reason, Cisco decided it made sense to break the object definition in two, putting the host (or subnet or range or...) portion in one place in the config and the NAT portion in another </shrug> Don't ask me; I don't know why, either.

In any case, now that the NAT rule has been created, let's try to ping the Knoppix Clone from the Knoppix Host:
        Side_A pings Side_B:
        ping 100.64.1.2

        Side_A tcpdump:
          10.0.0.2 > 100.64.1.2
          10.0.0.2 > 100.64.1.2

        Side_B tcpdump:
...nothing...

Next, we'll try pinging from the Knoppix Clone to the Knoppix Host:
        Side_B pings Side_A:
        ping 10.0.0.2

        Side_A tcpdump:
          100.64.1.2 > 10.0.0.2
          10.0.0.2 > 100.64.1.2

        Side_B tcpdump:
          192.168.1.2 > 10.0.0.2
          10.0.0.2 > 192.168.1.2

Did that make sense? Because this NAT translation only allows traffic to originate on the inside network (established, related packets will always be allowed back in with a stateful firewall), the Knoppix Host cannot ping the Knoppix Clone, but the Knoppix Clone can ping the Knoppix Host.

Things really get interesting, however, with Twice NAT. In this situation, not only do you want to rewrite the IP address of a system on the INSIDE network, but you also want to rewrite the IP address of a system on the OUTSIDE network as well. Why? Well...I don't know. But if for some reason you do, here's how to do it :)

We'll use the same ASA interface configuration that we used in the discussion of Single NAT above.

Next, we'll define the objects used in this config. As in the Single NAT and Auto NAT discussion, we'll use "CLIENT" to mean the host on the inside network and "CLIENT-OUTSIDE" to mean the NAT'd IP address of the client host (the IP that outside hosts see the request coming from). However, we will create two new objects, "MAPPED-DEST" which is the IP address that CLIENT will use in URL's, ping commands, etc. and "REAL-DEST" which is the actual IP address of the host on the OUTSIDE network. In other words, just as "CLIENT" refers to the actual IP address configured on the host on the INSIDE network, "REAL-DEST" refers to the actual IP address configured on host on the OUTSIDE network. Likewise, just like "CLIENT-OUTSIDE"refers to the IP address that OUTSIDE hosts use to reach the INSIDE network, "MAPPED-DEST" refers to the IP address that INSIDE hosts use to reach the OUTSIDE network:

object network MAPPED-DEST
host 172.16.0.1
object network REAL-DEST
host 100.64.1.3

Finally, we create the NAT statement to set up the Twice NAT:

nat (INSIDE,OUTSIDE) source static CLIENT CLIENT-OUTSIDE destination static MAPPED-DEST REAL-DEST

The only difference between this config and the Single NAT config is the addition of "destination static MAPPED-DEST REAL-DEST" at the end of the NAT statement. On the CLIENT computer, we can now try to access the server on the OUTSIDE network using the IP address 172.16.0.1:


As you can see, we are accessing the web server on the outside network by using the IP address 172.16.0.1, even though the IP address on the server is actually 100.64.1.3. Likewise, the web server sees the request coming from 100.64.1.129, even though the client's IP address is actually 192.168.1.3. In other words, we are NAT'ing both the INSIDE and OUTSIDE networks.

For our last example, we'll set up identity-NAT. I have to admit, this twist on NAT really threw me when I first encountered it. "Wait, you mean to tell me that we are creating a NAT rule to rewrite an incoming packet to use the EXACT SAME IP address it originally had?!?!" At first, it does seem a little silly, doesn't it? However, consider this scenario: you have a firewall with an inside and outside network, and you have an object-NAT rule to translate outgoing requests to a pool of publicly routable IP addresses. However, for some reason, there is a host or subnet connected to your outside interface that you wish to access via your private, inside IP addresses. For example, it is possible that in a large enterprise network, you might have firewalls between various departments inside the company. These firewalls might do the NAT translations from RFC-1918 addressing to public addressing, but you might still want to access a resource in another department via your private IP range (that's kinda-sorta the situation with one of the ASA's I currently manage). In this case, the identity-NAT rule will override the object-NAT rule for the objects that you specify. In terms of configuring identity-NAT, it's pretty much the same as single-NAT, except that you use the same source object and destination object in the NAT rule:

object network CLIENT
host 192.168.1.3
object network CLIENT-OUTSIDE
host 100.64.1.129
!
nat (INSIDE,OUTSIDE) source static CLIENT CLIENT

No, that's not a typo -- I really did mean "CLIENT CLIENT" in the NAT rule. Essentially, we are saying, "When a packet comes into the INSIDE interface with the IP address 192.168.1.3, rewrite the packet exiting the OUTSIDE interface with the source IP address of 192.168.1.3. This works because the ASA follows a hierarchy much like the mathematical concept of "order of operations" to determine at what point the various types of NAT will be performed. In this case, the identity NAT will happen after the object-NAT, so the identity-NAT rule will override the object-NAT.

Monday, July 14, 2014

Advanced Cisco Routing -- Route Maps

So far, all of our routing examples have been pretty straight-forward: to reach network "A" you take route "A," and to reach network "B" you take route "B," etc. Suppose, however, that you need to filter routes between different WAN sites? Specifically, consider the following list of requirements:

  1. Multiple WAN sites with RFC-1918 IP space on the inside of the networks;
  2. Direct Nat'ed Internet links at each WAN site;
  3. Point-to-Point links (T1's, VPN tunnels, etc.) between WAN sites to route the internal LANs together;
  4. OSPF routing between internal LAN subnets.


In this case, you can use a route map to filter what networks OSPF is advertising. Here's how you do it:

First, here is the network topology for our example:
In this drawing, we'll use router R1 as our Anchorage router, R2 as our Fairbanks router, R4 and R5 will be random hosts on the internal LANs of R1 and R2 (respectively), and R3 will represent the Internet network between R1 and R2. Here is the basic configuration for R1 (the Anchorage router):

interface FastEthernet0/0
description LAN
ip address 192.168.1.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.1.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Fairbanks
ip address 172.16.1.1 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.1.1
!
access-list 1 permit 192.168.1.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

As you can see, we have set up NAT to map addresses on the two internal interfaces to the external IP address of 169.254.1.10, and we have created a default route to the Internet router at 169.254.1.1. At this point, any hosts on the internal network should be able to reach any publicly-accessible IP address.

Similarly, here is the basic configuration for the Fairbanks router:

interface FastEthernet0/0
description LAN
ip address 192.168.3.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.2.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Anch
ip address 172.16.1.2 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.2.1
!
access-list 1 permit 192.168.3.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

With this configuration, R4 should be able to ping the outside interface on R2, and R5 should be able to ping the outside interface on R1 (assuming that R3, R4 and R5 have been configured with the appropriate IP addresses on their respective interfaces, and that R4 and R5 have default routes through R1 and R2, respectively). However, if you try to ping R5 from R4 or vice versa, you will find that the pings fail, because R1 and R2 are not yet advertising routes to their internal networks. You could create static routes on these routers to solve this problem, but that's why we have dynamic routing protocols -- to reduce the network admin's workload.

However, you don't want to send routes to public IP addresses over your internal-only links, and even more importantly, you don't want to advertise your RFC-1918 IP addresses on the public Internet (your service provider should already be filtering these, but...). Therefore, we want to make sure OSPF is only advertising our private LAN addresses over the point-to-point link, so we'll create a route map on R1 and R2 to filter what routes OSPF advertises.

The first step in creating a route map is creating the access control list (ACL) to identify the traffic we want OSPF to allow. On R1...:

access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

...and on R2...:
access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

Note: If you don't fully understand the ACL's we have created here, check out CCNA Lesson 12 for a more in-depth explanation of ACL's on a Cisco router.

Next, we create the route-map to allow the networks filtered by these access lists (configuration is the same on both R1 and R2):
route-map inside-ospf permit 10
match ip address 10
!

Finally, we create our OSPF configuration, referencing the route maps. On R1:

router ospf 42
router-id 192.168.1.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!

...and on R2:

router ospf 42
router-id 192.168.3.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!


Here's what's happening in the router. We are creating the ACL to match our internal LAN traffic (192.168.1.0/24, 192.168.3.0/24, and 172.16.1.0/30). Then, we are creating a route map called "inside-ospf" to match the networks defined in ACL 10. Finally, OSPF is redistributing the networks referenced in the route-map "inside-ospf." If a network does not match the ACL, for example 169.254.1.0/26 (the network attached to fa1/0 on router R1), OSPF does not forward that route to other OSPF-enabled routers in that area. You can verify that this is working by tracing routes to various networks from R4 or R5. Here is an example of two traceroutes from R5:

Router#traceroute 192.168.1.2

Type escape sequence to abort.
Tracing the route to 192.168.1.2

1 192.168.3.1 8 msec 8 msec 8 msec
2 172.16.1.1 24 msec 8 msec 16 msec
3 192.168.1.2 28 msec 16 msec *
Router#traceroute 169.254.1.10

Type escape sequence to abort.
Tracing the route to 169.254.1.10

1 192.168.3.1 8 msec 4 msec 8 msec
2 169.254.2.1 16 msec 12 msec 8 msec
3 169.254.1.10 28 msec 25 msec *
Router#

You can see the traceroute follows the P-t-P link from R2 to R1 to reach 192.168.1.2, but follows the "Internet" link to reach the outside interface of R1, which is exactly what we wanted.

Reference:Cisco's "Route Maps for IP Routing Protocol Redistribution Configuration" web page.

Thursday, September 26, 2013

Lesson 3 -- Network Address Translation

In our last lab, we set up a router to connect our company's small local area network to the Internet. However, in the first lab, we decided to use RFC-1918 addresses for our internal network. That causes a problem, unfortunately. RFC-1918 addresses are private, internal-only addresses, meaning most Internet Service Provider's routers won't route traffic to or from RFC-1918 addresses. At the ISP where I used to work, the network admins called RFC-1918 addresses "bogons" because those addresses were bogus on the Internet. So do we have to start over? Do we need to reconfigure all of our network equipment to use valid IP addresses?

Nope! There is a technology -- or more accurately, two closely related technologies that are often confused with each other -- that will allow our router to act as a "translator" between our internal network and the Internet. These technologies are often called "Network Address Translation" or "NAT," although what most people typically mean by the term is more accurately called "Port Address Translation" or "PAT." "NAT" refers to substituting a public IP address on the router for a private IP address inside the LAN -- basically, when the router receives an outbound packet, it rewrites the Source field of the IP packet with a public IP address assigned to the router's external interface. This is a one-to-one translation: if two hosts inside the LAN need to communicate with external hosts, there must be two IP addresses on the router's external interface. With "PAT," however, the router uses a combination of source port and a single, external interface to uniquely identify traffic for each internal host.

Let's set up port address translation on our company router:

lab2651rtr# conf t
lab2651rtr(config)# int fa0/0
lab2651rtr(config-if)# ip nat inside
lab2651rtr(config-if)# int fa0/1
lab2651rtr(config-if)# ip nat outside
lab2651rtr(config-if)# exit
lab2651rtr(config)# access-list 1 permit 192.168.1.0 0.0.0.255
lab2651rtr(config)# ip nat inside source list 1 interface FastEthernet0/1 overload


Essentially, what we are doing is creating a filter ("access-list 1 permit 192.168.1.0 0.0.0.255" -- we'll discuss access lists in a lot more detail later on), then using that filter to allow certain traffic (anything coming from a 192.168.1.xxx address) to be dynamically mapped to the router's external interface.

If you think about it, that's pretty cool, actually. Your computers and workstations inside your local area network can now communicate with other hosts on the Internet, but only Internet hosts that have an lready-established communication channel with your internal hosts can get back in through your router. Not only that, but a black hat on the Internet doesn't know the internal structure of your network when you are using NAT. Yeah, I'm familiar with the saying about security through obscurity. I'm not saying that you shouldn't take reasonable precautions to ensure network and PC security, but I would argue that hiding the details of your network design behind NAT can certainly be an effective layer of our security plan. Why give an attacker any more information than you have to?

However, there is a price to be paid for this feature (some would call it an ugly hack on IPv4 to handle the flaws inherent in the IPv4 addressing scheme, but meh...). First, since external hosts can only communicate with internal hosts that have already initiated a conversation with them, NAT will break services that you want to be initiated from outside your network. For example, if you build a public web server to advertise for your company, or an e-mail server that you want to be able to receive mail from other corporations, NAT will break these services. Furthermore, some protocols, for example SIP (which is commonly used in voice over IP telephony) do not work well when NAT'ted. There are work-arounds for these problems, fortunately. Servers that should have an external presence as well as an internal presence can be placed in a DMZ or you can configure additional external IP addresses on your router that map statically to the internal IP address of your servers.

At this point, your hosts should be talking on the Internet and to each other. That makes this a good point to stop for the night again. We'll pick up tomorrow with a tool to make it easier for you to assign IP addresses to hosts on your network.