All of lore.kernel.org
 help / color / mirror / Atom feed
* nftables rate limiting per multiple seconds
@ 2024-03-06 22:11 Sreedhar M
  2024-03-06 22:39 ` Kerin Millar
  0 siblings, 1 reply; 14+ messages in thread
From: Sreedhar M @ 2024-03-06 22:11 UTC (permalink / raw)
  To: netfilter

Hello Team

I am currently working on configuring rate limiting rules with nft and
have encountered a challenge. ex: I would appreciate your guidance in
achieving a rate limit of 10 ICMP echo-request packets within a
10-second interval.

Here is an example rule
example : nft add rule filter input icmp type echo-request limit rate
over 10/second drop

I understand that nft doesn't directly support specifying rates in the
format "10/10 seconds," and I'm seeking advice on how to adjust the
parameters to achieve the desired rate limiting behaviour.

Your assistance on this matter would be greatly appreciated.

Thank you for your time and support.

Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-06 22:11 nftables rate limiting per multiple seconds Sreedhar M
@ 2024-03-06 22:39 ` Kerin Millar
  2024-03-07 10:08   ` Sreedhar M
  0 siblings, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-06 22:39 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Wed, 6 Mar 2024 22:11:49 +0000
Sreedhar M <sreemtech@gmail.com> wrote:

> Hello Team
> 
> I am currently working on configuring rate limiting rules with nft and
> have encountered a challenge. ex: I would appreciate your guidance in
> achieving a rate limit of 10 ICMP echo-request packets within a
> 10-second interval.
> 
> Here is an example rule
> example : nft add rule filter input icmp type echo-request limit rate
> over 10/second drop
> 
> I understand that nft doesn't directly support specifying rates in the
> format "10/10 seconds," and I'm seeking advice on how to adjust the
> parameters to achieve the desired rate limiting behaviour.
> 
> Your assistance on this matter would be greatly appreciated.

"1/second burst 10 packets" should be close enough. The bucket will be initialised with 10 tokens and refilled at a rate of 1 per second.

-- 
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-06 22:39 ` Kerin Millar
@ 2024-03-07 10:08   ` Sreedhar M
  2024-03-07 12:30     ` Kerin Millar
  0 siblings, 1 reply; 14+ messages in thread
From: Sreedhar M @ 2024-03-07 10:08 UTC (permalink / raw)
  To: kfm; +Cc: netfilter

This is really inconvenient that we cant rate limit the packets for
multiple seconds , we have only the close enough but not 100% right in
edge cases.
"1/second burst 10 packets" should be close enough. The bucket will be
initialised with 10 tokens and refilled at a rate of 1 per second.

I really cant have an alternative for below please
iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
-m recent --update --seconds 10 --hitcount 15 -j DROP
nft # -A rms0 -p tcp --dport 8000 -m state --state NEW -m recent
--update --seconds 10 --hitcount 15 -j DROP

Thanks
Sreedhar

On Wed, Mar 6, 2024 at 10:39 PM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Wed, 6 Mar 2024 22:11:49 +0000
> Sreedhar M <sreemtech@gmail.com> wrote:
>
> > Hello Team
> >
> > I am currently working on configuring rate limiting rules with nft and
> > have encountered a challenge. ex: I would appreciate your guidance in
> > achieving a rate limit of 10 ICMP echo-request packets within a
> > 10-second interval.
> >
> > Here is an example rule
> > example : nft add rule filter input icmp type echo-request limit rate
> > over 10/second drop
> >
> > I understand that nft doesn't directly support specifying rates in the
> > format "10/10 seconds," and I'm seeking advice on how to adjust the
> > parameters to achieve the desired rate limiting behaviour.
> >
> > Your assistance on this matter would be greatly appreciated.
>
> "1/second burst 10 packets" should be close enough. The bucket will be initialised with 10 tokens and refilled at a rate of 1 per second.
>
> --
> Kerin Millar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-07 10:08   ` Sreedhar M
@ 2024-03-07 12:30     ` Kerin Millar
  2024-03-07 17:10       ` Sreedhar M
  0 siblings, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-07 12:30 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Thu, 7 Mar 2024, at 10:08 AM, Sreedhar M wrote:
> This is really inconvenient that we cant rate limit the packets for
> multiple seconds , we have only the close enough but not 100% right in
> edge cases.
> "1/second burst 10 packets" should be close enough. The bucket will be
> initialised with 10 tokens and refilled at a rate of 1 per second.

I understand that it it is not precisely what you are asking for and am definitely not opposed to the idea of supporting more flexible intervals. At the same time, I don't see what renders the suggested rule so very inconvenient. Should the bucket be drained through flooding, it will achieve the overall aim of allowing for no more than 10 packets to pass over 10 seconds.

Regardless, it is possible to implement more powerful rate limiting schemes through the use of dynamic sets, as should become clear momentarily.

>
> I really cant have an alternative for below please
> iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
> -m recent --update --seconds 10 --hitcount 15 -j DROP
> nft # -A rms0 -p tcp --dport 8000 -m state --state NEW -m recent
> --update --seconds 10 --hitcount 15 -j DROP

Since this is a different problem to the one that you initially described, it would be premature to infer that you can't have an alternative. Fortunately, you can. Below is a small ruleset, demonstrating how it can be implemented.

table ip filter {
    set ratelimit {
        type ipv4_addr . inet_service
        flags timeout
    }

    chain INPUT {
        type filter hook input priority filter; policy accept;
        tcp dport 8000 ct state new update @ratelimit { ip saddr . th dport timeout 10s limit rate over 1/hour burst 15 packets } drop
    }
}

It works by creating a dynamic, named set and leveraging the ability of ntables to update sets from the packet path. Each time the rule is matched, it adds or updates the set with an element consisting of both the source address and destination port. Newly added elements bear the given rate limiting policy, along with a timeout of 10 seconds, thereby matching your --seconds parameter. The capacity of the bucket is set to 15 tokens, thereby matching your --hitcount parameter. The buckets of elements that continue to survive the timeout will be credited with a single token every hour - a deliberately long interval (you may lengthen it further if you wish).

I would suggest taking a look at the SET STATEMENT section of the nft(8) man page:

LESS+='+/SET STATEMENT' man nft

There is also some information in the wiki:

https://wiki.nftables.org/wiki-nftables/index.php/Meters

--
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-07 12:30     ` Kerin Millar
@ 2024-03-07 17:10       ` Sreedhar M
  2024-03-07 23:11         ` Sreedhar M
  2024-03-08  2:03         ` Kerin Millar
  0 siblings, 2 replies; 14+ messages in thread
From: Sreedhar M @ 2024-03-07 17:10 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Thanks Kerin for the Info.

The workaround is not fulfilling . The use case for me is multiple
seconds combination.
I Wanted to keep new connections, at given every 10 seconds period I
don't won't to allow more than 15 connections

Let me explain , as I Wanted to accept new connections, at given every
10 seconds period I don't won't to allow more than 15 connections .

With the below rule, ex: say on a src client  If I run 15 connections
in one second because of 15 packets burst the rule will accept, from
2nd second onwards it accepts 1 each second until it reaches 10
seconds. basically the rule shouldn't accept any more until it reaches
10 seconds. this the problem with all two work around I said earlier.

The goal is at given every 10 seconds period I don't won't to allow
more than 15 connections. With burst say If accept 15 connections at
1st second, then the next connection shall be accepted only at 16th
second. This is where I am struck please.


table ip filter {
    set ratelimit {
         type ipv4_addr
         flags dynamic
         timeout 15s
    }

chain INPUT {
        type filter hook input priority filter; policy accept;
        tcp dport 8000 ct state new update @ratelimit { ip saddr limit
rate over 1/second burst 15 packets} drop
}

Thanks
Sreedhar

On Thu, Mar 7, 2024 at 12:30 PM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Thu, 7 Mar 2024, at 10:08 AM, Sreedhar M wrote:
> > This is really inconvenient that we cant rate limit the packets for
> > multiple seconds , we have only the close enough but not 100% right in
> > edge cases.
> > "1/second burst 10 packets" should be close enough. The bucket will be
> > initialised with 10 tokens and refilled at a rate of 1 per second.
>
> I understand that it it is not precisely what you are asking for and am definitely not opposed to the idea of supporting more flexible intervals. At the same time, I don't see what renders the suggested rule so very inconvenient. Should the bucket be drained through flooding, it will achieve the overall aim of allowing for no more than 10 packets to pass over 10 seconds.
>
> Regardless, it is possible to implement more powerful rate limiting schemes through the use of dynamic sets, as should become clear momentarily.
>
> >
> > I really cant have an alternative for below please
> > iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
> > -m recent --update --seconds 10 --hitcount 15 -j DROP
> > nft # -A rms0 -p tcp --dport 8000 -m state --state NEW -m recent
> > --update --seconds 10 --hitcount 15 -j DROP
>
> Since this is a different problem to the one that you initially described, it would be premature to infer that you can't have an alternative. Fortunately, you can. Below is a small ruleset, demonstrating how it can be implemented.
>
> table ip filter {
>     set ratelimit {
>         type ipv4_addr . inet_service
>         flags timeout
>     }
>
>     chain INPUT {
>         type filter hook input priority filter; policy accept;
>         tcp dport 8000 ct state new update @ratelimit { ip saddr . th dport timeout 10s limit rate over 1/hour burst 15 packets } drop
>     }
> }
>
> It works by creating a dynamic, named set and leveraging the ability of ntables to update sets from the packet path. Each time the rule is matched, it adds or updates the set with an element consisting of both the source address and destination port. Newly added elements bear the given rate limiting policy, along with a timeout of 10 seconds, thereby matching your --seconds parameter. The capacity of the bucket is set to 15 tokens, thereby matching your --hitcount parameter. The buckets of elements that continue to survive the timeout will be credited with a single token every hour - a deliberately long interval (you may lengthen it further if you wish).
>
> I would suggest taking a look at the SET STATEMENT section of the nft(8) man page:
>
> LESS+='+/SET STATEMENT' man nft
>
> There is also some information in the wiki:
>
> https://wiki.nftables.org/wiki-nftables/index.php/Meters
>
> --
> Kerin Millar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-07 17:10       ` Sreedhar M
@ 2024-03-07 23:11         ` Sreedhar M
  2024-03-08  2:03         ` Kerin Millar
  1 sibling, 0 replies; 14+ messages in thread
From: Sreedhar M @ 2024-03-07 23:11 UTC (permalink / raw)
  To: Kerin Millar, netfilter

I have also tested another use case

Iptables version :  say if user connects 1 per second. ip table allows
continuously - this is perfect
iptables -A INPUT -p tcp --dport 7880 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 7880 -m state --state NEW -m recent
--update --seconds 10 --hitcount 15 -j DROP

but the below never satisfy the above condition : means if user sends
1 per second once it reaches 15 seconds , it waits for 15 seconds and
then accepts 1 per second after 15 seconds

table ip filter {
    set ratelimit {
         type ipv4_addr
         flags dynamic
         timeout 15s
    }

chain INPUT {
        type filter hook input priority filter; policy accept;
        tcp dport 8000 ct state new update @ratelimit { ip saddr limit
rate over 1/day burst 15 packets} drop
}

On Thu, Mar 7, 2024 at 5:10 PM Sreedhar M <sreemtech@gmail.com> wrote:
>
> Thanks Kerin for the Info.
>
> The workaround is not fulfilling . The use case for me is multiple
> seconds combination.
> I Wanted to keep new connections, at given every 10 seconds period I
> don't won't to allow more than 15 connections
>
> Let me explain , as I Wanted to accept new connections, at given every
> 10 seconds period I don't won't to allow more than 15 connections .
>
> With the below rule, ex: say on a src client  If I run 15 connections
> in one second because of 15 packets burst the rule will accept, from
> 2nd second onwards it accepts 1 each second until it reaches 10
> seconds. basically the rule shouldn't accept any more until it reaches
> 10 seconds. this the problem with all two work around I said earlier.
>
> The goal is at given every 10 seconds period I don't won't to allow
> more than 15 connections. With burst say If accept 15 connections at
> 1st second, then the next connection shall be accepted only at 16th
> second. This is where I am struck please.
>
>
> table ip filter {
>     set ratelimit {
>          type ipv4_addr
>          flags dynamic
>          timeout 15s
>     }
>
> chain INPUT {
>         type filter hook input priority filter; policy accept;
>         tcp dport 8000 ct state new update @ratelimit { ip saddr limit
> rate over 1/second burst 15 packets} drop
> }
>
> Thanks
> Sreedhar
>
> On Thu, Mar 7, 2024 at 12:30 PM Kerin Millar <kfm@plushkava.net> wrote:
> >
> > On Thu, 7 Mar 2024, at 10:08 AM, Sreedhar M wrote:
> > > This is really inconvenient that we cant rate limit the packets for
> > > multiple seconds , we have only the close enough but not 100% right in
> > > edge cases.
> > > "1/second burst 10 packets" should be close enough. The bucket will be
> > > initialised with 10 tokens and refilled at a rate of 1 per second.
> >
> > I understand that it it is not precisely what you are asking for and am definitely not opposed to the idea of supporting more flexible intervals. At the same time, I don't see what renders the suggested rule so very inconvenient. Should the bucket be drained through flooding, it will achieve the overall aim of allowing for no more than 10 packets to pass over 10 seconds.
> >
> > Regardless, it is possible to implement more powerful rate limiting schemes through the use of dynamic sets, as should become clear momentarily.
> >
> > >
> > > I really cant have an alternative for below please
> > > iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
> > > -m recent --update --seconds 10 --hitcount 15 -j DROP
> > > nft # -A rms0 -p tcp --dport 8000 -m state --state NEW -m recent
> > > --update --seconds 10 --hitcount 15 -j DROP
> >
> > Since this is a different problem to the one that you initially described, it would be premature to infer that you can't have an alternative. Fortunately, you can. Below is a small ruleset, demonstrating how it can be implemented.
> >
> > table ip filter {
> >     set ratelimit {
> >         type ipv4_addr . inet_service
> >         flags timeout
> >     }
> >
> >     chain INPUT {
> >         type filter hook input priority filter; policy accept;
> >         tcp dport 8000 ct state new update @ratelimit { ip saddr . th dport timeout 10s limit rate over 1/hour burst 15 packets } drop
> >     }
> > }
> >
> > It works by creating a dynamic, named set and leveraging the ability of ntables to update sets from the packet path. Each time the rule is matched, it adds or updates the set with an element consisting of both the source address and destination port. Newly added elements bear the given rate limiting policy, along with a timeout of 10 seconds, thereby matching your --seconds parameter. The capacity of the bucket is set to 15 tokens, thereby matching your --hitcount parameter. The buckets of elements that continue to survive the timeout will be credited with a single token every hour - a deliberately long interval (you may lengthen it further if you wish).
> >
> > I would suggest taking a look at the SET STATEMENT section of the nft(8) man page:
> >
> > LESS+='+/SET STATEMENT' man nft
> >
> > There is also some information in the wiki:
> >
> > https://wiki.nftables.org/wiki-nftables/index.php/Meters
> >
> > --
> > Kerin Millar
>
>
>
> --
> Best Regards
> Sreedhar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-07 17:10       ` Sreedhar M
  2024-03-07 23:11         ` Sreedhar M
@ 2024-03-08  2:03         ` Kerin Millar
  2024-03-08  7:26           ` Sreedhar M
  1 sibling, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-08  2:03 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Thu, 7 Mar 2024, at 5:10 PM, Sreedhar M wrote:
> Thanks Kerin for the Info.
>
> The workaround is not fulfilling . The use case for me is multiple
> seconds combination.
> I Wanted to keep new connections, at given every 10 seconds period I
> don't won't to allow more than 15 connections
>
> Let me explain , as I Wanted to accept new connections, at given every
> 10 seconds period I don't won't to allow more than 15 connections .
>
> With the below rule, ex: say on a src client  If I run 15 connections
> in one second because of 15 packets burst the rule will accept, from
> 2nd second onwards it accepts 1 each second until it reaches 10

You have to set the interval long enough for the bucket refill rate to be immaterial (1/day is the longest possible interval). The example had it as 1/hour; I do not know why you reduced it to 1/second.

--
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08  2:03         ` Kerin Millar
@ 2024-03-08  7:26           ` Sreedhar M
  2024-03-08  8:07             ` Kerin Millar
  0 siblings, 1 reply; 14+ messages in thread
From: Sreedhar M @ 2024-03-08  7:26 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Hi Kerin,
Thanks again .

I have changed it for two reasons , because of the errors
nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
timeout ; }"
nft add rule ip filter INPUT tcp dport 8000 ct state new update
@myrate { ip saddr . th dport timeout 10s  limit rate over 1/day burst
15 packets } counter drop
Error: Could not process rule: Invalid argument
add rule ip filter INPUT tcp dport 8000 ct state new update @myrate {
ip saddr . th dport timeout 10s limit rate over 1/day burst 15 packets
} counter drop

After the above error I have changed it to below , In one use case -
the below never resets , Say If I send only one message per second all
the time , the below rule will stop at 10th second and the next
message will be accepted only after 10 seconds. This is not correct
when we are sending one 1 message per second it has to accept it ,
because we are not sending all the 15 messages in one second.

table ip filter {
    set ratelimit {
         type ipv4_addr
         flags dynamic
         timeout 10s
    }
chain INPUT {
        type filter hook input priority filter; policy accept;
        tcp dport 8000 ct state new update @ratelimit { ip saddr limit
rate over 1/day burst 15 packets} drop
}

Thanks
Sreedhar


On Fri, Mar 8, 2024 at 2:04 AM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Thu, 7 Mar 2024, at 5:10 PM, Sreedhar M wrote:
> > Thanks Kerin for the Info.
> >
> > The workaround is not fulfilling . The use case for me is multiple
> > seconds combination.
> > I Wanted to keep new connections, at given every 10 seconds period I
> > don't won't to allow more than 15 connections
> >
> > Let me explain , as I Wanted to accept new connections, at given every
> > 10 seconds period I don't won't to allow more than 15 connections .
> >
> > With the below rule, ex: say on a src client  If I run 15 connections
> > in one second because of 15 packets burst the rule will accept, from
> > 2nd second onwards it accepts 1 each second until it reaches 10
>
> You have to set the interval long enough for the bucket refill rate to be immaterial (1/day is the longest possible interval). The example had it as 1/hour; I do not know why you reduced it to 1/second.
>
> --
> Kerin Millar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08  7:26           ` Sreedhar M
@ 2024-03-08  8:07             ` Kerin Millar
  2024-03-08  9:12               ` Sreedhar M
  0 siblings, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-08  8:07 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Fri, 8 Mar 2024, at 7:26 AM, Sreedhar M wrote:
> Hi Kerin,
> Thanks again .
>
> I have changed it for two reasons , because of the errors
> nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> timeout ; }"
> nft add rule ip filter INPUT tcp dport 8000 ct state new update
> @myrate { ip saddr . th dport timeout 10s  limit rate over 1/day burst
> 15 packets } counter drop
> Error: Could not process rule: Invalid argument

Hmm. I would have to go over the release notes to be sure, but it may be that that it has not always been possible to incorporate a timeout as part of the rule. Should that be the case, defining the timeout as part of the set declaration - as you did - is acceptable.

> add rule ip filter INPUT tcp dport 8000 ct state new update @myrate {
> ip saddr . th dport timeout 10s limit rate over 1/day burst 15 packets
> } counter drop
>
> After the above error I have changed it to below , In one use case -
> the below never resets , Say If I send only one message per second all
> the time , the below rule will stop at 10th second and the next
> message will be accepted only after 10 seconds. This is not correct
> when we are sending one 1 message per second it has to accept it ,
> because we are not sending all the 15 messages in one second.

This should definitely not be the case. The bucket will have a capacity of 15 tokens and they must all be consumed before the drop verdict can be reached (the 16th attempt will be denied). Please review your testing methodology carefully and be sure to flush the set before you begin your testing procedure:

nft flush set ip filter ratelimit

Incidentally, it is worth worth noting that the "new" ctstate can be satisfied under conditions pertaining to all three of the following things:

- the content of the packet being considered
- the entries that already exist in the kernel's conntrack table
- the state of the kernel's "nf_conntrack_tcp_loose" sysctl

I consider it highly unlikely that those considerations would have affected your testing. Nevertheless, in the interest of certainty, you may find it useful to include "tcp flags syn" as a condition of your rule while you are testing.

--
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08  8:07             ` Kerin Millar
@ 2024-03-08  9:12               ` Sreedhar M
  2024-03-08  9:55                 ` Kerin Millar
  0 siblings, 1 reply; 14+ messages in thread
From: Sreedhar M @ 2024-03-08  9:12 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Hi Kerin,
Thanks for the mail.

I did the flush and clean-up in all my tests.

The main problem is with one of the below use case only other use cases works:
problem Use case : Say clients sends new connection request every 1
second , in this case the new connections must continue to be accepted
 even after 15 new connections in 15 seconds because in this use case
we are sending only one per second. this what expected, this use case
is not working when we use "update" rule. This use case works only
when we use "add" in the rule.

Add: The above use case works , when we use "add" in the rule
 nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
timeout ; flags dynamic; timeout 10s; }"
 nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate
{ ip saddr . th dport  limit rate over 1/day burst 15 packets }
counter drop

Update : The above use case won't work , when we use "update" in the rule.
 nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
timeout ; flags dynamic; timeout 10s; }"
 nft add rule ip filter INPUT tcp dport 7880 ct state new update
@myrate { ip saddr . th dport  limit rate over 1/day burst 15 packets
} counter drop

Use cases that works :
when we send 15 packets in 1 second, we wait for 10 seconds and the
next will be accepted at 11th second, this perfectly works with
update.

Use cases that do not work :
Assume we are going to 1 packet every 1 second for an hour , we should
continuously accept all the new connections as we are sending only one
per second this is not working when use "update" in the rule , but
works when use "add" in the rule.

Fyi, I have tested by adding this also - "tcp flags syn";

Please advise me shall I use "add" in all the cases , so it satisfy
all the above uses cases.?

Thanks
Sreedhar

On Fri, Mar 8, 2024 at 8:08 AM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Fri, 8 Mar 2024, at 7:26 AM, Sreedhar M wrote:
> > Hi Kerin,
> > Thanks again .
> >
> > I have changed it for two reasons , because of the errors
> > nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> > timeout ; }"
> > nft add rule ip filter INPUT tcp dport 8000 ct state new update
> > @myrate { ip saddr . th dport timeout 10s  limit rate over 1/day burst
> > 15 packets } counter drop
> > Error: Could not process rule: Invalid argument
>
> Hmm. I would have to go over the release notes to be sure, but it may be that that it has not always been possible to incorporate a timeout as part of the rule. Should that be the case, defining the timeout as part of the set declaration - as you did - is acceptable.
>
> > add rule ip filter INPUT tcp dport 8000 ct state new update @myrate {
> > ip saddr . th dport timeout 10s limit rate over 1/day burst 15 packets
> > } counter drop
> >
> > After the above error I have changed it to below , In one use case -
> > the below never resets , Say If I send only one message per second all
> > the time , the below rule will stop at 10th second and the next
> > message will be accepted only after 10 seconds. This is not correct
> > when we are sending one 1 message per second it has to accept it ,
> > because we are not sending all the 15 messages in one second.
>
> This should definitely not be the case. The bucket will have a capacity of 15 tokens and they must all be consumed before the drop verdict can be reached (the 16th attempt will be denied). Please review your testing methodology carefully and be sure to flush the set before you begin your testing procedure:
>
> nft flush set ip filter ratelimit
>
> Incidentally, it is worth worth noting that the "new" ctstate can be satisfied under conditions pertaining to all three of the following things:
>
> - the content of the packet being considered
> - the entries that already exist in the kernel's conntrack table
> - the state of the kernel's "nf_conntrack_tcp_loose" sysctl
>
> I consider it highly unlikely that those considerations would have affected your testing. Nevertheless, in the interest of certainty, you may find it useful to include "tcp flags syn" as a condition of your rule while you are testing.
>
> --
> Kerin Millar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08  9:12               ` Sreedhar M
@ 2024-03-08  9:55                 ` Kerin Millar
  2024-03-08 10:19                   ` Sreedhar M
  0 siblings, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-08  9:55 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Fri, 8 Mar 2024, at 9:12 AM, Sreedhar M wrote:
> Hi Kerin,
> Thanks for the mail.
>
> I did the flush and clean-up in all my tests.
>
> The main problem is with one of the below use case only other use cases works:
> problem Use case : Say clients sends new connection request every 1
> second , in this case the new connections must continue to be accepted
>  even after 15 new connections in 15 seconds because in this use case
> we are sending only one per second. this what expected, this use case
> is not working when we use "update" rule. This use case works only
> when we use "add" in the rule.

Indeed. That is because "add" does not cause the value of the timer to be reset to 10 seconds each time the rule is matched, potentially allowing for elements to persist for a long time after begin added (along with their token bucket states).

Consider the rule that you originally wanted translated:

iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
-m recent --update --seconds 10 --hitcount 15 -j DROP

There you specifed --update, which does have the effect of resetting the value of the timer. So it was that I proposed to use "update" in nftables, to precisely match its behaviour.

>
> Add: The above use case works , when we use "add" in the rule
>  nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> timeout ; flags dynamic; timeout 10s; }"
>  nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate
> { ip saddr . th dport  limit rate over 1/day burst 15 packets }
> counter drop
>
> Update : The above use case won't work , when we use "update" in the rule.
>  nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> timeout ; flags dynamic; timeout 10s; }"
>  nft add rule ip filter INPUT tcp dport 7880 ct state new update
> @myrate { ip saddr . th dport  limit rate over 1/day burst 15 packets
> } counter drop
>
> Use cases that works :
> when we send 15 packets in 1 second, we wait for 10 seconds and the
> next will be accepted at 11th second, this perfectly works with
> update.

Yes.

>
> Use cases that do not work :
> Assume we are going to 1 packet every 1 second for an hour , we should
> continuously accept all the new connections as we are sending only one
> per second this is not working when use "update" in the rule , but
> works when use "add" in the rule.

I see. You never wanted the behaviour of --update to begin with, despite implying otherwise.

>
> Fyi, I have tested by adding this also - "tcp flags syn";
>
> Please advise me shall I use "add" in all the cases , so it satisfy
> all the above uses cases.?

Yes. The effect will be that any element added to the set will be evicted after 10 seconds has elapsed, no matter how many more times the rule is matched during the intervening period.

--
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08  9:55                 ` Kerin Millar
@ 2024-03-08 10:19                   ` Sreedhar M
  2024-03-08 10:34                     ` Kerin Millar
  0 siblings, 1 reply; 14+ messages in thread
From: Sreedhar M @ 2024-03-08 10:19 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Great Kerin. Thank you so much for the support.

With the below rules specially using 'add' and all my uses cases are working.
nft add set ip filter myrate  { type ipv4_addr . inet_service; flags
timeout ; flags dynamic; timeout 10s; }
nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate {
ip saddr . th dport  limit rate over 1/day burst 15 packets } counter
drop

Thank you once again for your help

Best Regards
Sreedhar

On Fri, Mar 8, 2024 at 9:56 AM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Fri, 8 Mar 2024, at 9:12 AM, Sreedhar M wrote:
> > Hi Kerin,
> > Thanks for the mail.
> >
> > I did the flush and clean-up in all my tests.
> >
> > The main problem is with one of the below use case only other use cases works:
> > problem Use case : Say clients sends new connection request every 1
> > second , in this case the new connections must continue to be accepted
> >  even after 15 new connections in 15 seconds because in this use case
> > we are sending only one per second. this what expected, this use case
> > is not working when we use "update" rule. This use case works only
> > when we use "add" in the rule.
>
> Indeed. That is because "add" does not cause the value of the timer to be reset to 10 seconds each time the rule is matched, potentially allowing for elements to persist for a long time after begin added (along with their token bucket states).
>
> Consider the rule that you originally wanted translated:
>
> iptables-translate  -A rms0  -p tcp --dport 8000 -m state --state NEW
> -m recent --update --seconds 10 --hitcount 15 -j DROP
>
> There you specifed --update, which does have the effect of resetting the value of the timer. So it was that I proposed to use "update" in nftables, to precisely match its behaviour.
>
> >
> > Add: The above use case works , when we use "add" in the rule
> >  nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> > timeout ; flags dynamic; timeout 10s; }"
> >  nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate
> > { ip saddr . th dport  limit rate over 1/day burst 15 packets }
> > counter drop
> >
> > Update : The above use case won't work , when we use "update" in the rule.
> >  nft add set ip filter myrate  "{ type ipv4_addr . inet_service; flags
> > timeout ; flags dynamic; timeout 10s; }"
> >  nft add rule ip filter INPUT tcp dport 7880 ct state new update
> > @myrate { ip saddr . th dport  limit rate over 1/day burst 15 packets
> > } counter drop
> >
> > Use cases that works :
> > when we send 15 packets in 1 second, we wait for 10 seconds and the
> > next will be accepted at 11th second, this perfectly works with
> > update.
>
> Yes.
>
> >
> > Use cases that do not work :
> > Assume we are going to 1 packet every 1 second for an hour , we should
> > continuously accept all the new connections as we are sending only one
> > per second this is not working when use "update" in the rule , but
> > works when use "add" in the rule.
>
> I see. You never wanted the behaviour of --update to begin with, despite implying otherwise.
>
> >
> > Fyi, I have tested by adding this also - "tcp flags syn";
> >
> > Please advise me shall I use "add" in all the cases , so it satisfy
> > all the above uses cases.?
>
> Yes. The effect will be that any element added to the set will be evicted after 10 seconds has elapsed, no matter how many more times the rule is matched during the intervening period.
>
> --
> Kerin Millar



-- 
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08 10:19                   ` Sreedhar M
@ 2024-03-08 10:34                     ` Kerin Millar
  2024-03-08 11:44                       ` Sreedhar M
  0 siblings, 1 reply; 14+ messages in thread
From: Kerin Millar @ 2024-03-08 10:34 UTC (permalink / raw)
  To: Sreedhar M; +Cc: netfilter

On Fri, 8 Mar 2024, at 10:19 AM, Sreedhar M wrote:
> Great Kerin. Thank you so much for the support.
>
> With the below rules specially using 'add' and all my uses cases are working.
> nft add set ip filter myrate  { type ipv4_addr . inet_service; flags
> timeout ; flags dynamic; timeout 10s; }
> nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate {
> ip saddr . th dport  limit rate over 1/day burst 15 packets } counter
> drop

One more thing occurs to me. Now that you are using "add" and, given that "1/day" might otherwise appear confusing in the course of reviewing a ruleset, you could probably get away with changing the element template to:

{ ip saddr . th dport limit rate over 6/minute burst 15 packets }

Consider it optional; the behaviour should not change at all. Still, it does, perhaps, better hint at the underlying policy i.e. something should happen after 10 (60/6) seconds. Normally, that would be the bucket being credited with a token but it is my understanding that the timeout policy should prevail.

--
Kerin Millar

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: nftables rate limiting per multiple seconds
  2024-03-08 10:34                     ` Kerin Millar
@ 2024-03-08 11:44                       ` Sreedhar M
  0 siblings, 0 replies; 14+ messages in thread
From: Sreedhar M @ 2024-03-08 11:44 UTC (permalink / raw)
  To: Kerin Millar; +Cc: netfilter

Great Kerin. Good to know the optional.
Thanks again.

Best Regards
Sreedhar


On Fri, Mar 8, 2024 at 10:34 AM Kerin Millar <kfm@plushkava.net> wrote:
>
> On Fri, 8 Mar 2024, at 10:19 AM, Sreedhar M wrote:
> > Great Kerin. Thank you so much for the support.
> >
> > With the below rules specially using 'add' and all my uses cases are working.
> > nft add set ip filter myrate  { type ipv4_addr . inet_service; flags
> > timeout ; flags dynamic; timeout 10s; }
> > nft add rule ip filter INPUT tcp dport 7880 ct state new add @myrate {
> > ip saddr . th dport  limit rate over 1/day burst 15 packets } counter
> > drop
>
> One more thing occurs to me. Now that you are using "add" and, given that "1/day" might otherwise appear confusing in the course of reviewing a ruleset, you could probably get away with changing the element template to:
>
> { ip saddr . th dport limit rate over 6/minute burst 15 packets }
>
> Consider it optional; the behaviour should not change at all. Still, it does, perhaps, better hint at the underlying policy i.e. something should happen after 10 (60/6) seconds. Normally, that would be the bucket being credited with a token but it is my understanding that the timeout policy should prevail.
>
> --
> Kerin Millar



--
Best Regards
Sreedhar

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-03-08 11:45 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-06 22:11 nftables rate limiting per multiple seconds Sreedhar M
2024-03-06 22:39 ` Kerin Millar
2024-03-07 10:08   ` Sreedhar M
2024-03-07 12:30     ` Kerin Millar
2024-03-07 17:10       ` Sreedhar M
2024-03-07 23:11         ` Sreedhar M
2024-03-08  2:03         ` Kerin Millar
2024-03-08  7:26           ` Sreedhar M
2024-03-08  8:07             ` Kerin Millar
2024-03-08  9:12               ` Sreedhar M
2024-03-08  9:55                 ` Kerin Millar
2024-03-08 10:19                   ` Sreedhar M
2024-03-08 10:34                     ` Kerin Millar
2024-03-08 11:44                       ` Sreedhar M

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.