mod_rewrite无法实现基于请求频率的动态屏蔽,因其无跨请求状态计数能力;它仅支持基于url、参数、ua等特征的静态即时拦截(如[f]标志),频次控制须依赖mod_evasive或fail2ban等专用方案。

mod_rewrite 本身不提供请求频次统计能力,它无法直接实现“基于频次的动态屏蔽”。[F] 标志只是立即返回 403 Forbidden,作用是静态匹配并拒绝——比如匹配到某个参数、路径或 UA 就拦截,但不会记住“这个 IP 已经访问了 15 次”。
所以,用 mod_rewrite + [F] 实现“恶意频次屏蔽”在技术上不可行。这是常见误解。真正能做频次控制的是专用模块(如 mod_evasive)或外部系统(如 fail2ban),而 mod_rewrite 只适合做基于内容特征的即时拦截。
下面分清楚两类场景,避免误配:
✅ 正确用法:用 mod_rewrite + [F] 做“特征式即时拦截”
适用于识别明确恶意信号(无需计数),例如:
- 请求中含
cmd=、exec=、phpinfo等高危参数 - 访问
/wp-admin/但非登录态且 UA 异常 - 查询字符串含 base64 或 hex 编码的敏感指令
关键写法:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
# 拒绝任何含 cmd= 或 exec= 的请求(大小写不敏感)
RewriteCond %{QUERY_STRING} (cmd|exec)= [NC]
RewriteRule ^ - [F]
# 拒绝 UA 为空或含 python-requests/curl 的 /admin/ 路径请求
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} (python-requests|curl|Go-http-client) [NC]
RewriteRule ^/admin/ - [F]
⚠️ 注意:
-
RewriteCond必须紧挨RewriteRule -
%{QUERY_STRING}是原始编码值(如空格是+,中文是%E4%BD%A0),正则要按此匹配 -
.htaccess中需确保AllowOverride FileInfo已启用
❌ 错误尝试:强行用 mod_rewrite 做频次限制
以下配置无效且危险:
# 错误示例:rewrite 无法累计计数,这条规则永远只看当前请求
RewriteCond %{ENV:RATE_COUNT} >10
RewriteRule ^ - [F]
Apache 环境变量(如 %{ENV:xxx})是单次请求生命周期的,mod_rewrite 不维护跨请求状态,也无法原子增减计数。试图用 RewriteMap + 程序脚本模拟频控,性能差、易竞态、不推荐。
✅ 替代方案:真正防频次攻击的 Apache 推荐组合
| 方案 | 适用场景 | 关键配置点 |
|---|---|---|
mod_evasive |
简单有效,防扫描/CC,内存级临时封禁 |
DOSPageCount 10(同页面1秒内10次)、DOSSiteCount 50(全站2秒50次)、DOSBlockingPeriod 600(封10分钟);确认 apachectl -M | grep evasive 已加载 |
fail2ban + Apache 日志 |
精准可控,可审计,支持长期封禁 | 自定义 filter 匹配 access.log 中高频 404、无 Referer、爆破路径等行为;bantime = 3600,配合 iptables 或 nftables 执行封禁 |
| 前置 Nginx 限流 | 更高效,推荐作为反向代理层防护 |
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s; + limit_req zone=api burst=10 nodelay;
|
若你已在用 Apache 且不想加 Nginx,
mod_evasive是最轻量、最贴近需求的选择;若需日志溯源和灵活策略,fail2ban是更健壮的方案。
不需要复杂逻辑,抓准工具边界,才能稳定防护。









