我正在尝试为Apache配置modsecurity,以限制每单位时间内可以访问给定资源的命中数(假设,每个资源每分钟10次点击,无论请求是哪个IP地址)。资源具有“https://myhost/my-resource/my-resource-id”
形式的网址格式# Limit the requests count by unit of time.
SecRuleEngine On
<LocationMatch "^.*/my-resource/.*">
# SecAction initcol:ip=%{REMOTE_ADDR},pass,nolog,id:132
SecAction initcol:uri=%{REQUEST_URI},pass,nolog,id:232
SecAction "phase:5,deprecatevar:uri.counter=10/60,pass,nolog,id:332"
SecRule URI:COUNTER "@ge 10" "phase:2,pause:10,deny,status:429,setenv:RATELIMITED,skip:1,nolog,id:432"
SecAction "phase:2,pass,setvar:uri.counter=+1,nolog,id:532"
Header always set Retry-After "60" env=RATELIMITED
</LocationMatch>
ErrorDocument 429 "Too Many Requests"
据我了解这个片段,它告诉modsecurity“为每个request_uri创建一个名为uri的变量并为每个request_uri关联一个计数器,然后每60秒递减一次。如果当前的uri计数器达到10的值,则失败错误代码429,否则增加“这是我需要的。
此配置导致“未找到uri变量”错误,我不明白为什么。
如果我取消注释第一个SecAction并更改剩余配置以引用它,它可以工作(在10次快速调用后返回429),但显然不考虑uri(它对任何资源都失败,例如./ my -resource / 123和/ my-resource / 456)
有人可以帮忙吗?我的所有尝试都失败了,我对Apache的配置一般都不太熟悉,所以我想我在这里错过了一些重要的概念。
PS:Apache是v2.4,mod-security是v2.9
谢谢!
答案 0 :(得分:0)
有效的配置如下:
# Limit the requests count by unit of time.
SecRuleEngine On
<LocationMatch "^.*/my-resource/.*">
SecAction initcol:resource=%{REQUEST_URI},pass,nolog,id:132
SecRule RESOURCE:COUNTER "@ge 10" "phase:3,pause:10,deny,status:429,setenv:RATELIMITED,skip:1,nolog,id:232"
SecAction "phase:2,setvar:resource.counter=+1,pass,nolog,id:332"
SecAction "phase:2,deprecatevar:resource.counter=10/60,pass,nolog,id:432"
Header always set Retry-After "60" env=RATELIMITED
</LocationMatch>
ErrorDocument 429 "Too Many Requests"
ndlr:从&#34; uri&#34;更改集合名称到&#34;资源&#34;并稍微调整相位
然后它按预期工作(参见modsecurity邮件列表:https://sourceforge.net/p/mod-security/mailman/message/35889575/)