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/
[…] http://nat0.net/asa-nat-and-routing-behaviour-changed/ […]