Rate limiting ICMP flood with nftables
I'm trying to figure out how to allow ICMP pings to a server with nftables without being subject to flood attacks.
Here's my initial config:
table inet firewall {
chain incoming {
type filter hook input priority 0; policy drop;
# established/related connections
ct state { established, related } accept
# ICMP
ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept
# ICMP ping dealt with separately to rate limit
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 1/second accept
ip protocol icmp icmp type echo-request limit rate 1/second accept
}
}
However, flooding with ping -f [IP_ADDRESS]
shows most packets getting through. Certainly more than one per second.
If I remove the ct state { established, related } accept
rule I get 99% packet loss when trying to flood.
So it seems like the first request establishes a connection and subsequent pings ride in on that rule and it doesn't seem to matter if I put the ct
rule after the icmp
rule.
Any way to allow established connections but still rate limit pings?
Solution 1:
Try this solution:
table inet firewall { chain incoming { type filter hook input priority 0; policy drop; # ICMP ping dealt with separately to rate limit ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 1/second accept ip6 nexthdr icmpv6 icmpv6 type echo-request counter drop ip protocol icmp icmp type echo-request limit rate 1/second accept ip protocol icmp icmp type echo-request counter drop # established/related connections ct state { established, related } accept # ICMP ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-reply, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept ip protocol icmp icmp type { destination-unreachable, router-advertisement, time-exceeded, parameter-problem } accept } }
You should explicitly drop the packets, those exceeded ratelimit, to prevent accept they by rules below.