Well, I made a script to process it only for basic requests (without session requests or other requests that do not call the kernel). If you look at google, you will find scripts / classes that will kill your server due to heavy loads every time. The fact that many use SESSIONS and, possibly, ALSO SQL / Database, will allow you to get flood protection as a killer server. Also, the fact that SESSIONs need a Cookie (or GET SID) so you can easily manage SESSIONs to get a new SESSION identifier.
My function is text based and does simple processing. The bad news is that you may have to use CronJob to remove ips from time to time. Compared to other scenarios, it is about 10 * faster (and more than sessions).
I don’t know if this is really useful .;) You might want to change the rpm value to a lower one or /, and also to 200 req. My parameter is a ban for a bot that performs interval requests in <= 6 seconds.
<?php function ht_request_limiter() { if (!isset($_SERVER['REMOTE_ADDR'])) { return; } // Maybe its impossible, however we check it first if (empty($_SERVER['REMOTE_ADDR'])) { return; } // Maybe its impossible, however we check it first $path = '/your/path/ipsec/'; // I use a function to validate a path first and return if false... $path = $path.$_SERVER['REMOTE_ADDR'].'.txt'; // Real file path (filename = <ip>.txt) $now = time(); // Current timestamp if (!file_exists($path)) { // If first request or new request after 1 hour / 24 hour ban, new file with <timestamp>|<counter> if ($handle = fopen($path, 'w+')) { if (fwrite($handle, $now.'|0')) { chmod($path, 0700); } // Chmod to prevent access via web fclose($handle); } } else if (($content = file_get_contents($path)) !== false) { // Load existing file $content = explode('|',$content); // Create paraset [0] -> timestamp [1] -> counter $diff = (int)$now-(int)$content[0]; // Time difference in seconds from first request to now if ($content[1] == 'ban') { // If [1] = ban we check if it was less than 24 hours and die if so if ($diff>86400) { unlink($path); } // 24 hours in seconds.. if more delete ip file else { header("HTTP/1.1 503 Service Unavailable"); exit("Your IP is banned for 24 hours, because of too many requests."); } } else if ($diff>3600) { unlink($path); } // If first request was more than 1 hour, new ip file else { $current = ((int)$content[1])+1; // Counter + 1 if ($current>200) { // We check rpm (request per minute) after 200 request to get a good ~value $rpm = ($current/($diff/60)); if ($rpm>10) { // If there was more than 10 rpm -> ban (if you have a request all 5 secs. you will be banned after ~17 minutes) if ($handle = fopen($path, 'w+')) { fwrite($handle, $content[0].'|ban'); fclose($handle); // Maybe you like to log the ip once -> die after next request } return; } } if ($handle = fopen($path, 'w+')) { // else write counter fwrite($handle, $content[0].'|'.$current .''); fclose($handle); } } } }
Edit: my way to check request time was with microtime and simulate 10'000 users. I ask google and tested (as an example) http://technitip.net/simple-php-flood-protection-class
So I don’t know what should be there simply? You have about 3 SQL queries at a time, for example:
$this -> user_in_db($ip)) $this->user_flooding($ip); $this->remove_old_users();
You may have more features, but all legitimate users do not use servertime .;)
7three
source share