Blocking ICMP with iptables

The conventional wisdom that you may have heard for most of your career is that we need to block all the packets from the Internet Control Message Protocol (ICMP). The idea you may have been told is to make your server invisible to hackers by blocking ping packets. Of course, there are some vulnerabilities that are associated with ICMP, such as the following:

  • By using a botnet, a hacker could inundate your server with ping packets from multiple sources at once, exhausting your server's ability to cope. 
  • Certain vulnerabilities that are associated with the ICMP protocol can allow a hacker to either gain administrative privileges on your system, redirect your traffic to a malicious server, or crash your operating system.
  • By using some simple hacking tools, someone could embed sensitive data in the data field of an ICMP packet in order to secretly exfiltrate it from your organization.

However, while blocking certain types of ICMP packets is good, blocking all ICMP packets is bad. The harsh reality is that certain types of ICMP messages are necessary for the proper functionality of the network. Since the drop all that's not allowed rule that we'll eventually create also blocks ICMP packets, we'll need to create some rules that allow the types of ICMP messages that we have to have. So, here goes:

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 3 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 11 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

sudo iptables -A INPUT -m conntrack -p icmp --icmp-type 12 --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT

Here's the breakdown:

  • -m conntrack: As before, we're using the conntrack module to allow packets that are in a certain state. This time, though, instead of just allowing packets from a host that our server has connected to (ESTABLISHED,RELATED), we're also allowing NEW packets that other hosts are sending to our server.
  • -p icmp: This refers to the ICMP protocol.
  • --icmp-type: There are quite a few types of ICMP messages, which we'll outline next.

The three types of ICMP messages that we want to allow are as follows:

  • type 3: These are the destination unreachable messages. Not only can they tell your server that it can't reach a certain host, but they can also tell it why. For example, if the server has sent out a packet that's too large for a network switch to handle, the switch will send back an ICMP message that tells the server to fragment that large packet. Without ICMP, the server would have connectivity problems every time it tries to send out a large packet that needs to be broken up into fragments.
  • type 11: Time exceeded messages let your server know that a packet that it has sent out has either exceeded its Time-to-Live (TTL) value before it could reach its destination, or that a fragmented packet couldn't be reassembled before the TTL expiration date.
  • type 12: Parameter problem messages indicate that the server had sent a packet with a bad IP header. In other words, the IP header is either missing an option flag, or it's of an invalid length.

Three common message types are conspicuously absent from our list:

  • type 0 and type 8: These are the infamous ping packets. Actually, type 8 is the echo request packet that you would send out to ping a host, while type 0 is the echo reply that the host would return to let you know that it's alive. Of course, allowing ping packets to get through could be a big help with troubleshooting network problems. If that scenario ever comes up, you could just add a couple of iptables rules to temporarily allow pings.
  • type 5: Now, we have the infamous redirect messages. Allowing these could be handy if you have a router that can suggest more efficient paths for the server to use, but hackers can also use them to redirect you to someplace that you don't want to go. So, just block them.

There are lots more ICMP message types than I've shown here, but these are the only ones that we need to worry about for now.

When we use sudo iptables -L, we'll see our new ruleset, as things currently stand:

Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere tcp dpt:domain
ACCEPT udp -- anywhere anywhere udp dpt:domain
ACCEPT icmp -- anywhere anywhere ctstate NEW,RELATED,ESTABLISHED icmp destination-unreachable
ACCEPT icmp -- anywhere anywhere ctstate NEW,RELATED,ESTABLISHED icmp source-quench
ACCEPT icmp -- anywhere anywhere ctstate NEW,RELATED,ESTABLISHED icmp time-exceeded
ACCEPT icmp -- anywhere anywhere ctstate NEW,RELATED,ESTABLISHED icmp parameter-problem
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Looks good, eh? Well, not really. We haven't blocked anything with this ruleset yet. So, let's take care of that.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.118.95