Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Antiflood (WingedFox)
Author Message
WingedFox
Профессионал



Joined: 29 Apr 2003
Posts: 4064
Карма: 268
   поощрить/наказать

Location: Питер

PostPosted: Thu May 01, 2003 5:35 pm (написано за 16 секунд)
   Post subject: Antiflood
Reply with quote

Здравствуйте!

Небольшой класс для простой защиты сайта.
Code (php): скопировать код в буфер обмена
<?php
//
// on start it tries to create /deflood/ folder in the site root, if it doesn't exists
//
//
//  NOTE: Only first matched rule applies!
//

$def = new deflood();
unset (www.php.net/unset) ($def);
/**
* @author  Ilya Lebedev <ilya@lebedev.net>
* @version 0.5
* @package Deflood
*/

class deflood {
/**
*  Configuration array
*  @access private
*  @var array
//  start IP : required
//  end IP   : optional, same to start IP if doesn't exists
//  action   : allow/deny
//  sym.thr. : number of simulatenious threads. 0 = do not check
//  time     : time period when that rule applies. 0 = do not check
//  penalty  : number of seconds to be added to timeout when rule is breached
*/

//*************************************************************************
//                        | start IP       | end IP          | action | thr. | time | penalty
var $a_cfg = array (www.php.net/array) (array (www.php.net/array)("0.0.0.0",       "255.255.255.255","allow", "10""1",   "5"),
                   );


/**
*  Headers
*  @access private
*  @var array
*/

    var $resp = array (www.php.net/array) (1 => array (www.php.net/array) ("HTTP/1.1 408 Request Time-out",
                                   "<h3>Request Time-out</h3>Please, try again later."),
                            array (www.php.net/array) ("HTTP/1.1 403 Forbidden",
                                   "<h3>You're not welcome here</h3>"),
                            array (www.php.net/array) ("HTTP/1.1 500 Server is busy",
          "<h3>Server is busy</h3>We are unable to service your request now."),
                      );
/**
*  .htaccess content.
*  @access private
*  @var string
*/

    var $htaccess = "Order Allow,Deny\nDeny from all";
/**
*  Access rights for new files and /deflood/ folder.
*  @access private
*  @var integer
*/

    var $chmod = 0777;
/**
*  Name of the folder where IP data is stored
*  @access private
*  @var string
*/

    var $rootDir = "/deflood";
/**
*  Constructor =)
*  @access public
*  @return void
*/

    function deflood () {
       $this->rootDir = $GLOBALS["DOCUMENT_ROOT"].$this->rootDir;
           if (!file_exists (www.php.net/file_exists)($this->rootDir)) {
           mkdir (www.php.net/mkdir)($this->rootDir);
           chmod (www.php.net/chmod) ($this->rootDir,$this->chmod);
           $fd = fopen (www.php.net/fopen) ($this->rootDir."/.htaccess","w");
           if ($fd) {
               fwrite (www.php.net/fwrite) ($fd,$this->htaccess);
               chmod (www.php.net/chmod) ($this->rootDir,$this->chmod);
               fclose (www.php.net/fclose) ($fd);
           }
       }
       $uip  = $this->fetchip();            //get real IP;
       $fname = $this->rootDir."/".$uip;
       $fd = @fopen (www.php.net/fopen) ($fname."_busy","a+");
       if (@flock (www.php.net/flock)($fd,LOCK_EX|LOCK_NB)) {
           chmod (www.php.net/chmod) ($fname."_busy",$this->chmod);
           $res = 0;
       } else {
           $res = 3;
       }
       $i = 0;
       $num = sizeof (www.php.net/sizeof)($this->a_cfg);
       while ($i<$num && !$res) {
           $res = $this->checkrule ($i,$uip);
           $i++;
       }
       @fclose (www.php.net/fclose) ($fd);
       @unlink (www.php.net/unlink) ($fname."_busy");
       if ($res>0) {
           header (www.php.net/header) ($this->resp[$res][0]);
           echo (www.php.net/echo) ($this->resp[$res][1]);
           exit (www.php.net/exit);
       }
    }

/**
*  The method to prepare current rule for check
*  @access private
*  @return integer
*/

    function checkrule ($rnum,$uip) {
        $sip  = $this->a_cfg[$rnum][0];
        $eip  = $this->a_cfg[$rnum][1]==""?$this->a_cfg[$rnum][0]:$this->a_cfg[$rnum][1];
        $rule = $this->a_cfg[$rnum][2]=="allow"?true:false;
        $res = false;
        if (($uip>=$sip) && ($uip<=$eip)) {
            if (!$rule) $res = 2;
            else {
                $numThr = $this->a_cfg[$rnum][3]//number of simulatenious threads per IP
                if (!$numThr) $res = -1;
                else {
                    $period = $this->a_cfg[$rnum][4]//timeout for each thread
                    if (!$period) $res = -1;
                    else {
                        $pnlt = $this->a_cfg[$rnum][5];    //penalty
                        $res = $this->chktime ($uip,$period,$numThr,$pnlt);
                        $res = ($res>$numThr)?1:-1;
                   }
                }
            }
        }
        return $res;
    }

/**
*  The method to check current rule
*  @access private
*  @return integer
*/

    function chktime ($uip,$period,$thr,$pnlt) {
//open/create file and check all records
        $ts = time (www.php.net/time)();
        $res = array (www.php.net/array)();
        $i = 1;
        $fname = $this->rootDir."/".$uip;
        if (!file_exists (www.php.net/file_exists)($fname)) {
            $fd = fopen (www.php.net/fopen) ($fname,"w");
            chmod (www.php.net/chmod) ($fname,$this->chmod);
            fwrite (www.php.net/fwrite) ($fd,$ts."\n");
            fclose (www.php.net/fclose) ($fd);
        } else {
            $fd = fopen (www.php.net/fopen) ($fname,"r");
            while (!feof (www.php.net/feof) ($fd)) {
                $buf = fgets (www.php.net/fgets)($fd);
                $buf = (int)$buf;
                if ($buf==0) $buf = $ts;
                if ($ts-$buf<=$period) {
                    $res[$i] = $buf;
                    $i++;
                }
            }
            $i--;
            fclose (www.php.net/fclose) ($fd);
            if ($i<=$thr) $res[$i] = $ts;
            else {
              $i=$thr+1;
              for ($k=1;$k<=$i;$k++) {
                  $res[$k] +=$pnlt;
              }
            }
            $fd = fopen (www.php.net/fopen) ($fname,"w");
            chmod (www.php.net/chmod) ($fname,$this->chmod);
            for ($k=1;$k<=min (www.php.net/min)($i,$thr);$k++) {
                fwrite (www.php.net/fwrite) ($fd,$res[$k]."\n");
            }
            fclose (www.php.net/fclose) ($fd);
        }
        return $i//
    }
     
/**
*  The method to fetch user's IP
*  @access private
*  @return string
*/

    function fetchip() {
//get useful vars:
        $client_ip = isset (www.php.net/isset)($_SERVER['HTTP_CLIENT_IP'])?$_SERVER['HTTP_CLIENT_IP'] : "";
        $x_forwarded_for = isset (www.php.net/isset)($_SERVER['HTTP_X_FORWARDED_FOR'])?
           $_SERVER['HTTP_X_FORWARDED_FOR'] : "";
        $remote_addr = $_SERVER['REMOTE_ADDR'];
//then the script itself
        if (!empty (www.php.net/empty) ($client_ip) ) {
            $ip_expl = explode (www.php.net/explode)('.',$client_ip);
            $referer = explode (www.php.net/explode)('.',$remote_addr);
            if ($referer[0] != $ip_expl[0]) {
                $ip=array_reverse (www.php.net/array_reverse)($ip_expl);
                $ret=implode (www.php.net/implode)('.',$ip);
            } else {
                $ret = $client_ip;
            };
        } elseif (!empty (www.php.net/empty)($x_forwarded_for) ) {
            if (strstr (www.php.net/strstr)($x_forwarded_for,',')) {
                $ip_expl = explode (www.php.net/explode)(',',$x_forwarded_for);
                $ret = end (www.php.net/end)($ip_expl);
            } else {
                $ret = $x_forwarded_for;
            };
        } else {
          $ret = $remote_addr;
        };
        return $ret;
    }
}
?>


Last edited by WingedFox on Sun May 11, 2003 9:54 pm; edited 4 times in total
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 414
   поощрить/наказать


PostPosted: Sat Nov 13, 2004 3:07 pm (спустя 1 год 6 месяцев 11 дней 21 час 32 минуты)
   Post subject:
Reply with quote


М

Ветка выделена в отдельную тему «Antiflood: обсуждение»,
расположенную в форуме Разное :: PHP (13 Ноября 2004, 15:07).
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML