我同时使用Apache和Modsecurity,我试图通过请求的头部(如“facebookexternalhit”)来限制命中率,然后返回友好的“429 Too Many Requests”和“Retry-After:3英寸。我知道我可以读取一个文件的标题,如:SecRule REQUEST_HEADERS:User-Agent "@pmFromFile ratelimit-bots.txt"但我在建立规则时遇到了麻烦。任何帮助都将不胜感激。谢谢。
SecRule REQUEST_HEADERS:User-Agent "@pmFromFile ratelimit-bots.txt"
w3nuxt5m1#
经过两天的研究和了解Modsecurity是如何工作的,我终于做到了。FYI我使用的是Apache 2.4.37和Modsecurity 2.9.2这是我所做的:在我的自定义文件规则中:/etc/modsecurity/modsecurity_custom.conf我添加了以下规则:
/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"
说明:
1.第一个规则将请求标头用户代理与“facebookexternalhit”进行匹配。如果匹配成功,它将在global集合中创建ratelimit_facebookexternalhit属性,初始值为1(它将随着每次匹配用户代理的命中而递增该值)。然后,它将这个变量的有效期设置为3秒。如果我们收到一个匹配“facebookexternalhit”的新点击,它将为ratelimit_facebookexternalhit加1。如果我们在3秒后没有收到匹配“facebookexternalhit”的点击,ratelimit_facebookexternalhit将消失,并且此进程将重新启动。1.如果global.ratelimit_clients〉1(我们在3秒内收到2个或更多的点击)AND用户代理匹配“facebookexternalhit”(这个AND条件很重要,因为否则如果产生匹配,所有请求都将被拒绝),我们设置RATELIMITED=1,停止操作并显示429 http错误,并在Apache错误日志中记录一条自定义消息:“有限比例BOT”。1.设置RATELIMITED=1只是为了添加自定义标题“Retry-After:3”。在这种情况下,该var由Facebook的爬虫(facebookexternalhit)解释,并将在指定的时间内重试操作。1.我们为429错误Map一个自定义返回消息(如果需要)。你可以通过添加@pmf和一个.data文件来改进这个规则,然后初始化全局集合,比如initcol:global=%{MATCHED_VAR},这样你就不会被限制在一个单一的规则匹配。我没有测试最后一步(这是我现在需要的)。如果我测试了,我会更新我的答案。
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)#pmmromfile)。我们使用用户代理初始化USER集合:setuid:%{tx.ua_hash}(tx.ua_hash在/usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf中的全局范围内)。并且我们只是使用user作为集合而不是global。仅此而已!
/etc/modsecurity/data/ratelimit-clients.data
setuid:%{tx.ua_hash}
/usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf
643ylb082#
使用“deprecatevar”可能更好,并且可以允许稍大的突发延迟
# 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"
2条答案
按热度按时间w3nuxt5m1#
经过两天的研究和了解Modsecurity是如何工作的,我终于做到了。FYI我使用的是Apache 2.4.37和Modsecurity 2.9.2这是我所做的:
在我的自定义文件规则中:
/etc/modsecurity/modsecurity_custom.conf
我添加了以下规则:说明:
1.第一个规则将请求标头用户代理与“facebookexternalhit”进行匹配。如果匹配成功,它将在global集合中创建ratelimit_facebookexternalhit属性,初始值为1(它将随着每次匹配用户代理的命中而递增该值)。然后,它将这个变量的有效期设置为3秒。如果我们收到一个匹配“facebookexternalhit”的新点击,它将为ratelimit_facebookexternalhit加1。如果我们在3秒后没有收到匹配“facebookexternalhit”的点击,ratelimit_facebookexternalhit将消失,并且此进程将重新启动。
1.如果global.ratelimit_clients〉1(我们在3秒内收到2个或更多的点击)AND用户代理匹配“facebookexternalhit”(这个AND条件很重要,因为否则如果产生匹配,所有请求都将被拒绝),我们设置RATELIMITED=1,停止操作并显示429 http错误,并在Apache错误日志中记录一条自定义消息:“有限比例BOT”。
1.设置RATELIMITED=1只是为了添加自定义标题“Retry-After:3”。在这种情况下,该var由Facebook的爬虫(facebookexternalhit)解释,并将在指定的时间内重试操作。
1.我们为429错误Map一个自定义返回消息(如果需要)。
你可以通过添加@pmf和一个.data文件来改进这个规则,然后初始化全局集合,比如
initcol:global=%{MATCHED_VAR}
,这样你就不会被限制在一个单一的规则匹配。我没有测试最后一步(这是我现在需要的)。如果我测试了,我会更新我的答案。更新:
我已经修改了规则,以便能够对包含所有用户代理的文件进行评级限制,因此单个规则可以跨多个爬虫程序使用:
因此,包含用户代理的文件(每行一个)位于此规则的同一目录下的子目录中:
/etc/modsecurity/data/ratelimit-clients.data
。然后,我们使用@pmf读取并解析文件(https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#pmmromfile)。我们使用用户代理初始化USER集合:setuid:%{tx.ua_hash}
(tx.ua_hash在/usr/share/modsecurity-crs/modsecurity_crs_10_setup.conf
中的全局范围内)。并且我们只是使用user作为集合而不是global。仅此而已!643ylb082#
使用“deprecatevar”可能更好,并且可以允许稍大的突发延迟