I started a new thread so as not to interrupt the discussion on Gustaf's excellent throttling module.
In summary, here is my original question:
My web page stats (of my personal site) show something quite interesting.
/register/ receives over 4000 hits a month, but I have less than 20 registered users in over 1 year.
And my site allows anonymous comments, so it's not because people are being thrown to /register/ and leaving.
So I'm assuming that people are hitting my registration page with automated username/password robots trying to brute force their way in.
My proposed solution is to detect > x hits to /register/ from an individual ip address within y minutes, and block that ip for y hours.
My needs were somewhat simpler than Gustaf's, so here's what I came up with.
I basically nsv_incr a global nsv with the peeraddr as the key, then I have a scheduled proc decrementing the number of tries every 5 minutes.
If the try count hits zero then the key is nsv_unset.
in a -proc.tcl somewhere:
ad_proc decrease_registerips {} {} {
foreach key [nsv_array names registerips] {
set tries [nsv_incr registerips $key -5]
if {$tries < 1} {
nsv_unset registerips $key
}
}
}
in a -init.tcl somewhere:
nsv_set registerips "127.0.0.1" 0
ad_schedule_proc 300 decrease_registerips
to create the nsv and schedule the cleanup. Finally, put this in acs-subsite/www/register/index.tcl:
set user_ip [ad_conn peeraddr]
# get peer address from ad_conn or header if behind a local proxy
if {[string match $user_ip "127.0.0.1"]} {
set user_ip [lindex [ns_set iget [ns_conn headers] x-forwarded-for] end]
}
if {[nsv_exists registerips $user_ip]} {
set tries [nsv_incr registerips $user_ip]
} else {
nsv_set registerips $user_ip 0
set tries 0
}
if {$tries > 5} {
ad_return_error "Access error" "Too many loads of /register. Please try again later"
}
You will need to adjust if you are behind a proxy not on 127.0.0.1. You can also add this code to other pages - you should then probably increase the allowed count (or use a seperate nsv).
I think something along these lines would be useful in the standard acs-subsite, with the number of tires per 5 minutes as a parameter (and more robust proxy detecting).
Opinions?