26

I am running CentOS 5.5 with the stock Apache httpd-2.2.3.

I have enabled mod_status at the Location /server-status. I would like to allow access to this single Location in the following way:

  1. Deny from all
  2. Allow from the subnet 192.168.16.0/24
  3. Deny from a the IP 192.168.16.100, which is within the 192.168.16.0/24 subnet.

1 & 2 are easy. However, since I "Allow from 192.168.16.0/24", is it possible to Deny from 192.168.16.100?

I tried to add a Deny statement for 192.168.16.100 but it doesn't work. Here is the relevant config:

<Location /server-status> SetHandler server-status Order Allow,Deny Deny from all Deny from 192.168.16.100 # This does not deny access from 192.168.16.100 Allow from 192.168.16.0/24 </Location> 

Or:

<Location /server-status> SetHandler server-status Order Allow,Deny Deny from all Deny from 192.168.16.100 # This does not deny access from 192.168.16.100 Allow from 192.168.16.0/24 </Location> 

However, this doesn't prevent access to this particular page, as demonstrated in the Access logs:

www.example.org 192.168.16.100 - - [11/Mar/2011:16:01:14 -0800] "GET /server-status HTTP/1.1" 200 9966 "-" " 

According to the manual for mod_authz_host:

Allow,Deny

First, all Allow directives are evaluated; at least one must match, or the request is rejected. Next, all Deny directives are evaluated. If any matches, the request is rejected

The IP address matches the Deny directive, so shouldn't the request be rejected?

According to the table on the mod_authz_host page, this IP address should "Match both Allow & Deny", and thus the "Final match controls: Denied" rule should apply.

 Match Allow,Deny result Deny,Allow result Match Allow only Request allowed Request allowed Match Deny only Request denied Request denied No match Default to second directive: Denied Default to second directive: Allowed Match both Allow & Deny Final match controls: Denied Final match controls: Allowed 
5
  • Deny from all 192.168.16.100 -- Since you are using "all" here, I would expect all requests to be denied from any IP address. Think something else is going on here. Commented Apr 6, 2011 at 19:48
  • @Michah: I am also doing a Allow from 192.168.16.0/24. As I understand the documentation, any requestor IPs in the 192.168.16.0/24 network will match this Allow statement, the request is allowed. Commented Apr 6, 2011 at 20:34
  • Following the documentation pasted above. "First, all Allow directives are evaluated; at least one must match, or the request is rejected" ==> This should match your "Allow from 192.168.16.0/24", but the second part of "Next, all Deny directives are evaluated. If any matches, the request is rejected" With "Deny from all", won't every request match that second part and therefore be denied? Commented Apr 11, 2011 at 15:10
  • You should really consider if you want to deny that IP address complete access to your system or only from httpd. If the former continue with your approach at using apache directives. If the latter this should be done in the firewall. Commented Oct 7, 2011 at 17:20
  • Thanks ACase. I only want to deny access from 192.168.16.100to this particular page. I want 192.168.16.100 to be able to access all other pages on this webserver. Commented Oct 7, 2011 at 19:01

3 Answers 3

36

I haven't tested, but I think you are almost there.

<Location /server-status> SetHandler server-status Order Allow,Deny Deny from 192.168.16.100 Allow from 192.168.16.0/24 </Location> 

Deny from all is not needed. In fact it will screw up because everything will match all, and thus denied (and I think Apache is trying to be smart and do something stupid). I have always found Apache's Order, Allow and Deny directives confusing, so always visualize things in a table (taken from the docs):

 Match | Allow,Deny result | Deny,Allow result ------------------------------------------------------- Allow only | Allowed | Allowed Deny only | Denied | Denied No match | Default: Denied | Default: Allowed Match both | Final match: Denied | Final match: Allowed 

With the above settings:

  • Requests from 192.168.16.100 get "Match both" and thus denied.
  • Requests from 192.168.16.12 get "Allow only" and thus allowed.
  • Requests from 123.123.123.123 get "No match" and thus denied.
0
1

I would probably look at also adding IPTables rules for this to deny the single host on port 80, deny from all, and allow the subnet.

You should have no problem setting up a deny rule from a specific address after you have allowed the subnet. Just do it in that order.

4
  • I've updated my answer. I included a "Deny from 192.168.16.100" rule, but access is still allowed from 192.168.16.100 Commented Mar 11, 2011 at 20:57
  • I want to allow access to all other locations from this host. However, I want to Deny specific locations. IPTables does not help me here. Commented Mar 11, 2011 at 21:00
  • IPTables will not specifically deny outbound traffic unless you tell it to. You can however, deny inbound traffic from world, and a specific address, but all allow a subnet. Commented Mar 11, 2011 at 21:29
  • I think you misunderstand my request. I want to apply this access control to /server-status only, not the entire host. IPtables cannot do this easily, to my knowledge. Commented Apr 5, 2011 at 15:23
-4

Can you use php? If so add a php statement to exit/redirect for that one specific IP address

Example:

$deny = array("111.111.111", "222.222.222", "333.333.333");

if (in_array ($_SERVER['REMOTE_ADDR'], $deny))

{ header("location: http://www.google.com/");

exit();

Reference: http://perishablepress.com/press/2007/07/03/how-to-block-ip-addresses-with-php/

1
  • 2
    This would have to be in every single page hosted by the webserver. This solution is impractical and not where you would want to filter access to a webserver. Commented Oct 7, 2011 at 17:18

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.