当 url 指向现有文件夹(无尾部斜杠)时如何重定向到 404。 HAproxy 或 mod-rewrite 相关
How to redirect to 404 when url is pointing to an existing folder (no trailing slash). HAproxy or mod-rewrite related
我正在使用监听 80 的 HAProxy 将请求发送到节点服务器(端口:3000)或 php 服务器(4000);我还安装了 CSF,它有可用的端口 3000 和 80。
当我在 http://example.com/forum/1/page.php
浏览页面时它工作正常,但有时当我不小心输入 example.com/forum/1
(没有尾部斜线)时,它一直加载并最终导致错误页面 ERR_CONNECTION_TIMED_OUT
.地址栏显示已重定向到http://example.com:4000/forum/1/
。
由于我没有打开 4000 端口,当我多次 example.com/forum/1
时,它会触发 CSF 的阻止。我的问题是,我可以将所有指向实际文件夹 example.com/forum/1
(没有尾部斜杠)的请求重定向到 404 页面吗?我已经尝试添加一个重写规则来为每个请求附加一个尾部斜杠,但这会破坏我的所有相对路径(请参阅我的问题 post)。
所以我想知道的是,为什么我从 http://example.com/forum/1
重定向到 http://example.com:4000/forum/1/
?是HAproxy引起的吗?
一些 HAproxy 配置:
frontend all 0.0.0.0:80
timeout client 1h
# use apache2 as default webserver for incoming traffic
default_backend apache2
backend apache2
balance roundrobin
option forwardfor
server apache2 myIpAddress:4000 weight 1 maxconn 1024 check
# server must be contacted within 5 seconds
timeout connect 5s
# all headers must arrive within 3 seconds
timeout http-request 3s
# server must respond within 25 seconds. should equal client timeout
timeout server 25s
这是我的重写规则:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^([^\.]+)$ .php [NC,L]
由于 /forum/1
是一个有效的物理目录,因此您被重定向到 /forum/1/
由于此设置:
DirectorySlash On
由名为 mod_dir
的模块使用,如果缺少目录,则在目录后添加尾部斜杠。
您当然可以使用以下方式关闭此标志:
DirectorySlash Off
但是be aware of security implications.
为了更安全,您还需要:
Options -Indexes
关闭目录列表。
安全警告(从链接手册复制)
关闭尾部斜杠重定向可能会导致信息泄露。考虑 mod_autoindex
处于活动状态 (Options +Indexes
) 且 DirectoryIndex
设置为有效资源(例如 index.html)并且没有为该 [= 定义其他特殊处理程序的情况53=]。在这种情况下,带有尾部斜杠的请求将显示 index.html
文件。但是没有尾部斜杠的请求会列出目录内容。
更新: 回答这部分问题:
My question is, can I redirect all the requests that are pointing to an actual folder example.com/forum/1
(no trailing slash) to an 404 page?
您可以在 /forum/1/.htaccess
:
中使用此代码
DirectorySlash On
RewriteEngine On
RewriteRule ^$ - [L,R=404]
这将强制使用尾部斜杠,以便重写规则可用于发送 404 错误。
在您的 .htaccess 文件中添加以下代码。将 /404.php 替换为您想要的任何文件。
ErrorDocument 404 /404.php
将其放在 .htaccess 的顶部
DirectorySlash Off
RewriteOptions AllowNoSlash
RewriteEngine On
RewriteCond ${REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ - [L,R=404]
DirectorySlash Off 将使目录可通过无斜线访问而无需重定向。
但问题是非斜杠版本只会简单地列出目录内容。
我为了避免这种情况,添加了 RewriteOptions AllownoSlash。
现在,当请求文件夹时不带斜线,会引发 404 错误。
我正在使用监听 80 的 HAProxy 将请求发送到节点服务器(端口:3000)或 php 服务器(4000);我还安装了 CSF,它有可用的端口 3000 和 80。
当我在 http://example.com/forum/1/page.php
浏览页面时它工作正常,但有时当我不小心输入 example.com/forum/1
(没有尾部斜线)时,它一直加载并最终导致错误页面 ERR_CONNECTION_TIMED_OUT
.地址栏显示已重定向到http://example.com:4000/forum/1/
。
由于我没有打开 4000 端口,当我多次 example.com/forum/1
时,它会触发 CSF 的阻止。我的问题是,我可以将所有指向实际文件夹 example.com/forum/1
(没有尾部斜杠)的请求重定向到 404 页面吗?我已经尝试添加一个重写规则来为每个请求附加一个尾部斜杠,但这会破坏我的所有相对路径(请参阅我的问题 post)。
所以我想知道的是,为什么我从 http://example.com/forum/1
重定向到 http://example.com:4000/forum/1/
?是HAproxy引起的吗?
一些 HAproxy 配置:
frontend all 0.0.0.0:80
timeout client 1h
# use apache2 as default webserver for incoming traffic
default_backend apache2
backend apache2
balance roundrobin
option forwardfor
server apache2 myIpAddress:4000 weight 1 maxconn 1024 check
# server must be contacted within 5 seconds
timeout connect 5s
# all headers must arrive within 3 seconds
timeout http-request 3s
# server must respond within 25 seconds. should equal client timeout
timeout server 25s
这是我的重写规则:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteCond %{REQUEST_URI} !^.*\.(jpg|css|js|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^([^\.]+)$ .php [NC,L]
由于 /forum/1
是一个有效的物理目录,因此您被重定向到 /forum/1/
由于此设置:
DirectorySlash On
由名为 mod_dir
的模块使用,如果缺少目录,则在目录后添加尾部斜杠。
您当然可以使用以下方式关闭此标志:
DirectorySlash Off
但是be aware of security implications.
为了更安全,您还需要:
Options -Indexes
关闭目录列表。
安全警告(从链接手册复制)
关闭尾部斜杠重定向可能会导致信息泄露。考虑 mod_autoindex
处于活动状态 (Options +Indexes
) 且 DirectoryIndex
设置为有效资源(例如 index.html)并且没有为该 [= 定义其他特殊处理程序的情况53=]。在这种情况下,带有尾部斜杠的请求将显示 index.html
文件。但是没有尾部斜杠的请求会列出目录内容。
更新: 回答这部分问题:
My question is, can I redirect all the requests that are pointing to an actual folder
example.com/forum/1
(no trailing slash) to an 404 page?
您可以在 /forum/1/.htaccess
:
DirectorySlash On
RewriteEngine On
RewriteRule ^$ - [L,R=404]
这将强制使用尾部斜杠,以便重写规则可用于发送 404 错误。
在您的 .htaccess 文件中添加以下代码。将 /404.php 替换为您想要的任何文件。
ErrorDocument 404 /404.php
将其放在 .htaccess 的顶部
DirectorySlash Off
RewriteOptions AllowNoSlash
RewriteEngine On
RewriteCond ${REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ - [L,R=404]
DirectorySlash Off 将使目录可通过无斜线访问而无需重定向。
但问题是非斜杠版本只会简单地列出目录内容。 我为了避免这种情况,添加了 RewriteOptions AllownoSlash。
现在,当请求文件夹时不带斜线,会引发 404 错误。