On Fri, 25 Oct 2024, at 4:19 PM, Francisco Agostinho wrote: > Hello, I'm trying to implement a rate limiting for my machine using > iptables. The use case is to do 2 things: > > 1) block traffic from the same ip+port combination for 15 minutes if > it gets more than 10 hits per minute. > > 2) block traffic from the same ip for 30 minutes if it gets more than > 80 hits per minute. > > For this I'm currently using these rules: > > 1) -A PREROUTING -p tcp -m tcp -m state --state NEW -m hashlimit > --hashlimit-above 10/minute --hashlimit-burst 10 --hashlimit-mode > srcip,dstport --hashlimit-name test10 --hashlimit-htable-expire 900000 > -j ACCEPT > > 2) -A PREROUTING -p tcp -m tcp -m state --state NEW -m hashlimit > --hashlimit-above 80/minute --hashlimit-burst 80 --hashlimit-mode > srcip --hashlimit-name test80 --hashlimit-htable-expire 1800000 -j > ACCEPT Why is --hashlimit-above being combined with a verdict of ACCEPT? > > But it's not quite working, as soon as it gets on the list, if you get > another hit the timer gets reset to the default expire time and it > gets blocked on the first try even if after the expire. So are there > any suggestions on how to achieve the use case or what i'm doing > wrong? I would suggest disentangling all three of the following concerns: - determining whether a rate limit has been exceeded - adding to a set of banned addresses (with attached timeout values) - consulting the set to determine whether a given address has been banned To that end, consider taking advantage of ipsets. Below is a sample ruleset in iptables-save format. *raw :PREROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :limitban - [0:0] -A PREROUTING ! -i lo -p tcp -m conntrack --ctstate NEW -j limitban -A limitban -m set --match-set banned src -j DROP -A limitban -m hashlimit --hashlimit-above 10/min --hashlimit-mode srcip --hashlimit-name test10 -j SET --add-set banned src --timeout 900 -A limitban -m hashlimit --hashlimit-above 80/min --hashlimit-mode srcip --hashlimit-name test80 -j SET --add-set banned src -A limitban -m set --match-set banned src -j DROP COMMIT For this ruleset to be loadable, you'll first need to create the ipset that it references. # ipset create banned hash:ip timeout 1800 -- Kerin Millar