So I ran into another interesting problem today at work. The solution was interesting to me so I thought I’d do a quick write up on it. As many people know, firewalls (ASAs in particular) handle ICMP traffic a little differently than most would expect. When doing a tracert from a linux box through a firewall I was something like this…
[root@CentosBox ~]# traceroute 4.2.2.2 -I
traceroute to 4.2.2.2 (4.2.2.2), 30 hops max, 40 byte packets
1 <removed Internal MLS> 0.471 ms 0.879 ms 1.061 ms
2 <removed ASA> 0.680 ms 1.340 ms 1.320 ms
3 * * *
4 * * *
5 * * *
6 * * *
7 * * *
8 * * *
9 vnsc-bak.sys.gtei.net (4.2.2.2) 44.674 ms * *
What’s interesting here is that it started to miss hops in the middle, but then suddenly arrived at the destination and replied. What confused me even more was that I could successfully ping 4.2.2.2. After reviewing the firewall I noted that ICMP inspection was enabled. My thought with ICMP inspection was that it would inspect ICMP (traceroute included) and allow it out and back in. After some further investigation I determined that this wasn’t the case.
ICMP inspection allows a one to one connection. That is, it allows one response for one request. In addition, it apparently doesn’t play well with ICMP time-exceeded messages. So now this makes sense. The first couple of hops work but once I get past the firewall the time-exceeded messages don’t get allowed back in with the inspection. To fix this, you need to explicitly allow it on the outside interface. I added….
access-list inbound extended permit icmp any any
Or if you want to be more specific with it you could do…
access-list inbound extended permit icmp any any unreachable
access-list inbound extended permit icmp any any time-exceeded
access-list inbound extended permit icmp any any echo-reply
Once you add those, you should see…
[root@CentosBox ~]# traceroute 4.2.2.2 -I
traceroute to 4.2.2.2 (4.2.2.2), 30 hops max, 40 byte packets
1 <removed Internal MLS> 0.471 ms 0.879 ms 1.061 ms
2 <removed ASA> 0.680 ms 1.340 ms 1.320 ms
3 73.205.28.1 (73.205.28.1) 15.812 ms 16.264 ms 16.243 ms
4 <removed hop> 17.192 ms 17.173 ms 17.172 ms
5 <removed hop> 16.126 ms 17.095 ms 17.080 ms
6 <removed hop> 19.412 ms 17.651 ms 17.586 ms
7 <removed hop> 33.128 ms 32.470 ms 32.329 ms
8 4.79.82.57 (4.79.82.57) 35.257 ms 76.288 ms 76.307 ms
9 vlan51.ebr1.Denver1.Level3.net (4.69.147.94) 35.666 ms 36.134 ms 35.172 ms
10 ae-2-2.ebr2.Dallas1.Level3.net (4.69.132.106) 48.745 ms 49.005 ms 48.986 ms
11 ae-92-92.csw4.Dallas1.Level3.net (4.69.151.165) 47.844 ms 46.955 ms 46.828 ms
12 ae-41-90.car1.Dallas1.Level3.net (4.69.145.195) 74.307 ms 73.806 ms 73.662 ms
13 vnsc-bak.sys.gtei.net (4.2.2.2) 45.573 ms 44.733 ms 41.836 ms
[root@CentosBox ~]#
So that was the fix. There are a couple of other commands I added to make traceroute through the ASA seem more normal…
Allows the ASA to show as a hop and decrement the TTL
policy-map global_policy
class class-default
set connection decrement-ttl
Allows the ASA to respond with traceroute statistics when it’s on its hop.
icmp unreachable rate-limit 10 burst-size 5
Interesting! Good to know…