Reputation: 3042
My website has been getting vulnerability scans lately which I am not responsible of. I'm trying to block any IP that requests more than a reasonable amount of pages. I'm actually unsure of an amount maybe 4-5 requests and block them.
I've seen this done with lightspeed web servers but I have apache. How can I limit PHP requests to my pages so if a user goes over the limit they are blocked from my site for 30 minutes? (I'm really not sure what a good amount is. Something so a real user wouldn't get blocked for.)
Upvotes: 1
Views: 3697
Reputation: 2425
i use this to block custom ip-addresses, just paste in the script:
<?php
$deny = array("111.111.111", "222.222.222", "333.333.333");
if (in_array ($_SERVER['REMOTE_ADDR'], $deny)) {
header("location: http://www.mywarningpage_or_anywhereyouwouldlike.com/");
exit();
} ?>
to block someone automatically you would have to create a history of the ip's with time.
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$time = time();
$myFile = "ip_log.txt";
$fh = fopen($myFile, 'a') or die("can't open file");
$stringData = $ip.":"$time."\n";
fwrite($fh, $stringData);
fclose($fh);
to now automate let the first script get the array
$ip = $_SERVER['REMOTE_ADDR'];
$ips = file("ip_log.txt")
$count = count($ips);
for ($i=0;$i<=$count;$i++){
if (strpos($ips[$i],$ip)==true){
$teile = explode(" ", $pizza);
$ip_h[] = $teile[0]; // Teil1
$time_h[] = $teile[1]; // Teil2
}
//now you have arrays of the actual users ip with times.
// now set a timeinterval of amount of requests you define as "spam"
// and check with if for through array to deny similar like first script
written by me without testing
Upvotes: 1
Reputation: 29866
The important thing in such a solution is, that the actual "blocking" is very resource-cost inexpensive. It is also important to correctly recognise attackers and not ban someone by accident, but also don't be too open so that you already wasted lots of resources before blocking somebody.
However you are not the first one experiencing this problem.
There is a great apache module available called mod_evasive which is configured to do exactly that.
I once did a very simple technique on a server (because it worked better with that partuclar application) that had a flow like so:
My application counts up a variable in local apc cache with the key that was the current hour of the day and the user ip adress and checks whether a limit has been reached.
If so the ip adress is written into a job-log where a cronjob picked it up and added a filter using iptables so packages from that ip are just dropped.
So they dont even reach the webserver and the resources spended are minimal.
Once a day the added rules got cleared.
Upvotes: 1
Reputation: 54445
I think we all know what'll happen next (bearing in mind that each file/image, etc. is a single request).
To suggest an alternative, why not simply block the offending IP address(es) one at a time - you can presumably get the IP(s) in question from your traffic logs and it's trivial to add a "Deny from xxx.xxx.xxx.xxx
" style IP address block to your httpd config. (Additionally, unlike a PHP based approach this will apply to images, etc. as well.)
To do otherwise is liable to run the risk of blocking legitimate web traffic, Google spiders, etc.
Upvotes: 0