Today I noticed something weird that I have not investigated further yet. There is a change of behavious in how Cisco ASA routes traffic in later versions of software. In later versions it takes NAT into consideration when doing routing decisions that it have never done before.
Let´s have a look at a simple example. A 3-legged ASA, inside, outside and dmz.
Inside network is 192.168.1.0/24 and does a dynamic NAT towards outside to allow for internet traffic.
interface GigabitEthernet1/2
nameif inside
security-level 100
ip address 192.168.1.1 255.255.255.0
!
object network inside-network
subnet 192.168.1.0 255.255.25.0
nat (inside,outside) dynamic interface
Outside network in my lab setup just runs dhcp.
interface GigabitEthernet1/1
nameif outside
security-level 0
ip address dhcp setroute
The dmz is 10.0.0.1/24. To allow for general outbound internet traffic the entire network is hidden behind the outside interface address just like the inside-network.
interface GigabitEthernet1/3
nameif dmz
security-level 50
ip address 10.0.0.1 255.255.255.0
!
object network dmz
subnet 10.0.0.0 255.255.255.0
nat (dmz,outside) dynamic interface
On the inside network there is a server called mail01 with ip 192.168.1.100. It is statically translated to the public ip 1.2.3.4 on internet.
object network mailserver
host 192.168.1.100
nat (inside,outside) static 1.2.3.4
Now, hosts on dmz needs to communicate with the mailserver using its public ip so I create a manual nat:
nat (dmz,inside) source static any any destination static mailserver_publ_ip mailserver
This line above kill traffic for the mailserver going to outside! If I try to ping something on internet from the mailserver and enable debug icmp trace I get the following output:
ICMP echo request from inside:192.168.1.100 to dmz:8.8.8.8 ID=34056 seq=0 len=56
ICMP echo request translating inside:192.168.1.100 to dmz:1.2.3.4
ICMP echo request from inside:192.168.1.100 to dmz:8.8.8.8 ID=34056 seq=1 len=56
ICMP echo request translating inside:192.168.1.100 to dmz:1.2.3.4
ICMP echo request from inside:192.168.1.100 to dmz:8.8.8.8 ID=34056 seq=2 len=56
ICMP echo request translating inside:192.168.1.100 to dmz:1.2.3.4
ICMP echo request from inside:192.168.1.100 to dmz:8.8.8.8 ID=34056 seq=3 len=56
ICMP echo request translating inside:192.168.1.100 to dmz:1.2.3.4
So, the routing table obviously tells that the destination 1.2.3.4 is via interface outside:
ciscoasa(config)# sh route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route, + - replicated route
Gateway of last resort is 10.200.40.1 to network 0.0.0.0
S* 0.0.0.0 0.0.0.0 [1/0] via 10.200.40.1, outside
C 10.200.40.0 255.255.254.0 is directly connected, outside
L 10.200.40.133 255.255.255.255 is directly connected, outside
C 192.168.1.0 255.255.255.0 is directly connected, inside
L 192.168.1.1 255.255.255.255 is directly connected, inside
ciscoasa(config)#
So, why is it sending the packet out on dmz? Obviously because of the NAT statement above. And if I change it from using “any any” as source to instead define the dmz network “source static dmz dmz…” it works. So, the firewall uses the nat statement to override the routing table.
This behaviour exists in code 9.5.2 but not in 9.3.3. I have yet to dig thru the release notes…
UPDATE:
http://packetpushers.net/understanding-when-a-cisco-asa-nat-rule-can-override-the-asa-routing-table/