On many of the firewalls that I administer, the machine fails to respond to a traceroute. The traceroute would get the entire way to the host, and then fail to respond when it hit the host. I have messed with this on and off for a while, and finally came up with the problem and a solution.
First, I tried to make sure that the firewall was open to receive ICMP packets. I use these command to permit a few specific ICMP types:
## Accept ICMP Echo-Reply, Echo-Request, and Time-Exceeded packets
iptables -A INPUT -s 0/0 -d 0/0 -p icmp –icmp-type 0 -j ACCEPT
iptables -A INPUT -s 0/0 -d 0/0 -p icmp –icmp-type 8 -j ACCEPT
iptables -A INPUT -s 0/0 -d 0/0 -p icmp –icmp-type 11 -j ACCEPT
However, just enabling those didn’t allow traceroutes to work correctly. There is also an ICMP type 30 for traceroute, but enabling that never got it working for me
So, I had to dig a little deeper into how traceroute works. What it does, is send a UDP packet to a port that it doesn’t expect to be open. The host then should send an ICMP ‘Unreachable’ packet back to the originating machine.
Turns out that the firewall rules that I was using blocked all incoming UDP requests (unless they were specifically allowed). This made it so that the machine never received the UDP request because the firewall blocked it.
Most traceroute implementations start sending requests on UDP port 33441, and then increment the port number sequentially for each one that it sends out. So I added this firewall rule to allow these packets through:
## Allow traceroutes, which send a packet to a UDP port in this general range
iptables -A INPUT -s 0/0 -p udp –destination-port 33441:33500 -j ACCEPT
Now those UDP packets get accepted and the machine properly replies with the ICMP packet like it should.