You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by John Karr <br...@brainbuz.org> on 2012/03/24 02:38:48 UTC

[users@httpd] allow from based on database query (2.4)

I have an application that uses both ip and credentials authentication,
currently to update the "allow from" I have to edit a file and restart the
server. My next release will be using Apache 2.4 with dbd authentication, I
was wondering if there were a way to either have apache get its' ip address
list for "allow from" from the database or to dynamically update the list
apache was using without needing to restart the server. 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] allow from based on database query (2.4)

Posted by Daniel Gruno <ru...@cord.dk>.
On 26-03-2012 16:41, brainbuz wrote:
>
> mod_gatekeeper sounds like it does exactly what I was looking for I 
> will try it.
>
I took the liberty of taking this example one step further, implementing 
it into the mod_auth group so you can use it within a Require block. The 
module in its current form can be found at 
http://people.apache.org/~humbedooh/authz_dynamic.html and the 
directives would look something like this:

# Require a line from /foo/bar/allowed_ips.txt to match the IP:
Require fromfile REMOTE_ADDR /foo/bar/allowed_ips.txt

# Or require an SQL statement to return a result. (all values are 
escaped, don't worry)
DBDriver mysql
DBDParams host=localhost,dbname=mydatabase,user=root
Require fromdb REMOTE_ADDR "SELECT `ip` FROM `ips` WHERE `ip` = '%s' 
LIMIT 1"

This new example requires mod_dbd loaded in order to work, but also 
offers the option of being able to check against a database of your 
choice for the list of IPs to allow/deny.

*Note:* This is a (personal) work in progress (or rather, it's a 
proposed solution), so there will be places that need more work in order 
to become effective, but if you just need something basic to compare IPs 
against a list or a database, it'll work better than the previous 
gatekeeper example.

With regards,
Daniel.

Re: [users@httpd] allow from based on database query (2.4)

Posted by brainbuz <br...@brainbuz.org>.
 

mod_gatekeeper sounds like it does exactly what I was looking for I
will try it. 

On 2012-03-26 03:00, Daniel Gruno wrote: 

> On
25-03-2012 00:12, JohnKarr wrote: 
> 
>> I hadn't want to mention what I
was thinking of doing as an alternative, because I really hoped that
there was a better answer that I had failed to read/find the
documentation on! 
>> 
>> My two solutions in mind were (a) the
application that maintains the ip list writes out a fresh copy of the ip
allow from config file and a cron job periodically restarts apache (b)
my stored procedure that apache uses for checking passwords takes the ip
address as an added parameter and have the database check the ip
address. I don't like (a) because it will require me to restart the
server frequently or accept a long potential delay in updates to the ip
table. I don't like (b) because I would rather a user from an
unauthorized address be completely blocked and not even redirected to
login and when working on the config I would prefer separate
queries/stored_procedures for ip and credentials.
> It's still only
early Monday morning - perhaps some wiz kid will wake up and give the
right answer soon.
> In the meantime; httpd comes with a set of modules
and directives that will satisfy 99% of the population, but there will
always be things that have either not been thought of, or are better
suited as third party modules. There is, after all, a very useful API
built into httpd that you can make use of rather easy and fast if you
have special needs for your web server. So, when in doubt, make a
module!
> 
> And so I did; I made an example module that takes a text
file (with a caching mechanism for only reading it if/when it updates),
rifles through it, and checks if an IP is on the list or not. The
example module source code can be found at
http://www.humbedooh.com/mod_gatekeeper.zip [1] and works with 2.4. The
simple directives that you can put into place are:
> 
> GKEngine on
>
GKAllow ip /foo/bar/allowed_ips.txt
> GKDeny ip
/foo/bar/denied_ips.txt
> 
> This is somewhat like writing a new
.htaccess with updated rules whenever the IP list changes, but it has
the advantage of being significantly faster in its execution since it
only reads changes to your list when they occur.
> 
> One could (and I
probably will) continue to work on this module, eventually allowing one
to make more complex requirements using mod_dbd as a database gateway,
such as:
> 
> GKAllow REMOTE_HOST in mod_dbd using "SELECT `ip` FROM
`grantedlist` WHERE `ip` = ?"
> GKAllow REMOTE_USER,REMOTE_PASSWORD in
mod_dbd using "SELECT `user` FROM `grantedusers` WHERE `user` = ? AND
`password` = MD5(?)"
> GKDeny from file /foo/bar/deny.txt
> 
> I'm
guessing this is more along the lines you had in mind? If so, I'll
likely continue to work on this module over the course of the summer,
and if it wasn't exactly what you had in mind, any input or opinions you
may have are of course very welcome either on users@, or private to
humbedooh@apache.org [2].
> 
> With regards,
> Daniel.




Links:
------
[1] http://www.humbedooh.com/mod_gatekeeper.zip
[2]
mailto:humbedooh@apache.org

Re: [users@httpd] allow from based on database query (2.4)

Posted by Nick Kew <ni...@webthing.com>.
On 26 Mar 2012, at 08:00, Daniel Gruno wrote:

> It's still only early Monday morning - perhaps some wiz kid will wake up and give the right answer soon.

I think yours looks like the right answer: it's a requirement that hasn't really
hit the mainstream, so I'm stumped for a non-hackish answer (rewritemap
as already suggested being distinctly hackish).

The other answer that might be worth googling is real-time blacklist
modules, of the kind most commonly associated with email.

-- 
Nick Kew
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org


Re: [users@httpd] allow from based on database query (2.4)

Posted by Daniel Gruno <ru...@cord.dk>.
On 25-03-2012 00:12, John Karr wrote:
>
> I hadn't want to mention what I was thinking of doing as an 
> alternative, because I really hoped that there was a better answer 
> that I had failed to read/find the documentation on!
>
> My two solutions in mind were (a) the application that maintains the 
> ip list writes out a fresh copy of the ip allow from config file and a 
> cron job periodically restarts apache (b) my stored procedure that 
> apache uses for checking passwords takes the ip address as an added 
> parameter and have the database check the ip address. I don't like (a) 
> because it will require me to restart the server frequently or accept 
> a long potential delay in updates to the ip table. I don't like (b) 
> because I would rather a user from an unauthorized address be 
> completely blocked and not even redirected to login and when working 
> on the config I would prefer separate queries/stored_procedures for ip 
> and credentials.
>
>
It's still only early Monday morning - perhaps some wiz kid will wake up 
and give the right answer soon.
In the meantime; httpd comes with a set of modules and directives that 
will satisfy 99% of the population, but there will always be things that 
have either not been thought of, or are better suited as third party 
modules. There is, after all, a very useful API built into httpd that 
you can make use of rather easy and fast if you have special needs for 
your web server. So, when in doubt, make a module!

And so I did; I made an example module that takes a text file (with a 
caching mechanism for only reading it if/when it updates), rifles 
through it, and checks if an IP is on the list or not. The example 
module source code can be found at 
http://www.humbedooh.com/mod_gatekeeper.zip and works with 2.4. The 
simple directives that you can put into place are:

<Location /foo/bar>
     GKEngine on
     GKAllow ip /foo/bar/allowed_ips.txt
     GKDeny ip /foo/bar/denied_ips.txt
</Location>
This is somewhat like writing a new .htaccess with updated rules 
whenever the IP list changes, but it has the advantage of being 
significantly faster in its execution since it only reads changes to 
your list when they occur.

One could (and I probably will) continue to work on this module, 
eventually allowing one to make more complex requirements using mod_dbd 
as a database gateway, such as:
<Location /foo>
     GKAllow REMOTE_HOST in mod_dbd using "SELECT `ip` FROM 
`grantedlist` WHERE `ip` = ?"
     GKAllow REMOTE_USER,REMOTE_PASSWORD in mod_dbd using "SELECT `user` 
FROM `grantedusers` WHERE `user` = ? AND `password` = MD5(?)"
     GKDeny from file /foo/bar/deny.txt
</Location>

I'm guessing this is more along the lines you had in mind? If so, I'll 
likely continue to work on this module over the course of the summer, 
and if it wasn't exactly what you had in mind, any input or opinions you 
may have are of course very welcome either on users@, or private to 
humbedooh@apache.org.

With regards,
Daniel.

RE: [users@httpd] allow from based on database query (2.4)

Posted by John Karr <br...@brainbuz.org>.
I hadn't want to mention what I was thinking of doing as an alternative,
because I really hoped that there was a better answer that I had failed to
read/find the documentation on!

 

My two solutions in mind were (a) the application that maintains the ip list
writes out a fresh copy of the ip allow from config file and a cron job
periodically restarts apache (b) my stored procedure that apache uses for
checking passwords takes the ip address as an added parameter and have the
database check the ip address. I don't like (a) because it will require me
to restart the server frequently or accept a long potential delay in updates
to the ip table. I don't like (b) because I would rather a user from an
unauthorized address be completely blocked and not even redirected to login
and when working on the config I would prefer separate
queries/stored_procedures for ip and credentials.

 

 

From: Daniel Gruno [mailto:rumble@cord.dk] 
Sent: Saturday, March 24, 2012 3:03 AM
To: users@httpd.apache.org
Subject: Re: [users@httpd] allow from based on database query (2.4)

 

On 24-03-2012 02:38, John Karr wrote: 

I have an application that uses both ip and credentials authentication,
currently to update the "allow from" I have to edit a file and restart the
server. My next release will be using Apache 2.4 with dbd authentication, I
was wondering if there were a way to either have apache get its' ip address
list for "allow from" from the database or to dynamically update the list
apache was using without needing to restart the server. 
 
 
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
For additional commands, e-mail: users-help@httpd.apache.org
 

I have a way, but it's not necessarily pretty, and someone should probably
shoot me for mentioning this.
What you can do, since the dawn of Man (or, since mod_rewrite), is use
RewriteMap creatively and run it through a program, that checks if the IP is
on a white-list, and if not, rewrite the URI to serve a static "forbidden!"
file. The idea is that, as you can pass on any httpd argument, header etc in
a rewrite, you can pass on both the IP and the request URI to a program,
that then splits it up, checks the IP, and if it checks out, passes back the
URI.

First off, you would need to apply something like this to your
configuration:
<Directory "/path/to/forbidden/zone">
RewriteMap checkip prg:/path/to/checkip.pl
RewriteRule - ${checkip:%{REMOTE_ADDR}:%{REQUEST_URI}}
</Directory>

You would then have a corresponding program (checkip.pl) running (httpd
takes care of running this in the background for you):
#!/usr/bin/perl
$| = 1; # Turn off I/O buffering

sub DatabaseLookup {
    #doStuffHere();
}

while (<STDIN>) { #For each incoming IP request, look it up in the db.
    ($ip, $uri)  = split(/:/); #Separate the IP and the URI in the string
httpd gave us
    
    #Run some checks here to see if the IP matches one on our list
    if (DatabaseLookup($ip) == 1) {
        print($uri); # Allow the request through, unaltered
    }
    else { # If the IP isn't on our list, then...
        print("/forbidden.html\n"); # Redirect to some static error file
    }
}

As mentioned, this is probably but one of the methods you could use, and
it's prone to be a bottleneck if you have a lot of requests going on at once
- but I've tested it and it works, so that's at least something. 

I'm done - send in the firing squad.

With regards,
Daniel.


Re: [users@httpd] allow from based on database query (2.4)

Posted by Daniel Gruno <ru...@cord.dk>.
On 24-03-2012 02:38, John Karr wrote:
> I have an application that uses both ip and credentials authentication,
> currently to update the "allow from" I have to edit a file and restart the
> server. My next release will be using Apache 2.4 with dbd authentication, I
> was wondering if there were a way to either have apache get its' ip address
> list for "allow from" from the database or to dynamically update the list
> apache was using without needing to restart the server.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@httpd.apache.org
> For additional commands, e-mail: users-help@httpd.apache.org
>
I have a way, but it's not necessarily pretty, and someone should 
probably shoot me for mentioning this.
What you can do, since the dawn of Man (or, since mod_rewrite), is use 
RewriteMap creatively and run it through a program, that checks if the 
IP is on a white-list, and if not, rewrite the URI to serve a static 
"forbidden!" file. The idea is that, as you can pass on any httpd 
argument, header etc in a rewrite, you can pass on both the IP and the 
request URI to a program, that then splits it up, checks the IP, and if 
it checks out, passes back the URI.

First off, you would need to apply something like this to your 
configuration:
<Directory "/path/to/forbidden/zone">
RewriteMap checkip prg:/path/to/checkip.pl
RewriteRule - ${checkip:%{REMOTE_ADDR}:%{REQUEST_URI}}
</Directory>

You would then have a corresponding program (checkip.pl) running (httpd 
takes care of running this in the background for you):
#!/usr/bin/perl
$| = 1; # Turn off I/O buffering

sub DatabaseLookup {
     #doStuffHere();
}

while (<STDIN>) { #For each incoming IP request, look it up in the db.
     ($ip, $uri)  = split(/:/); #Separate the IP and the URI in the 
string httpd gave us

     #Run some checks here to see if the IP matches one on our list
     if (DatabaseLookup($ip) == 1) {
         print($uri); # Allow the request through, unaltered
     }
     else { # If the IP isn't on our list, then...
         print("/forbidden.html\n"); # Redirect to some static error file
     }
}

As mentioned, this is probably but one of the methods you could use, and 
it's prone to be a bottleneck if you have a lot of requests going on at 
once - but I've tested it and it works, so that's at least something.

I'm done - send in the firing squad.

With regards,
Daniel.