Apache Rewrite(mod_rewrite)无法重写,如果目录名与root下的另一个目录相同,例如Linux上的“lib”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Apache Rewrite(mod_rewrite)无法重写,如果目录名与root下的另一个目录相同,例如Linux上的“lib”相关的知识,希望对你有一定的参考价值。
我在Amazon EC2上有一个运行在Ubuntu 16.04.3上的网站。这是uname -a
的结果
Linux ip-172-31-34-232 4.4.0-1050-aws #59-Ubuntu SMP Tue Jan 30 19:57:10 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
我的网站的根目录是:
/var/www/html/www
所以我的000-default.conf中有这样一行:
DocumentRoot /var/www/html/www
我在根目录中有一个名为lib
的目录。目录的完整路径是:
/var/www/html/www/lib
其中有一些css和js文件。例如:
/var/www/html/www/lib/customized.css
完全没有问题,直到我开始使用Apache Rewrite(mod_rewrite)。
如果我不写任何重写规则,那很好。可以从lib/customized.css
访问http://hostname/lib/customized.css
,HTTP状态代码为200,这意味着一切正常。
如果我重写其他目录,那很好。例如:
RewriteRule ^\/img\/.*$ $0 [L]
写完上面的这一行之后,我仍然可以在img
下访问任何内容。例如,我可以从img/logo.png
访问http://hostname/img/logo.png
。
但是,如果我想为lib
做同样的事情,要么添加:
RewriteRule ^\/lib\/.*$ $0 [L]
或将现有行更改为
RewriteRule ^\/(img|lib)\/.*$ $0 [L]
lib
下的一切都变得无法进入。我会得到:
403 Forbidden
在lib
(完整路径:/var/www/html/www/lib
)下的任何事情。
这似乎只发生在文档根目录下直接名为lib
的目录中。如果我创建一个指向lib
但名为lib2
的符号链接,并编写此重写规则:
RewriteRule ^\/lib(\/.*)$ /lib2/$1 [L]
或者,如果我在../lib
中创建一个指向img
并仍然命名为lib
的符号链接,并编写此重写规则:
RewriteRule ^\/lib(\/.*)$ /img/lib/$1 [L]
一切都像魅力一样。没有403.只有200。
更糟糕的是,Windows上不存在此错误 或Raspberry Pi Zero W上的Raspbian (见更新3)。我在两个Windows上测试了我的重写规则 和Raspberry Pi Zero W (请参阅更新3)然后将它们上传到Amazon EC2,只是为了找到这个奇怪的错误。
我还检查了error.log
,发现这是可访问的情况(img
下的文件,省略了无关的信息):
[rid#7fc9349cc0a0/initial] init rewrite engine with requested uri /img/logo.png
[rid#7fc9349cc0a0/initial] applying pattern '^\\/(img|lib)\\/.*$' to uri '/img/logo.png'
[rid#7fc9349cc0a0/initial] rewrite '/img/logo.png' -> '/img/logo.png'
[rid#7fc9349cc0a0/initial] local path result: /img/logo.png
[rid#7fc9349cc0a0/initial] prefixed with document_root to /var/www/html/www/img/logo.png
[rid#7fc9349cc0a0/initial] go-ahead with /var/www/html/www/img/logo.png [OK]
并且,这是无法访问的情况(lib
下的文件,省略了无关的信息):
[rid#7fc9349ce0a0/initial] init rewrite engine with requested uri /lib/zenscroll-4.0.0/zenscroll-min.js
[rid#7fc9349ce0a0/initial] applying pattern '^\\/(img|lib)\\/.*$' to uri '/lib/zenscroll-4.0.0/zenscroll-min.js'
[rid#7fc9349ce0a0/initial] rewrite '/lib/zenscroll-4.0.0/zenscroll-min.js' -> '/lib/zenscroll-4.0.0/zenscroll-min.js'
[rid#7fc9349ce0a0/initial] local path result: /lib/zenscroll-4.0.0/zenscroll-min.js
[rid#7fc9349ce0a0/initial] go-ahead with /lib/zenscroll-4.0.0/zenscroll-min.js [OK]
[rid#7fc9349ca790/initial/redir#1] init rewrite engine with requested uri /error.php
...
... (error.php is a customized ErrorDocument, omitted)
...
[authz_core:error] [pid 13179] [client 61.149.87.39:57002] AH01630: client denied by server configuration: /lib/zenscroll-4.0.0
似乎mod_rewrite
未能使用document_root作为前缀,如果该目录与根目录下的另一个目录具有相同的名称。对于我的情况,它是lib
与/lib
同名。
所以我在根目录下创建了一个名为img
的目录,因此/img
和繁荣! img
(完整路径:/var/www/html/www/img
)下的文件也变得无法访问!
我目前的解决方案是在/var/www/html/www
下创建一个名为lib2
的链接并重写如下:
RewriteRule ^\/lib(\/.*)$ /lib2/$1 [L]
我不想重命名lib
目录,因为一切都适用于Windows
和Raspbian
(见更新3)。还有其他解决方案吗?例如,我可以:
- 将Ubuntu上的apache更新为解决此bug的较新版本 (不工作,见更新1),或
- 告诉apache他们应该在实际尝试访问
/lib
之前加前缀?
Ubuntu上的Apache(版本号似乎有点过时,但我不知道如何升级到比Ubuntu提供的版本更新的版本):
Package: apache2
Status: install ok installed
Priority: optional
Section: httpd
Installed-Size: 489
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 2.4.18-2ubuntu3.5
Raspbian上的Apache:
Package: apache2
Status: install ok installed
Priority: optional
Section: httpd
Installed-Size: 577
Maintainer: Debian Apache Maintainers <debian-apache@lists.debian.org>
Architecture: armhf
Version: 2.4.25-3+deb9u3
Windows上的Apache:
AH00455: Apache/2.4.27 (Win32) OpenSSL/1.0.2l PHP/7.1.9 configured -- resuming normal operations
AH00456: Apache Lounge VC14 Server built: Jul 9 2017 11:48:22
UPDATE 1
通过ppa:ondrej / apache2将Apache更新到2.4.29,但没有运气。它仍然存在与Windows相同的问题 和Raspbian (见更新3)没有。
Package: apache2
Status: install ok installed
Priority: optional
Section: httpd
Installed-Size: 504
Maintainer: Debian Apache Maintainers <debian-apache@lists.debian.org>
Architecture: amd64
Version: 2.4.29-2+ubuntu16.04.1+deb.sury.org+2
UPDATE 2
apache2.conf中有这样的行:
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
我认为/lib
被拒绝,因为它是/
的一部分,所以我将其修改为:
<Directory />
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
并重新启动Apache2。仍然没有运气。 403禁止。
UPDATE 3
重新检查Raspbian。 Raspberry Pi Zero W在Raspbian上发生了同样的问题
可能由于浏览器缓存而没问题。我的错。现在我认为这不是特定于Ubuntu的bug,而是针对Linux的。
默认情况下,RewriteRule中的目标(或替换字符串)被假定为文件路径。使用[PT]标志会将其视为URI。
默认情况下,重写目标假定为URI之前的第一个文件路径(绝对路径)(DocumentRoot的相对路径)。因此,最终的解决方案是在重写规则中使用[PT]标志:
RewriteRule ^\/(img|lib)\/.*$ $0 [PT]
它现在有效!
[L]不再需要,因为[PT]暗示[L]。
以上是关于Apache Rewrite(mod_rewrite)无法重写,如果目录名与root下的另一个目录相同,例如Linux上的“lib”的主要内容,如果未能解决你的问题,请参考以下文章
如果 .htaccess 使用 mod_rewrite,则 Apache httpd.conf mod_rewrite 取消
Debian/Ubuntu下安装Apache的Mod_Rewrite模块的步骤