Re: Rate Limiter Filter or Valve

2023-03-12 Thread Igal Sapir
On Thu, Mar 9, 2023 at 12:27 AM Rémy Maucherat  wrote:

> On Wed, Mar 8, 2023 at 8:37 PM Igal Sapir  wrote:
> >
> > All,
> >
> > I would like to add a Rate Limiter Filter or Valve which will help
> mitigate
> > DoS and Brute Force attacks, and want to get feedback from the community
> > and the PMC.  The checks will run before the request reaches the servlet
> > and will be dropped if too many requests arrive from the same IP address
> > within a certain time window.
> >
> > It has been suggested that a Valve might be the better choice because it
> > can be set up on a Host or Engine level, but in my opinion a Filter is a
> > good choice for the following reasons:
> >
> > 1) While in the past it was common to reuse the same server for different
> > applications due to costs and challenges in setting up servers, nowadays
> it
> > is more common to set up a single application per server, many times in a
> > containerized environment, so setting up a Rate Limiter on a Host or
> Engine
> > does not offer much benefit over setting it up on the Context level.
> >
> > 2) Different applications have different requirements  In fact, different
> > URIs of the same application could have different requirements: a Login /
> > Authentication script expects far less requests from a single IP address
> > compared to a Dashboard page, for example.  Filter mapping allows us to
> map
> > different URIs to different configurations.
> >
> > 3) Filters are part of the Servlet spec, and therefore more users are
> > familiar with them and know how to configure them.
> >
> > Either way it is implemented, I propose the following requirements for
> the
> > Rate Limiter itself (with the possibility of adding some of the features
> > later):
> >
> > A) Low overhead - The checks will take place with every request so the
> > implementation must be efficient and make good utilization of resources.
> >
> > B) Close approximation is good enough - If a URI is configured to allow
> 300
> > requests per minute and instead it allows 300 requests per 1:05 minute
> > before dropping the requests then that should be good enough, if that
> > allows the implementation to be more efficient with computation time and
> > memory consumption.  The approximation can offer leniency but not
> > strictness, meaning that it's ok if it allows more requests than the
> > configured value, but not less.
> >
> > C) Drop excessive requests - Requests from an IP that exceeds the allowed
> > limit will be dropped and "429 Too Many Requests" will be returned to the
> > client.
> >
> > D) Tag only mode - If configured as such, then rather than dropping the
> > request with a 429 error code, a Request Attribute will be set and that
> > would allow the Servlet to determine what to do next, e.g. it might allow
> > authenticated clients more requests than it would to unauthenticated
> > clients.
> >
> > E) Allow list of URI patterns - Static resources have very little
> overhead,
> > so requests for "*.jpg" or "*.png" should not be counted by the Rate
> > Limiter.
> >
> > F) Allow list of IP addresses - Known IP addresses that are used by your
> > organization, or 3rd party partners, should not be blocked.
> >
> > G) Block list of IP addresses - Repeat offenders can be added
> automatically
> > to the block list for 4 hours, for example, preventing them from hitting
> > the server each minute and contributing to a DDoS attack.
> >
> > H) Logging
> >
> > Please offer your thoughts and ideas.
>
> That's a good feature idea overall. Of course, no matter what you do,
> it's going to be better if done on a front end server, and any serious
> setup will do it like that.
>

True, and in most Prod deployments I do that on the reverse proxy server,
but it'd
be nice to have a simple solution that can be used without having to
configure another
server.


>
> As for filter or valve, well, it's your choice ;)
>

Sounds good.  I think that I will start with a Filter implementation but
the
core logic will be in reusable classes so it will be very easy to add a
Valve
if others think that it's beneficial.

Igal



>
> Rémy
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Rate Limiter Filter or Valve

2023-03-09 Thread Rémy Maucherat
On Wed, Mar 8, 2023 at 8:37 PM Igal Sapir  wrote:
>
> All,
>
> I would like to add a Rate Limiter Filter or Valve which will help mitigate
> DoS and Brute Force attacks, and want to get feedback from the community
> and the PMC.  The checks will run before the request reaches the servlet
> and will be dropped if too many requests arrive from the same IP address
> within a certain time window.
>
> It has been suggested that a Valve might be the better choice because it
> can be set up on a Host or Engine level, but in my opinion a Filter is a
> good choice for the following reasons:
>
> 1) While in the past it was common to reuse the same server for different
> applications due to costs and challenges in setting up servers, nowadays it
> is more common to set up a single application per server, many times in a
> containerized environment, so setting up a Rate Limiter on a Host or Engine
> does not offer much benefit over setting it up on the Context level.
>
> 2) Different applications have different requirements  In fact, different
> URIs of the same application could have different requirements: a Login /
> Authentication script expects far less requests from a single IP address
> compared to a Dashboard page, for example.  Filter mapping allows us to map
> different URIs to different configurations.
>
> 3) Filters are part of the Servlet spec, and therefore more users are
> familiar with them and know how to configure them.
>
> Either way it is implemented, I propose the following requirements for the
> Rate Limiter itself (with the possibility of adding some of the features
> later):
>
> A) Low overhead - The checks will take place with every request so the
> implementation must be efficient and make good utilization of resources.
>
> B) Close approximation is good enough - If a URI is configured to allow 300
> requests per minute and instead it allows 300 requests per 1:05 minute
> before dropping the requests then that should be good enough, if that
> allows the implementation to be more efficient with computation time and
> memory consumption.  The approximation can offer leniency but not
> strictness, meaning that it's ok if it allows more requests than the
> configured value, but not less.
>
> C) Drop excessive requests - Requests from an IP that exceeds the allowed
> limit will be dropped and "429 Too Many Requests" will be returned to the
> client.
>
> D) Tag only mode - If configured as such, then rather than dropping the
> request with a 429 error code, a Request Attribute will be set and that
> would allow the Servlet to determine what to do next, e.g. it might allow
> authenticated clients more requests than it would to unauthenticated
> clients.
>
> E) Allow list of URI patterns - Static resources have very little overhead,
> so requests for "*.jpg" or "*.png" should not be counted by the Rate
> Limiter.
>
> F) Allow list of IP addresses - Known IP addresses that are used by your
> organization, or 3rd party partners, should not be blocked.
>
> G) Block list of IP addresses - Repeat offenders can be added automatically
> to the block list for 4 hours, for example, preventing them from hitting
> the server each minute and contributing to a DDoS attack.
>
> H) Logging
>
> Please offer your thoughts and ideas.

That's a good feature idea overall. Of course, no matter what you do,
it's going to be better if done on a front end server, and any serious
setup will do it like that.

As for filter or valve, well, it's your choice ;)

Rémy

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Re: Rate Limiter Filter or Valve

2023-03-08 Thread Igal Sapir
Chris,

On Wed, Mar 8, 2023 at 4:18 PM Christopher Schultz <
ch...@christopherschultz.net> wrote:

> Igal,
>
> On 3/8/23 14:36, Igal Sapir wrote:
> > I would like to add a Rate Limiter Filter or Valve which will help
> mitigate
> > DoS and Brute Force attacks, and want to get feedback from the community
> > and the PMC.  The checks will run before the request reaches the servlet
> > and will be dropped if too many requests arrive from the same IP address
> > within a certain time window.
> >
> > It has been suggested that a Valve might be the better choice because it
> > can be set up on a Host or Engine level, but in my opinion a Filter is a
> > good choice for the following reasons:
> >
> > 1) While in the past it was common to reuse the same server for different
> > applications due to costs and challenges in setting up servers, nowadays
> it
> > is more common to set up a single application per server, many times in a
> > containerized environment, so setting up a Rate Limiter on a Host or
> Engine
> > does not offer much benefit over setting it up on the Context level.
>
> Counter-point: an attacker can make requests to non-existent contexts
> and avoid your Filter. You could put the Filter on the ROOT application
> as well, but (a) nobody will remember to do that and (b) it won't share
> data with the primary web application.
>
> Honestly, it should pretty easy to write a general rate-limiter and then
> wrap a Filter and/or Valve around it.
>

Fair enough.  There is no reason to not implement both.


>
> > 2) Different applications have different requirements  In fact, different
> > URIs of the same application could have different requirements: a Login /
> > Authentication script expects far less requests from a single IP address
> > compared to a Dashboard page, for example.  Filter mapping allows us to
> map
> > different URIs to different configurations.
>
> +1
>
> > 3) Filters are part of the Servlet spec, and therefore more users are
> > familiar with them and know how to configure them.
>
> +1
>
> A Filter is also portable to other containers. Speaking of which... has
> this wheel already been invented? I would be surprised if Spring
> Security doesn't already have this kind of thing.
>

I don't know about Spring Security, but Jetty has a DoSFilter.  I haven't
looked into it though,
as I don't think that Tomcat users should have to go and get a filter from
another engine.


>
> > Either way it is implemented, I propose the following requirements for
> the
> > Rate Limiter itself (with the possibility of adding some of the features
> > later):
> >
> > A) Low overhead - The checks will take place with every request so the
> > implementation must be efficient and make good utilization of resources.
> >
> > B) Close approximation is good enough - If a URI is configured to allow
> 300
> > requests per minute and instead it allows 300 requests per 1:05 minute
> > before dropping the requests then that should be good enough, if that
> > allows the implementation to be more efficient with computation time and
> > memory consumption.  The approximation can offer leniency but not
> > strictness, meaning that it's ok if it allows more requests than the
> > configured value, but not less.
> >
> > C) Drop excessive requests - Requests from an IP that exceeds the allowed
> > limit will be dropped and "429 Too Many Requests" will be returned to the
> > client.
> >
> > D) Tag only mode - If configured as such, then rather than dropping the
> > request with a 429 error code, a Request Attribute will be set and that
> > would allow the Servlet to determine what to do next, e.g. it might allow
> > authenticated clients more requests than it would to unauthenticated
> > clients.
>
> +1
>
> > E) Allow list of URI patterns - Static resources have very little
> overhead,
> > so requests for "*.jpg" or "*.png" should not be counted by the Rate
> > Limiter.
> >
> > F) Allow list of IP addresses - Known IP addresses that are used by your
> > organization, or 3rd party partners, should not be blocked.
> >
> > G) Block list of IP addresses - Repeat offenders can be added
> automatically
> > to the block list for 4 hours, for example, preventing them from hitting
> > the server each minute and contributing to a DDoS attack.
> >
> > H) Logging
> >
> > Please offer your thoughts and ideas.
>
> Avoid regular expressions. For IP range matching, search the archives
> for references to CIDR. I think there was a discussion some years ago
> about that. In fact, I there should be a CIDR evaluator/matcher
> somewhere in the Tomcat source code already.
>

Agreed.  I am not a fan of Regex in general.  I will definitely look at the
Tomcat code for that first, thanks!

Igal


>
> -chris
>
> -
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>
>


Re: Rate Limiter Filter or Valve

2023-03-08 Thread Christopher Schultz

Igal,

On 3/8/23 14:36, Igal Sapir wrote:

I would like to add a Rate Limiter Filter or Valve which will help mitigate
DoS and Brute Force attacks, and want to get feedback from the community
and the PMC.  The checks will run before the request reaches the servlet
and will be dropped if too many requests arrive from the same IP address
within a certain time window.

It has been suggested that a Valve might be the better choice because it
can be set up on a Host or Engine level, but in my opinion a Filter is a
good choice for the following reasons:

1) While in the past it was common to reuse the same server for different
applications due to costs and challenges in setting up servers, nowadays it
is more common to set up a single application per server, many times in a
containerized environment, so setting up a Rate Limiter on a Host or Engine
does not offer much benefit over setting it up on the Context level.


Counter-point: an attacker can make requests to non-existent contexts 
and avoid your Filter. You could put the Filter on the ROOT application 
as well, but (a) nobody will remember to do that and (b) it won't share 
data with the primary web application.


Honestly, it should pretty easy to write a general rate-limiter and then 
wrap a Filter and/or Valve around it.



2) Different applications have different requirements  In fact, different
URIs of the same application could have different requirements: a Login /
Authentication script expects far less requests from a single IP address
compared to a Dashboard page, for example.  Filter mapping allows us to map
different URIs to different configurations.


+1


3) Filters are part of the Servlet spec, and therefore more users are
familiar with them and know how to configure them.


+1

A Filter is also portable to other containers. Speaking of which... has 
this wheel already been invented? I would be surprised if Spring 
Security doesn't already have this kind of thing.



Either way it is implemented, I propose the following requirements for the
Rate Limiter itself (with the possibility of adding some of the features
later):

A) Low overhead - The checks will take place with every request so the
implementation must be efficient and make good utilization of resources.

B) Close approximation is good enough - If a URI is configured to allow 300
requests per minute and instead it allows 300 requests per 1:05 minute
before dropping the requests then that should be good enough, if that
allows the implementation to be more efficient with computation time and
memory consumption.  The approximation can offer leniency but not
strictness, meaning that it's ok if it allows more requests than the
configured value, but not less.

C) Drop excessive requests - Requests from an IP that exceeds the allowed
limit will be dropped and "429 Too Many Requests" will be returned to the
client.

D) Tag only mode - If configured as such, then rather than dropping the
request with a 429 error code, a Request Attribute will be set and that
would allow the Servlet to determine what to do next, e.g. it might allow
authenticated clients more requests than it would to unauthenticated
clients.


+1


E) Allow list of URI patterns - Static resources have very little overhead,
so requests for "*.jpg" or "*.png" should not be counted by the Rate
Limiter.

F) Allow list of IP addresses - Known IP addresses that are used by your
organization, or 3rd party partners, should not be blocked.

G) Block list of IP addresses - Repeat offenders can be added automatically
to the block list for 4 hours, for example, preventing them from hitting
the server each minute and contributing to a DDoS attack.

H) Logging

Please offer your thoughts and ideas.


Avoid regular expressions. For IP range matching, search the archives 
for references to CIDR. I think there was a discussion some years ago 
about that. In fact, I there should be a CIDR evaluator/matcher 
somewhere in the Tomcat source code already.


-chris

-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



Rate Limiter Filter or Valve

2023-03-08 Thread Igal Sapir
All,

I would like to add a Rate Limiter Filter or Valve which will help mitigate
DoS and Brute Force attacks, and want to get feedback from the community
and the PMC.  The checks will run before the request reaches the servlet
and will be dropped if too many requests arrive from the same IP address
within a certain time window.

It has been suggested that a Valve might be the better choice because it
can be set up on a Host or Engine level, but in my opinion a Filter is a
good choice for the following reasons:

1) While in the past it was common to reuse the same server for different
applications due to costs and challenges in setting up servers, nowadays it
is more common to set up a single application per server, many times in a
containerized environment, so setting up a Rate Limiter on a Host or Engine
does not offer much benefit over setting it up on the Context level.

2) Different applications have different requirements  In fact, different
URIs of the same application could have different requirements: a Login /
Authentication script expects far less requests from a single IP address
compared to a Dashboard page, for example.  Filter mapping allows us to map
different URIs to different configurations.

3) Filters are part of the Servlet spec, and therefore more users are
familiar with them and know how to configure them.

Either way it is implemented, I propose the following requirements for the
Rate Limiter itself (with the possibility of adding some of the features
later):

A) Low overhead - The checks will take place with every request so the
implementation must be efficient and make good utilization of resources.

B) Close approximation is good enough - If a URI is configured to allow 300
requests per minute and instead it allows 300 requests per 1:05 minute
before dropping the requests then that should be good enough, if that
allows the implementation to be more efficient with computation time and
memory consumption.  The approximation can offer leniency but not
strictness, meaning that it's ok if it allows more requests than the
configured value, but not less.

C) Drop excessive requests - Requests from an IP that exceeds the allowed
limit will be dropped and "429 Too Many Requests" will be returned to the
client.

D) Tag only mode - If configured as such, then rather than dropping the
request with a 429 error code, a Request Attribute will be set and that
would allow the Servlet to determine what to do next, e.g. it might allow
authenticated clients more requests than it would to unauthenticated
clients.

E) Allow list of URI patterns - Static resources have very little overhead,
so requests for "*.jpg" or "*.png" should not be counted by the Rate
Limiter.

F) Allow list of IP addresses - Known IP addresses that are used by your
organization, or 3rd party partners, should not be blocked.

G) Block list of IP addresses - Repeat offenders can be added automatically
to the block list for 4 hours, for example, preventing them from hitting
the server each minute and contributing to a DDoS attack.

H) Logging

Please offer your thoughts and ideas.

Thank you,

Igal