LeonardChallis
LeonardChallis

Reputation: 7783

Why is my apache Directory config being ignored?

I have sections of several sites IP restricted using a Directory match rule. Now, I want to allow a new IP have access to just one of those sites.

The secured folders are an admin directoy (always /admin), a few random secure folders and WordPress admin areas if that site happens to have a blog. They <Directory ~> directive is as follows:

<Directory ~ "^/var/www/vhosts/[^/]+/public/((securefolder1)|(securefolder2)|((blog/)?wp\-)?admin)">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333
</Directory>

I tried to allow the new IP address to a specific WordPress admin area by adding this directive after the above one:

<Directory "/var/www/vhosts/foo.com/public/wp-admin">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333 444.444.444.444
</Directory>

Although the original IPs still work, the new IP is still blocked from viewing. I was wondering if it was to do with the order they are merged in, so I changed <Directory> to <Directory ~> for the foo.com directive but it still doesn't work. I also tried moving it to come after the other directive with no effect.

How can I override the IP restriction for this one site?

Note: .htaccess solutions are acceptable if that's possible.

Apache version is 2.2.15

Upvotes: 1

Views: 904

Answers (1)

Tony Chiboucas
Tony Chiboucas

Reputation: 5683

It is a merge order issue

Just as you suspected, it DOES have "to do with the order they are merged in."

processed in the order shortest directory component to longest. So for example, <Directory /var/web/dir> will be processed before <Directory /var/web/dir/subdir>.

Use the Apache merge order carefully

If you take a second look at those docs, you'll notice:

The order of merging is:

  1. <Directory> (except regular expressions) and .htaccess done simultaneously (with .htaccess, if allowed, overriding <Directory>)
  2. <DirectoryMatch> (and <Directory ~>)
  3. <Files> and <FilesMatch> done simultaneously
  4. <Location> and <LocationMatch> done simultaneously

...Which means you can do any one of a number of things:

  1. Create the foo.com Directory entry as a Directory Match
  2. Adjust the Directory paths (with some clever regex) such that the foo.com entry is LONGER than the main entry.
  3. Define access with Files or Location entries (a little trickier, but still doable.

For your case, it may be as simple as:

# regex not allowed here, adjust accordingly (three separate directory entries)
<Directory "^/var/www/vhosts/[^/]+/public/((securefolder1)|(securefolder2)|((blog/)?wp\-)?admin)">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333
</Directory>

<Directory ~ "/var/www/vhosts/foo.com/public/wp-admin">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333 444.444.444.444
</Directory>

Improved solution

# This should be reflective of the url
<Location ~ "^/((securefolder1)|(securefolder2)|((blog/)?wp\-)?admin)">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333
</Location>

<Directory "/var/www/vhosts/foo.com/public/wp-admin">
  AllowOverride All
  Order Deny,Allow
  Deny from all
  Allow from 111.111.111.111 222.222.222.222 333.333.333.333 444.444.444.444
</Directory>

Note, if these are shared servers, an users are allowed to write their own .htaccess file, that COULD override the Location directive by changing the url to access the files. In such a case the only remaining solutions are the previous <Directory> example, or using VHosts directives.

Upvotes: 2

Related Questions