Apache .htaccess/virtualhost动态阻止列表+;错误文档
我目前有一个多站点虚拟主机,我已经设置了一些通用错误文档,每个域都可以重置这些文档。我也有一个黑名单重写,但我试图设置一个自定义错误条件,如果一个IP被阻止,然后显示一个自定义错误页面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
<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响应(通过内部子请求),并将调用自定义的404ErrorDocument
但是,定义的错误文档本身需要是可访问的。在您发布的指令中,当用户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 varMYVAR
设置为值Message
。如果消息文本包含空格,则将整个flags参数用双引号括起来。(尽管我会将您的特定错误文本留给error\u handler.php
,并在此处设置一个简短的代码或标志。)
…尝试使用HTTP代码404将浏览器重定向到/cloud cgi/error\u handler.php
如果指定的HTTP状态代码的R
标志超出3xx范围,则替换字符串将被忽略(不会发生替换)。在这种情况下,最好只包含连字符(-
)作为替换字符串,以明确表示不打算进行替换
当您指定R=404
时,Apache会触发404响应(通过内部子请求),并将调用自定义的404ErrorDocument
但是,定义的错误文档本身需要是可访问的。在