[f]标志直接返回http 403 forbidden响应,不重定向、不改写url,仅中断请求并发送拒绝状态码,与[r](重定向)、[p](代理)有本质区别。

直接用 RewriteRule 配合 [F] 标志就能实现基于域名或路径的强制拒绝,但必须确保 RewriteCond 匹配逻辑正确、RewriteEngine 已启用,且规则位置不会被其他配置覆盖。
为什么 [F] 能返回 403 而不是跳转
[F] 是 mod_rewrite 的内置标志,作用是立即中断请求处理流程,并返回 HTTP 状态码 403 Forbidden。它不重定向、不代理、不改写 URL,只发一个干净的拒绝响应。这和 [R](重定向)、[P](代理)有本质区别——如果你看到浏览器跳到了错误页或 404,说明规则没生效,或者被后续规则覆盖了。
常见错误现象:curl -I http://blocked.example.com 返回 200 或 301,而不是 403;日志里出现 client denied by server configuration(这是 Require 拒绝的提示,和 [F] 无关)。
-
[F]必须和RewriteCond配合使用,单独写RewriteRule .* - [F]会拦截所有请求 - 若在
.htaccess中使用,需确认对应目录的AllowOverride包含FileInfo或All - Apache 2.4 默认不启用
mod_rewrite,得先检查httpd -M | grep rewrite输出中是否有rewrite_module
RewriteCond %{HTTP_HOST} 匹配域名时的大小写与边界问题
域名匹配最常出错的地方是正则表达式没锚定、忽略大小写、或漏掉子域名变体。比如想封 bad.example.com,但用户访问的是 www.bad.example.com 或 BAD.EXAMPLE.COM,规则就失效。
实操建议:
- 加
[NC]标志确保不区分大小写:RewriteCond %{HTTP_HOST} ^bad\.example\.com$ [NC] - 用
^和$锚定整个 Host 字符串,避免部分匹配(如bad.example.com.evil.com) - 点号
.必须转义为\.,否则会被当作正则通配符 - 如果要同时封多个域名,用
|分隔:RewriteCond %{HTTP_HOST} ^(bad\.example\.com|evil\.site)$ [NC]
把黑名单规则放在 VirtualHost 还是 .htaccess 更稳妥
优先放 <virtualhost></virtualhost> 块里。它加载早、执行快、不受 AllowOverride 限制,也避免因目录层级导致规则被跳过。而 .htaccess 是运行时逐目录读取的,性能差,且容易被上层目录的同名文件覆盖。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
典型配置位置示例(放在 /etc/httpd/conf.d/vhost.conf 或主配置的 <virtualhost></virtualhost> 内):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(malicious\.com|spam\.org|phish\.net)$ [NC]
RewriteRule .* - [F,L]
注意:[L] 很关键——它告诉 Apache 这是最后一条规则,避免后续规则意外放行。没有它,哪怕前面匹配了,后面某条 RewriteRule 可能又把请求放过去了。
- 修改后必须运行
apachectl configtest,确认输出Syntax OK才 reload - 不要把
RewriteRule放在<directory></directory>块里——mod_rewrite在目录上下文中对%{HTTP_HOST}的支持不稳定 - 如果服务器前端有 CDN 或 Nginx,
%{HTTP_HOST}可能已被改写,此时应结合%{HTTP_X_FORWARDED_HOST}判断(需确保可信)
用外部文本文件做动态黑名单,改完不用重启
硬编码在配置里的黑名单,每次增删都要 reload Apache,不适合高频更新场景。可以用 RewriteMap 指向一个纯文本映射文件,实现热更新。
步骤简述:
- 在主配置中声明映射:
RewriteMap blacklist "txt:/etc/httpd/conf/blacklist.txt" - 准备
/etc/httpd/conf/blacklist.txt,每行一个域名:bad.example.com 1 - 在
<virtualhost></virtualhost>中写规则:RewriteCond ${blacklist:%{HTTP_HOST}|0} ^1$RewriteRule .* - [F,L]
这个方案的关键点:文本文件修改后无需 reload,Apache 每次请求时自动重新读取(默认缓存 10 分钟,可调)。但要注意文件权限必须是 Apache 进程可读(如 root:apache + 644),且路径不能用相对路径。
容易被忽略的地方:如果域名带端口(如 example.com:8080),%{HTTP_HOST} 会包含端口号,而黑名单文件里通常不写端口——这时得用 %{SERVER_NAME} 替代,或在 RewriteCond 里用正则剥离端口部分。










