Apache .htaccess/virtualhost动态阻止列表+;错误文档

Apache .htaccess/virtualhost动态阻止列表+;错误文档,apache,.htaccess,mod-rewrite,virtualhost,Apache,.htaccess,Mod Rewrite,Virtualhost,我目前有一个多站点虚拟主机,我已经设置了一些通用错误文档,每个域都可以重置这些文档。我也有一个黑名单重写,但我试图设置一个自定义错误条件,如果一个IP被阻止,然后显示一个自定义错误页面 <Virtualhost *:80> ServerName catchall.host ServerAlias * VirtualDocumentRoot /var/www/hosts/%0 Alias /cloud-cgi /var/www/cloud-cgi

我目前有一个多站点虚拟主机,我已经设置了一些通用错误文档,每个域都可以重置这些文档。我也有一个黑名单重写,但我试图设置一个自定义错误条件,如果一个IP被阻止,然后显示一个自定义错误页面

<Virtualhost *:80>
    ServerName catchall.host
    ServerAlias *
    VirtualDocumentRoot /var/www/hosts/%0
    Alias /cloud-cgi /var/www/cloud-cgi
    SetEnv DIRECT_ACCESS no
    HttpProtocolOptions Unsafe

    RewriteEngine On
    RewriteMap access txt:/var/www/blacklist.txt
    RewriteCond ${access:%{REMOTE_ADDR}} deny [NC]
    RewriteRule ^ "/cloud-cgi/error_handler.php" [R=404,L]

    RemoteIPHeader CF-Connecting-IP
    CustomLog /var/www/catchall_access.log combined
    ErrorLog /var/www/catchall_error.log
</Virtualhost>
在vhost中,您可以看到黑名单,在黑名单中,如果满足重写条件,则尝试将浏览器重定向到HTTP代码404的
/cloud cgi/error_handler.php

出于某种原因,当我尝试这一点时,我得到的不是定制的ErrorDocument,而是默认的Apache文档。如何触发其中一个HTTP错误,并重定向到ErrorDocument。如果我可以用一个值设置一个环境变量,这样处理程序就可以设置一个自定义消息,那将非常好。我也尝试从vhost定义中设置错误文档,但没有成功

我遗漏了什么吗?

正如我所说。。。尝试将
RewriteRule^”/cloud cgi/error\u handler.php“[R=404,L]
更改为
RewriteRule^-[R=404,L]

重写规则使它看起来不存在errorhandler文件。因此,由于apache无法访问errorhandler文件,因此它显示了默认文件。您还应该在默认错误页面中看到一个通知,上面写着类似的内容。此外,在尝试使用ErrorDocument处理请求时遇到了404 Not Found错误。

如前所述。。。尝试将
RewriteRule^”/cloud cgi/error\u handler.php“[R=404,L]
更改为
RewriteRule^-[R=404,L]

重写规则使它看起来不存在errorhandler文件。因此,由于apache无法访问errorhandler文件,因此它显示了默认文件。您还应该在默认的错误页面中看到一个通知,如另外,在尝试使用ErrorDocument处理请求时遇到404 Not Found错误。

…尝试使用HTTP代码404将浏览器重定向到
/cloud cgi/error\u handler.php

如果指定的HTTP状态代码的
R
标志超出3xx范围,则替换字符串将被忽略(不会发生替换)。在这种情况下,最好只包含连字符(
-
)作为替换字符串,以明确表示不打算进行替换

当您指定
R=404
时,Apache会触发404响应(通过内部子请求),并将调用自定义的404
ErrorDocument

但是,定义的错误文档本身需要是可访问的。在您发布的指令中,当用户IP地址位于黑名单上时,对
/cloud cgi/error\u handler.php
本身的请求也会触发404响应,因此无法显示自定义错误文档。Apache退回到Apache默认设置(并抱怨定制错误文档触发了404甚至500响应,具体取决于您使用这些指令的位置)

要使其可访问,您可以:

包括一个特定的异常 在规则中包含异常,以排除对特定错误文档的请求。例如:

 RewriteRule !^/cloud-cgi/error_handler.php - [R=404]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ - [R=404]
<Files error_handler.php>
Require all granted
</Files>
RewriteRule ^ - [E=MYVAR:Message,R=404]
(当指定非3xx响应代码时,
L
标志不是必需的;它是隐含的。)

包括一个通用异常 或者,更一般地说,防止在已触发错误响应时触发规则。这可以通过检查
REDIRECT\u STATUS
环境变量来实现,该变量在触发错误文档后设置为HTTP响应代码。例如:

 RewriteRule !^/cloud-cgi/error_handler.php - [R=404]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ - [R=404]
<Files error_handler.php>
Require all granted
</Files>
RewriteRule ^ - [E=MYVAR:Message,R=404]
在上面,我们只是检查
REDIRECT\u STATUS
env var是否为空。(旁白:这种技术在LiteSpeed服务器上不起作用,因为在请求到错误状态的过程中,
REDIRECT_STATUS
env var没有更新。)

允许公众访问错误文档 但也可能有其他指令需要触发错误文档

或者,使用mod_authz_core允许公共访问。例如:

 RewriteRule !^/cloud-cgi/error_handler.php - [R=404]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ - [R=404]
<Files error_handler.php>
Require all granted
</Files>
RewriteRule ^ - [E=MYVAR:Message,R=404]
内部重写 或者,您可以在内部将请求重写为自定义错误文档。但是您现在必须在PHP脚本中设置404响应代码(理想情况下,如果直接请求错误文档,您仍然需要这样做-不太可能,但并非不可能):

一些可以由每个域重置的通用错误文档

这里的问题是,如果每个域都重置了它们,那么上面包含的特定异常将不再有效。您可以为所有错误文档指定一个特定的子目录,只需允许不受限制地访问该目录即可

如果我可以用一个值设置一个环境变量,这样处理程序就可以设置一个自定义消息,那将非常好

您可以在相同的
RewriteRule
指令中设置环境变量。例如:

 RewriteRule !^/cloud-cgi/error_handler.php - [R=404]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^ - [R=404]
<Files error_handler.php>
Require all granted
</Files>
RewriteRule ^ - [E=MYVAR:Message,R=404]
上面将env var
MYVAR
设置为值
Message
。如果消息文本包含空格,则将整个flags参数用双引号括起来。(尽管我会将您的特定错误文本留给
error\u handler.php
,并在此处设置一个简短的代码或标志。)

…尝试使用HTTP代码404将浏览器重定向到
/cloud cgi/error\u handler.php

如果指定的HTTP状态代码的
R
标志超出3xx范围,则替换字符串将被忽略(不会发生替换)。在这种情况下,最好只包含连字符(
-
)作为替换字符串,以明确表示不打算进行替换

当您指定
R=404
时,Apache会触发404响应(通过内部子请求),并将调用自定义的404
ErrorDocument

但是,定义的错误文档本身需要是可访问的。在