Modsecurity&Apache:如何通过标头限制访问速率?



我让Apache和Modsecurity一起工作。我试图通过请求的标题来限制命中率(比如"facebookexternalhit"(。然后返回友好的"429请求太多"one_answers"重试时间:3"。

我知道我可以阅读一个标题文件,比如:

SecRule REQUEST_HEADERS:User-Agent "@pmFromFile ratelimit-bots.txt"

但我在制定规则时遇到了麻烦。

如有任何帮助,我们将不胜感激。非常感谢。

经过两天的研究和了解Modsecurity的工作原理,我终于做到了。仅供参考,我正在使用Apache 2.4.37和Modsecurity 2.9.2这就是我所做的:

在我的自定义文件规则:/etc/modsecurity/modsecurity_custom.conf中,我添加了以下规则:

# Limit client hits by user agent
SecRule REQUEST_HEADERS:User-Agent "@pm facebookexternalhit" 
"id:400009,phase:2,nolog,pass,setvar:global.ratelimit_facebookexternalhit=+1,expirevar:global.ratelimit_facebookexternalhit=3"
SecRule GLOBAL:RATELIMIT_FACEBOOKEXTERNALHIT "@gt 1" 
"chain,id:4000010,phase:2,pause:300,deny,status:429,setenv:RATELIMITED,log,msg:'RATELIMITED BOT'"
SecRule REQUEST_HEADERS:User-Agent "@pm facebookexternalhit"
Header always set Retry-After "3" env=RATELIMITED
ErrorDocument 429 "Too Many Requests"

说明:

注意:我希望限制为每3秒1个请求

  1. 第一条规则将请求头用户代理与"facebookexternalhit"匹配。如果匹配成功,它将在全局集合中创建ratelimit_facebookexternalhit属性,初始值为1(它将随着与用户代理匹配的每次命中而增加该值(。然后,它将此var的过期时间设置为3秒。如果我们收到一个匹配"facebookexternalhit"的新点击,它将加1到ratelimit_facebookexternal hit。如果我们在3秒钟后没有收到与"facebookexternalhit"匹配的点击,ratelimit_facebookexternal hit将消失,此过程将重新启动
  2. 如果global.ratelimit_clients>1(我们在3秒内收到2个或更多点击(AND用户代理匹配"facebookexternalhit"(这个AND条件很重要,因为否则如果产生匹配,所有请求都将被拒绝(,我们将RATELIMITED设置为1,停止带有429http错误的操作,并在Apache错误日志中记录一条自定义消息:"RATELIMITEDBOT">
  3. RATELIMITED=1仅用于添加自定义标头"Retry After:3"。在这种情况下,这个var由Facebook的爬网程序(facebookexternalhit(解释,并将在指定的时间内重试操作
  4. 我们为429错误映射了一个自定义返回消息(如果需要的话(

您可以通过添加@pmf和.data文件来改进此规则,然后初始化全局集合(如initcol:global=%{MATCHED_VAR}(,这样您就不局限于按规则进行的单个匹配。我没有测试最后一步(这是我现在需要的(。我会更新我的答案,以备不时之需。

更新

我已经调整了规则,使其能够拥有一个包含我想要评分限制的所有用户代理的文件,因此一个规则可以在多个机器人/爬网程序中使用:

# Limit client hits by user agent
SecRule REQUEST_HEADERS:User-Agent "@pmf data/ratelimit-clients.data" 
"id:100008,phase:2,nolog,pass,setuid:%{tx.ua_hash},setvar:user.ratelimit_client=+1,expirevar:user.ratelimit_client=3"
SecRule USER:RATELIMIT_CLIENT "@gt 1" 
"chain,id:1000009,phase:2,deny,status:429,setenv:RATELIMITED,log,msg:'RATELIMITED BOT'"                                                                                     
SecRule REQUEST_HEADERS:User-Agent "@pmf data/ratelimit-clients.data"
Header always set Retry-After "3" env=RATELIMITED
ErrorDocument 429 "Too Many Requests"

因此,具有用户代理的文件(每行一个(位于该规则的同一目录下的一个子目录中:/etc/modsecurity/data/ratelimit-clients.data。然后我们使用@pmf来读取和解析文件(https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x(#pmfromfile(。我们使用用户代理setuid:%{tx.ua_hash}初始化USER集合(tx.ua_hash/usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf的全局范围内(。我们只是使用用户作为集合,而不是全局。仅此而已!

使用"depletevar";,你可以允许更大的突发亮度

# Limit client hits by user agent
SecRule REQUEST_HEADERS:User-Agent "@pmf data/ratelimit-clients.data" 
"id:100008,phase:2,nolog,pass,setuid:%{tx.ua_hash},setvar:user.ratelimit_client=+1,deprecatevar:user.ratelimit_client=3/1"
SecRule USER:RATELIMIT_CLIENT "@gt 1" 
"chain,id:100009,phase:2,deny,status:429,setenv:RATELIMITED,log,msg:'RATELIMITED BOT'"                                                                 
SecRule REQUEST_HEADERS:User-Agent "@pmf data/ratelimit-clients.data"

Header always set Retry-After "6" env=RATELIMITED

ErrorDocument 429 "Too Many Requests"

相关内容

  • 没有找到相关文章

最新更新