2013-04-16 3 views
2

여러 파일 (예 : 동시에 500 개의 파일)을 다운로드하고 약간의 시간 동안 더 많은 페이지를 열어서 내 웹 사이트에 부하가 걸리는 것을 발견했습니다. captcha if 예기치 않은 탐색이 사용자에 의해 감지되었습니다.예기치 않은 탐색이 트래픽 남용을 방지하기 위해 감지 된 경우 captcha 보여주기

보안 문자을 구현하는 방법을 알고 있지만 (PHP)를 사용하여 트래픽 남용을 감지하는 가장 좋은 방법은 무엇인지 알 수 없습니까?

답변

5

일반적인 방법은 분 단위로 요청을 저장하기 위해 memcached와 같은 것을 사용하는 것입니다, 나는 개방이 달성 작은 클래스를 공급 한 : php-ratelimiter 당신이 왜의보다 철저한 설명에 관심이 있다면

요청은 분 단위로 저장해야합니다 (check this post).

사실
if (!verifyCaptcha()) { 
    $rateLimiter = new RateLimiter(new Memcache(), $_SERVER["REMOTE_ADDR"]); 
    try { 
     $rateLimiter->limitRequestsInMinutes(100, 5); 
    } catch (RateExceededException $e) { 
     displayCaptcha(); 
     exit; 
    } 
} 

, 코드가 분당을 기반으로하지만 당신은 아주 쉽게 당에가이 적응할 수 : 그래서

그것을 요약하면, 코드는 다음과 같이보고 끝낼 수 있었다 30초 기준 :

private function getKeys($halfminutes) { 
    $keys = array(); 
    $now = time(); 
    for ($time = $now - $halfminutes * 30; $time <= $now; $time += 30) { 
     $keys[] = $this->prefix . date("dHis", $time); 
    } 
    return $keys; 
} 
+2

이것은보기 좋은 간단한 클래스입니다. 공유 Thx! –

2

소개

비슷한 질문 Prevent PHP script from being flooded 전에 답변을 얻을 수있다 그러나 수도 충분한 이유가 될 수 없습니다 :

  • 그것은 $_SERVER["REMOTE_ADDR"] 사용하고 일부 공유 연결이 같은 Public IP Address
  • 이 있습니다이 있습니다 많은 수는 사용자가 각 요청

에 대해 여러 프록시를 사용할 수 있습니다 Firefox addon 다중 요청! = 복수 다운로드

다중 요청 방지는 다중 다운로드와 완전히 다른 이유는 무엇입니까?

까 하나이다 당신이 그것을 당신이 볼 수있는이 문제를 해결하려면

10MB * 100 per min 

를 다운로드하는 사용자에게 액세스 권한을 부여하는 의미를 100 request per min 말을 사용자를 제한하는 경우, 다운로드 1min 걸릴 것 10MB의 파일을 상상해 Download - max connections per user?.

초당 사용자를 제한 할 memcache을 확장 SimpleFlood을 사용할 수 있습니다

후문 액세스를 여러 번 요청.그것은 공유 연결 문제를 해결하기 위해 cookies를 사용하고

$flood = new SimpleFlood(); 
$flood->addserver("127.0.0.1"); // add memcache server 
$flood->setLimit(2); // expect 1 request every 2 sec 
try { 
    $flood->check(); 
} catch (Exception $e) { 
    sleep(2); // Feel like wasting time 
    // Display Captcher 
    // Write Message to Log 
    printf("%s => %s %s", date("Y-m-d g:i:s"), $e->getMessage(), $e->getFile()); 
} 

당신은 할 수 있습니다 SimpleFlood::setLimit(float $float);가 수레를 허용 함을 유의하시기 바랍니다 실제 IP 주소를 얻기 위해 시도

$flood->setLimit(0.1); // expect 1 request every 0.1 sec 

사용 클래스

class SimpleFlood extends \Memcache { 
    private $ip; 
    private $key; 
    private $prenalty = 0; 
    private $limit = 100; 
    private $mins = 1; 
    private $salt = "I like TO dance A #### Lot"; 

    function check() { 
     $this->parseValues(); 
     $runtime = floatval($this->get($this->key)); 
     $diff = microtime(true) - $runtime; 
     if ($diff < $this->limit) { 
      throw new Exception("Limit Exceeded By : $this->ip"); 
     } 
     $this->set($this->key, microtime(true)); 
    } 

    public function setLimit($limit) { 
     $this->limit = $limit; 
    } 

    private function parseValues() { 
     $this->ip = $this->getIPAddress(); 
     if (! $this->ip) { 
      throw new Exception("Where the hell is the ip address"); 
     } 

     if (isset($_COOKIE["xf"])) { 
      $cookie = json_decode($_COOKIE["xf"]); 
      if ($this->ip != $cookie->ip) { 
       unset($_COOKIE["xf"]); 
       setcookie("xf", null, time() - 3600); 
       throw new Exception("Last IP did not match"); 
      } 

      if ($cookie->hash != sha1($cookie->key . $this->salt)) { 
       unset($_COOKIE["xf"]); 
       setcookie("xf", null, time() - 3600); 
       throw new Exception("Nice Faking cookie"); 
      } 
      if (strpos($cookie->key, "floodIP") === 0) { 
       $cookie->key = "floodRand" . bin2hex(mcrypt_create_iv(50, MCRYPT_DEV_URANDOM)); 
      } 
      $this->key = $cookie->key; 
     } else { 
      $this->key = "floodIP" . sha1($this->ip); 
      $cookie = (object) array(
        "key" => $this->key, 
        "ip" => $this->ip 
      ); 
     } 
     $cookie->hash = sha1($this->key . $this->salt); 
     $cookie = json_encode($cookie); 
     setcookie("xf", $cookie, time() + 3600); // expire in 1hr 
    } 

    private function getIPAddress() { 
     foreach (array(
       'HTTP_CLIENT_IP', 
       'HTTP_X_FORWARDED_FOR', 
       'HTTP_X_FORWARDED', 
       'HTTP_X_CLUSTER_CLIENT_IP', 
       'HTTP_FORWARDED_FOR', 
       'HTTP_FORWARDED', 
       'REMOTE_ADDR' 
     ) as $key) { 
      if (array_key_exists($key, $_SERVER) === true) { 
       foreach (explode(',', $_SERVER[$key]) as $ip) { 
        if (filter_var($ip, FILTER_VALIDATE_IP) !== false) { 
         return $ip; 
        } 
       } 
      } 
     } 

     return false; 
    } 
} 

결론

이 기본 개념의 증명 추가 레이어는 분 또는 특정 수의 사용자를 차단 곳

  • 처벌에 대한 지원을 추가 차이 URL의 그것과 같은

    같은
    • 설정 다른 제한에 추가 할 수있다 시간
    • 탐지 및 Tor 연결
  • +0

    좋은 설명을 주셔서 감사합니다 ... –

    1

    나는 Y를 생각에 대한 다른 제한 ou는이 경우 세션을 사용할 수 있습니다. 타임 스탬프를 저장하기 위해 세션을 초기화하고 [더 나은 결과를 얻으려면 마이크로 시간 사용] 새 페이지의 타임 스탬프를 얻습니다.이 차이는 방문중인 페이지의 빈도를 분석하는 데 사용될 수 있으며 보안 문자를 표시 할 수 있습니다.

    방문중인 페이지에서 카운터를 실행하고 페이지 및 타임 스탬프를 저장하기 위해 2 차원 어레이를 사용할 수도 있습니다. 방문중인 페이지의 값이 갑자기 증가하면 시간 소인 차이를 확인할 수 있습니다.

    +0

    나는 또한 세션을 사용하여 그것을 시도했다. 그것을 구현 한 후에 나는 방문 횟수를 계산하는 동안 약간의 오버 헤드에 직면하고 각각의 새로운 방문에 대해 업데이트했습니다 ... –

    +0

    글쎄, 많은 트래픽 중독자는 없을 것 같습니다. 당신은 그것에 대한 데이터베이스 테이블을 만들 수 있으며 일부 IP는 위의 계산에 의해 안전한 것으로 보인다 목록에 추가 할 수 있습니다. 또한 몇 가지 구별 키를 사용하여 데이터베이스에 나쁜 IP를 추가 할 수 있습니다. 한 번 당신이 나쁜 실행 계산 드문 또는 대신 ip 단위로 x 번 방문 할 때마다 captcha를 표시합니다. –

    +0

    그러나 때로는 좋은 사용자가 파일 목록을 다운로드하려고하지만 항상 그런 것은 아닙니다. 그래서 예기치 않은 동작이 감지 된 경우에만 captcha를 표시해야하는 이유입니다. –