Iptables rules to block/allow icmp ping request in Linux

In this article I will show you different ways to block or allow incoming and outgoing icmp ping request in your Linux server.

Block ICMP ping request from all the servers in my network 192.168.1.0/24 towards my localhost 192.168.1.6

[root@test1 ~]# iptables -I INPUT -s 192.168.1.0/24 -p icmp -j DROP

Try to ping from any other machine of same network

[root@test ~]# ping 192.168.1.6
PING 192.168.1.6 (192.168.1.6) 56(84) bytes of data.
^C
--- 192.168.1.6 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2949ms

In the above test 3 packets were transmitted but none of them were received. As you can see below 3 packets were blocked by the INPUT chain in our localhost

[root@test1 ~]# iptables -L -v
Chain INPUT (policy ACCEPT 28 packets, 2004 bytes)
 pkts bytes target     prot opt in     out     source               destination
    3   252 DROP       icmp --  any    any     192.168.1.0/24       anywhere

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 18 packets, 1688 bytes)
 pkts bytes target     prot opt in     out     source               destination

Block ALL the outgoing ping request

[root@test1 ~]# iptables -I OUTPUT -d 192.168.1.0/24 -p icmp -j DROP
[root@test1 ~]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
ping: sendmsg: Operation not permitted
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2183ms

As you see above 3 packets made an attempt to send an icmp request to 192.168.1.0/24 but as it says "operation not permitted"

[root@test1 ~]# iptables -v -L
Chain INPUT (policy ACCEPT 38 packets, 2548 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 25 packets, 2688 bytes)
 pkts bytes target     prot opt in     out     source               destination
    3   252 DROP       icmp --  any    any     anywhere             192.168.1.0/24

You can also use extra arguments for icmp request types
1. echo-request (ping)
2. echo-reply (pong)

When you are trying to ping a server, basically you are sending a echo-request to that server and that server once receives the request, it will reply with echo-reply.

Block all outgoing echo-reply for echo-request coming from 192.168.1.0/24 using OUTPUT chain

# iptables -I OUTPUT -s 192.168.1.0/24 -p icmp --icmp-type echo-reply -j DROP

Now try to ping from any of the machine of same network

[root@test ~]# ping 192.168.1.6
PING 192.168.1.6 (192.168.1.6) 56(84) bytes of data.
^C
--- 192.168.1.6 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2521ms

As you can see 3 packets were blocked in the OUTPUT chain

[root@test1 ~]# iptables -L -v
Chain INPUT (policy ACCEPT 26 packets, 1952 bytes)
 pkts bytes target     prot opt in     out     source    destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source    destination

Chain OUTPUT (policy ACCEPT 16 packets, 1504 bytes)
 pkts bytes target   prot opt in   out  source           destination
    3   252 DROP     icmp --  any  any  192.168.1.0/24   anywhere   icmp echo-reply

Block all ICMP incoming traffic for ESTABLISHED connection only

# iptables -I INPUT -s 192.168.1.0/24 -p icmp -m state --state ESTABLISHED -j DROP

Try to ping from any other machine of same network

[root@test ~]# ping 192.168.1.6
PING 192.168.1.6 (192.168.1.6) 56(84) bytes of data.
64 bytes from 192.168.1.6: icmp_seq=1 ttl=64 time=2.00 ms
^C
--- 192.168.1.6 ping statistics ---
4 packets transmitted, 1 received, 75% packet loss, time 3092ms

Do you see something unusual above?

The first packet was sent properly which means node 1 sent with SYN signal which was accepted by node 2 with SYN/ACK signal and sent ACK signal back to node 1 (TCP 3 way handshake). So once the connection was established no further icmp request was allowed as you see out of 4 packets 1 was transmitted successfully and 3 were dropped.

[root@test1 ~]# iptables -L -v
Chain INPUT (policy ACCEPT 28 packets, 2121 bytes)
 pkts bytes target     prot opt in     out     source               destination
    3   252 DROP       icmp --  any    any     192.168.1.0/24       anywhere            state ESTABLISHED

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 18 packets, 1620 bytes)
 pkts bytes target     prot opt in     out     source               destination

You can do the same for other state condition as well

# iptables -I INPUT -s 192.168.1.0/24 -p icmp -m state --state NEW,ESTABLISHED,RELATED -j DROP

State
Description
NEW
meaning that the packet has started a new connection, or otherwise  associated with a connection which has not seen packets in both directions
ESTABLISHED
meaning that the packet is associated with a connection which has seen packets in both directions
RELATED
meaning that the packet is starting a new connection, but is  associated  with an existing connection, such as an FTP data transfer, or an ICMP error

So I hope I made my self clear. Please let me know your success and failures

Related Articles
Iptables rules to allow/block ssh incoming/outgoing connection in Linux
iptables rules for Samba 4 in Red Hat Linux
Basic iptables tutorial in Linux I
Basic iptables tutorial in Linux II
Iptables for Samba server