How can one deny access to all subdirectories of a given directory? (While allowing to manually modify the access rights for single items in the directory tree.)
I tried to do it with the <Directory(Match)>
directives. The server configuration (000-sites-enabled) looks like this:
DocumentRoot /var/www
<Directory /var/www>
Allow from all
Deny from none
Order deny,allow
</Directory>
<Directory /var/www/*>
Deny from all
</Directory>
A query to http://localhost/
successfully displays /var/www/index.html
and all queries to any subdirectories fail.
The problem is: any query to a file in the httproot fails - i.e. requesting http://localhost/index.html
will result into 403 Forbidden
.
The <Directory(Match)>
directives seem to actually match directories AND files!?
To see if this is true, i tried:
<Directory /var/www/i*>
Deny from all
</Directory>
This denies access only to files/directories starting with 'i'.
Is there a way to alter this behaviour and let <Directory>
match only directories? Is there another way to accomplish that all the subdirectories are denied? (besides denying all of them manually or enabling all files manually)
in the end, the solution turns out to be pretty simple:
<Directory /var/www/*/>
Allow from None
Order allow,deny
</Directory>
Note the trailing slash /
after the directory pattern, which will make it match only directories, not files!
This works exactly like we would expect from the <Directory>
-directive - in that it denies access only to the direct subdirectories of /var/www/
.
Specified subdirectories (anywhere in the tree) can still manually be re-enabled with <Directory>
directives.
This is in contrast to <DirectoryMatch>
which will
- also match all files & directories in the tree and
- override all <Files>
or <Directory>
directives for any item in the tree.
This did it for me.
<DirectoryMatch "^/var/www/(.+)/"> # don't put $ at the end
Order Allow,Deny
Deny From All
</DirectoryMatch>
For not denying sub-subdirectories (comment below), add this DirectoryMatch below the one above in your configuration file:
<DirectoryMatch "^/var/www/(.+?)/(.+)/"> # again no $, see comment
Order Deny,Allow
Allow From All
</DirectoryMatch>
Use this:
<Directory /var/www/public>
allow from all
</Directory>
<DirectoryMatch "^/var/www/public/(.+)/">
deny from all
</DirectoryMatch>
You might want to add Options etc.
The trick is how the directives are merged.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With