Linux – iptables will match the following ICMP request packet as ESTABLISHED state after the first reply packet is sent

iptableslinux

Test environment: CentOS 6.3 – kernel 2.6.32-279.el6.i686, iptables v1.4.7 Win7 ⇔ CentOS
Windows is constantly replaying ICMP echo request in 10pkt/sec rate to CentOS.

In iptables, I added the rules as below to limit the incoming icmp request packet rate. But it didn't work. Because after the 1st incoming icmp request was accepted by the 1st rule and my host replied, all the following icmp request will accepted by the 2nd rule, which will accept the incoming icmp request as ESTABLISHED state packet. I think this doesn't make sense.

enter image description here

I checked the "Iptables Tutorial 1.2.2" and I found the statement as below:

Iptables Tutorial ► The state machine

The reply packet is considered as being ESTABLISHED, as we have already explained. However, we can know for sure that after the ICMP reply, there will be absolutely no more legal traffic in the same connection. For this reason, the connection tracking entry is destroyed once the reply has traveled all the way through the Netfilter structure.
In each of the above cases, the request is considered as NEW, while the reply is considered as ESTABLISHED.

However, I found the conntrack entry was always there in /proc/net/nf_conntrack after the 1st reply was sent.

ipv4     2 icmp     1 24 src=192.168.56.1 dst=192.168.56.101 type=8 code=0 id=1 src=192.168.56.101 dst=192.168.56.1 type=0 code=0 id=1 mark=0 secmark=0 use=2

I think each incoming ICMP request should be treated as NEW state not ESTABLISHED even a icmp connection has been establised.

Correct me if I don't understand the state match in a proper way.

Best Answer

As you suggest, connection tracking obviously records your ICMP "session" and thus it considers the packets to be in ESTABLISHED state once a ping-pong roundtrip has been executed.

To achieve your goal of throttling ICMP requests you move the "drop all other ICMP" rule (third rule in your screenshot) just below the rule that accepts echo requests with rate limiting. This way the ESTABLISHED rule will not get considered for ICMP packets.

However since ICMP packets are also used to communicate various problems, I strongly recommend you add a rule accepting all icmp packets with a type other than "echo-request" to make sure you don't get problems with for example TCP connections (as an example, "Connection refused" is communicated using ICMP). The rule I suggest is:

iptables -A INPUT -p icmp ! --icmp-type echo-request -j ACCEPT

and put it right below your rate limiting rule accepting ECHO requests and just above the "drop all other ICMP" rule.

Related Question