如何在Apache中通过Mod Security模块为各网站配置速率限制?
Apache ModSecurity 2.9.5 多站点自定义速率限制配置方案
你的现有规则存在几个关键问题:计数器初始化冗余、阈值配置错误、缺少重试时间提示、未支持多站点差异化阈值,以下是优化后的专业配置方案:
核心规则实现
1. 初始化IP+站点专属计数器集合
仅在IP与站点的组合计数器未创建时初始化,避免无意义的重复操作:
# 仅当IP+站点的集合未初始化时,创建集合并初始化基础变量 SecRule IP:%{REMOTE_ADDR}-%{SERVER_NAME} "@unmatched" \ "phase:1,id:900,pass,nolog,\ initcol:ip=%{REMOTE_ADDR}-%{SERVER_NAME},\ setvar:ip.%{REMOTE_ADDR}-%{SERVER_NAME}.request_count=0,\ setvar:ip.%{REMOTE_ADDR}-%{SERVER_NAME}.window_start=%{TIME_EPOCH}"
2. 分站点配置差异化速率阈值
针对每个站点单独设置速率限制,示例中包含两个站点和默认规则,可按需扩展至100+站点:
# domain1.com: 同一IP每分钟100次请求 SecRule REQUEST_HEADERS:Host "@rx ^domain1\.com$" \ "phase:1,id:901,pass,nolog,\ setvar:tx.rate_limit=100,\ setvar:tx.window_seconds=60" # domain2.com: 同一IP每分钟150次请求(示例不同阈值) SecRule REQUEST_HEADERS:Host "@rx ^domain2\.com$" \ "phase:1,id:902,pass,nolog,\ setvar:tx.rate_limit=150,\ setvar:tx.window_seconds=60" # 默认规则:未单独配置的站点统一限制为每分钟80次请求 SecRule REQUEST_HEADERS:Host "@rx .+" \ "phase:1,id:903,pass,nolog,\ setvar:tx.rate_limit=80,\ setvar:tx.window_seconds=60"
3. 计数、阈值检查与超限拦截
自动重置过期计数器,拦截超限请求并返回符合HTTP规范的429状态码与重试提示:
# 重置已过期的计数器(窗口时间结束后清零) SecRule IP:%{REMOTE_ADDR}-%{SERVER_NAME}.window_start "@lt %{TIME_EPOCH}-%{tx.window_seconds}" \ "phase:1,id:904,pass,nolog,\ setvar:ip.%{REMOTE_ADDR}-%{SERVER_NAME}.request_count=0,\ setvar:ip.%{REMOTE_ADDR}-%{SERVER_NAME}.window_start=%{TIME_EPOCH}" # 递增当前请求计数器 SecAction \ "phase:1,id:905,pass,nolog,\ setvar:ip.%{REMOTE_ADDR}-%{SERVER_NAME}.request_count+=1" # 拦截超限请求,返回429并设置Retry-After响应头 SecRule IP:%{REMOTE_ADDR}-%{SERVER_NAME}.request_count "@gt %{tx.rate_limit}" \ "phase:1,id:906,deny,status:429,\ log,msg:'Client %{REMOTE_ADDR} exceeded rate limit for %{SERVER_NAME}: %{tx.rate_limit} requests/%{tx.window_seconds}s',\ setenv:RETRY_AFTER=%{tx.window_seconds},\ header:Retry-After=%{env.RETRY_AFTER}"
关键配置说明
- 唯一计数器标识:用
%{REMOTE_ADDR}-%{SERVER_NAME}作为IP与站点的组合键,确保不同站点的计数器完全隔离 - 动态阈值管理:通过
tx变量存储阈值,便于批量修改和维护100+站点的配置 - 自动过期机制:对比当前时间与窗口起始时间,自动重置过期计数器,避免内存泄漏
- 规范响应头:
Retry-After头明确告知客户端需要等待的秒数,符合HTTP 429状态码的规范要求 - 可追溯日志:日志包含IP、站点、阈值等关键信息,便于后续排查超限事件
部署注意事项
- 可将规则放在全局
modsecurity.conf中,或每个站点的VirtualHost配置块内(全局配置需确保SERVER_NAME正确设置) - 对于100+站点,建议将分站点阈值配置单独存入
modsecurity-rate-limits.conf文件,通过Include指令引入,简化维护流程 - 测试规则可使用
curl模拟批量请求:for i in {1..101}; do curl -I https://domain1.com; done - 监控ModSecurity审计日志(默认路径
/var/log/apache2/modsec_audit.log)确认规则生效状态
内容的提问来源于stack exchange,提问作者Rahul Thakkar
相关产品推荐
相关产品推荐

