【发布时间】:2018-02-19 20:09:21
【问题描述】:
我有一个网站在 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 下的任何内容。例如,我可以从http://hostname/img/logo.png 访问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]
或者,如果我在img 中创建一个指向../lib 的符号链接,并且仍然命名为lib,并编写此重写规则:
RewriteRule ^\/lib(\/.*)$ /img/lib/$1 [L]
一切都像一个魅力。没有 403。只有 200。
更糟糕的是,此错误在 Windows 或 Raspberry Pi Zero W 上的 Raspbian 上不存在(请参阅更新 3)。在将它们上传到 Amazon EC2 之前,我在 Windows 和 Raspberry Pi Zero W(参见更新 3)上测试了我的重写规则,只是为了找到这个奇怪的错误。
我还检查了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 更新到解决此错误的较新版本(不起作用,请参阅更新 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
更新 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
更新 2
apache2.conf中有这么几行:
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
我认为/lib 被拒绝是因为它是/ 的一部分,所以我将其修改为:
<Directory />
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
并重新启动 Apache2。仍然没有运气。 403 禁止。
更新 3
重新检查 Raspbian。使用 Raspbian Pi Zero W 的 Raspbian 也出现了同样的问题。
可能是因为浏览器缓存没问题。我的错。现在我认为这不是 Ubuntu 特有的错误,而是 Linux 特有的错误。
【问题讨论】:
标签: apache .htaccess ubuntu mod-rewrite ubuntu-16.04