Re: Rate Limiter Filter or Valve
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
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
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
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
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