我正在尝试使用 为 apache (v2.2) 虚拟主机中的某些敏感 URI 设置请求限制mod_security
,但发现使用 存在问题LocationMatch
。到目前为止,配置如下:
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
DocumentRoot "/var/www/html/www.example.com"
<Directory "/var/www/html/www.example.com">
Options None
AllowOverride None
Order allow,deny
Allow from all
</Directory>
SecRuleEngine On
# ignore requests from localhost or some other IP
SecRule REMOTE_ADDR "^127\.0\.0\.2$" "phase:1,id:'1',nolog,allow"
<LocationMatch "^\/RESTv2\/auth\..+">
SecRule REQUEST_FILENAME ".*" "phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests.auth=+1,id:'3',expirevar:ip.requests.auth=1"
SecRule ip:requests.auth "@gt 2" "phase:1,pass,log,logdata:'blocking auth %{REMOTE_ADDR} req/sec: %{ip.requests}',setvar:ip.block.auth=1,expirevar:ip.block.auth=5,id:'4'"
SecRule ip:block.auth "@eq 1" "phase:1,deny,id:'999',nolog,logdata:'blocking RESTv2/auth.json for %{REMOTE_ADDR} req/sec: %{ip.requests.auth}', status:509"
</LocationMatch>
ErrorDocument 509 "Special Rate Limit Exceeded!"
</VirtualHost>
问题是,LocationMatch
即使我将指令简化为像 一样一般的东西,它也不会匹配.*
。我也尝试过在正则表达式中使用和不使用/
转义符,行为没有任何区别。
如果我注释掉打开和关闭标签,节流规则将按预期工作,只是它们在标签内时永远不会启动LocationMatch
。/RESTv2/auth.json
文件存在于DocumentRoot
目录内,并正常提供服务。
我正在以 方式调用受限制的请求curl http://www.example.com/RESTv2/auth.json
。
这是使用上的问题LocationMatch
,还是它与mod_security
规则之间存在一些奇怪的交互?
答案1
ModSecurity 第 1 阶段规则在 LocationMatch 指令之前处理。
因此,您需要将这些更改为第 2 阶段规则(这可能并不可取,因为会浪费时间处理所有第 1 阶段规则而不是立即阻止这些规则)或使用 ModSecurity 语法和链式规则来替换 LocationMatch 语法:
SecRule REQUEST_URI "^\/RESTv2\/auth\..+" phase:1,nolog,pass,initcol:ip=%{REMOTE_ADDR},setvar:ip.requests.auth=+1,id:'3',expirevar:ip.requests.auth=1,chain”
SecRule REQUEST_FILENAME ".*"
其他规则也同样如此。