The root directory of my website is:
/var/www/html/www
So there is such a line in my 000-default.conf:
DocumentRoot /var/www/html/www
I have directories under the document root directory. The full path of the directories are:
/var/www/html/www/img
/var/www/html/www/lib
There are some css and js files in lib. For example:
/var/www/html/www/lib/customized.css
There was no problem at all, until I started to use Apache Rewrite (mod_rewrite).
If I rewrite for /var/www/html/www/img, it is fine. For example:
RewriteRule ^\/img\/.*$ $0 [L]
After writing the line above, I can still access anything under img. For example, I could access img/logo.png from http://hostname/img/logo.png.
However, if I want to do the same thing for /var/www/html/www/lib, either adding:
RewriteRule ^\/lib\/.*$ $0 [L]
or changing the existing line to
RewriteRule ^\/(img|lib)\/.*$ $0 [L]
Everything under lib becomes inaccessible. I will get:
403 Forbidden
for anything under lib (full path: /var/www/html/www/lib).
This seem to happen only for directories named lib directly under the document root directory. If I create a symlink pointing to lib but named lib2, and write this rewrite rule:
RewriteRule ^\/lib(\/.*)$ /lib2/$1 [L]
or, if I create a symlink pointing to ../lib in img and still named lib, and write this rewrite rule:
RewriteRule ^\/lib(\/.*)$ /img/lib/$1 [L]
Everything works like a charm. No 403. Only 200.
To make it worse, this bug does not exist on Windows. This bug happen only on Linux. I tested Ubuntu Linux 16.04.3 with Apache 2.4.18 and the latest 2.4.29 and Raspbian with Apache 2.4.25. All three versions have this bug.
I’ve also checked the error.log, and found this for accessible case (files under img, unrelated info omitted):
[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]
And, this for inaccessible case (files under lib, unrelated info omitted):
[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
It seems that, mod_rewrite failed to prefix with document_root, if the directory is having a same name as another directory under the root directory. For my case, it is lib having the same name as /lib.
So I created a directory named img under the root directory, thus /img, and boom! Files under img (full path: /var/www/html/www/img) became inaccessible, too!
My current solution is to create a link under /var/www/html/www named lib2 and rewrite like this:
RewriteRule ^\/lib(\/.*)$ /lib2/$1 [L]
I think this is a bug of Apache. Is there any better solution than this? Could anyone please help me on this? Thanks in advance.