Why You Shouldn’t Block ICMP: Security Risks and Best Practices for Linux iptables Configuration


2 views

ICMP (Internet Control Message Protocol) is often misunderstood as just "ping" traffic, but it serves several vital functions in IP networks. While your current iptables configuration accepts all ICMP traffic (iptables -A INPUT -p icmp -j ACCEPT), there are better ways to handle it than either completely blocking or completely allowing.

Complete ICMP blocking can cause:

  • Path MTU discovery failures (causing fragmentation and performance issues)
  • Troubleshooting becomes nearly impossible
  • Potential TCP connection problems (ICMP Destination Unreachable messages help TCP adjust)
  • Network monitoring tools lose visibility

Here's an improved version of your ruleset with more granular ICMP control:

# Essential ICMP types to allow
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

# Rate limit other ICMP to prevent floods
iptables -A INPUT -p icmp -m limit --limit 1/second --limit-burst 10 -j ACCEPT
iptables -A INPUT -p icmp -j DROP

For your VPS web hosting scenario, pay special attention to:

# Prevent ICMP redirect attacks
iptables -A INPUT -p icmp --icmp-type redirect -j DROP

# Block ICMP timestamp requests
iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP

# Block ICMP address mask requests
iptables -A INPUT -p icmp --icmp-type address-mask-request -j DROP

After applying these rules, verify functionality with:

# Test basic ping (should work with rate limiting)
ping yourserver.com

# Test path MTU discovery (should work)
ping -M do -s 1500 yourserver.com

# Check for unwanted ICMP types being blocked
nmap -Pn -sI --packet-trace -p T:80 yourserver.com

For better monitoring, add logging rules before your drop rules:

iptables -A INPUT -p icmp -m limit --limit 5/minute -j LOG --log-prefix "ICMP DROP: "
iptables -A INPUT -p icmp -j DROP

Then monitor your logs with:

tail -f /var/log/messages | grep "ICMP DROP"

While ICMP (Internet Control Message Protocol) might seem like a low-priority protocol to block for security purposes, completely disabling it can cause significant operational issues. ICMP serves several essential functions:

  • Path MTU discovery (PMTUD) - critical for proper TCP packet fragmentation
  • Network diagnostics (ping, traceroute)
  • Error reporting for unreachable hosts/ports
  • Quality of service monitoring

When you completely block ICMP, you're essentially blindfolding your server's ability to communicate network problems efficiently.

Here's what actually happens when ICMP is completely blocked:

# Example of problematic PMTUD scenario without ICMP:
1. Client sends 1500-byte packet to server
2. Intermediate router with 1400 MTU needs to fragment but can't send "Packet Too Big" message
3. Packet gets silently dropped
4. Connection hangs or becomes extremely slow

Instead of blanket blocking, implement selective ICMP filtering. Here's an improved version of your ruleset:

# Essential ICMP types to allow (numbered by type/code)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -m limit --limit 1/second -j ACCEPT
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

# Block all other ICMP traffic with logging
iptables -A INPUT -p icmp -j LOG --log-prefix "ICMP DROP: "
iptables -A INPUT -p icmp -j DROP

For additional protection against ICMP flood attacks, consider these refined rate-limiting rules:

# Create dedicated ICMP chain
iptables -N ICMP_RATE_LIMIT

# Allow critical ICMP with strict limits
iptables -A ICMP_RATE_LIMIT -m limit --limit 10/minute --limit-burst 30 -j RETURN
iptables -A ICMP_RATE_LIMIT -j LOG --log-prefix "ICMP Flood: "
iptables -A ICMP_RATE_LIMIT -j DROP

# Apply rate limiting to ICMP echo
iptables -A INPUT -p icmp --icmp-type echo-request -j ICMP_RATE_LIMIT

Implement comprehensive logging for suspicious ICMP activity:

# Log unusual ICMP types
iptables -A INPUT -p icmp --icmp-type ! echo-request \
    --icmp-type ! echo-reply \
    --icmp-type ! destination-unreachable \
    --icmp-type ! time-exceeded \
    --icmp-type ! parameter-problem \
    -j LOG --log-prefix "Suspicious ICMP: "

# Create logrotate configuration for iptables logs
cat > /etc/logrotate.d/iptables < /dev/null 2> /dev/null || true
    endscript
}
EOF

If your server supports IPv6, remember that ICMPv6 is even more critical than its IPv4 counterpart:

# Essential IPv6 ICMP rules
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbour-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbour-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -j ACCEPT
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT