The Cisco ASA firewall doesn’t like traffic that enters and exits the same interface. This kind of traffic pattern is called hairpinning or u-turn traffic. In the first hairpin example I explained how traffic from remote VPN users was dropped when you are not using split horizon, this time we will look at another scenario.
Take a look at the following topology:
Above we have a webserver using IP address 192.168.2.2 on our internal LAN. The ASA is configured so that IP address 192.168.2.220 on the outside is translated to IP address 192.168.1.2. This allows users on the Internet to access our webserver.
What if we want our internal hosts to access the webserver using the same outside IP address (192.168.2.220) instead of its internal IP address (192.168.1.2)? We can do this by configuring hairpinning on our ASA. Take a look below:
H1 is on the same subnet as the webserver but is trying to reach the webserver using IP address 192.168.2.220. With the default configuration of our ASA, traffic will be routed to the outside and will never end up at the webserver.
Want to try this yourself? Here you will find the startup configuration of each device.
hostname H1 ! interface GigabitEthernet0/1 ip address 192.168.1.1 255.255.255.0 ! ip default-gateway 192.168.1.254 ! end
hostname Web ! interface GigabitEthernet0/1 ip address 192.168.1.2 255.255.255.0 ! ip default-gateway 192.168.1.254 ! end
hostname H2 ! interface GigabitEthernet0/1 ip address 192.168.2.3 255.255.255.0 ! ip default-gateway 192.168.2.254 ! end
hostname ASA1 ! interface GigabitEthernet0/0 nameif OUTSIDE security-level 0 ip address 192.168.2.254 255.255.255.0 ! interface GigabitEthernet0/1 nameif INSIDE security-level 100 ip address 192.168.1.254 255.255.255.0 ! object network WEB_SERVER host 192.168.1.2 access-list OUTSIDE_TO_INSIDE extended permit tcp any host 192.168.1.2 ! object network WEB_SERVER nat (INSIDE,OUTSIDE) static 192.168.2.200 access-group OUTSIDE_TO_INSIDE in interface OUTSIDE ! : end
Let’s see how the ASA is configured at the moment:
ASA1# show xlate 1 in use, 1 most used Flags: D - DNS, e - extended, I - identity, i - dynamic, r - portmap, s - static, T - twice, N - net-to-net NAT from INSIDE:192.168.1.2 to OUTSIDE:192.168.2.200 flags s idle 0:01:37 timeout 0:00:00
Above you can see that the ASA is currently only translating IP address 192.168.1.2 on the inside to IP address 192.168.2.200 on the outside. This allows a host on the outside to reach the webserver:
H2# H2#telnet 192.168.2.200 80 Trying 192.168.2.200, 80 ... Open
H1 on the inside however is unable to reach the webserver using the outside IP address:
H1#telnet 192.168.2.200 80 Trying 192.168.2.200, 80 ... % Connection timed out; remote host not responding
Let’s fix this!
The first thing we have to do is to tell our ASA to permit traffic that enters and exits the same interface:
ASA1(config)# same-security-traffic permit intra-interface
Now we can focus on the NAT configuration. First I will create some objects that match:
- the subnet of the internal hosts (192.168.1.0 /24).
- the translated outside IP address of the webserver.
- the inside IP address of the webserver.
- the TCP port that we use for HTTP traffic.
Here are the objects:
ASA1(config)# object-group network INTERNAL_HOSTS ASA1(config-network-object-group)# network-object 192.168.1.0 255.255.255.0
ASA1(config)# object network WEB_PUBLIC ASA1(config-network-object)# host 192.168.2.200
ASA1(config)# object network WEB_LOCAL ASA1(config-network-object)# host 192.168.1.2
ASA1(config# object service HTTP ASA1(config-service-object)# service tcp destination eq 80
Now we can configure the NAT translation: