2012-12-30 7 views
4

질문이 있습니다. 특정 ip가 내 웹 사이트를 홍수로 치는 지 확인하기 위해이 작은 스크립트를 만들었습니다. 이 경우, .htaccess 파일에서 ip를 거부합니다. 내 질문은, 누군가가이 스크립트가 완전히 쓸모 없거나 시도할만한 가치가 있는지 말해 줄 수 있습니다 ... 스크립트는 config 파일에서 호출되므로 모든 pageload에서 실행됩니다. PHP, .htaccess, DDoS 및 빠른 요청 보호

<?php 
#get the visitor ip 
$ip = $_SERVER["REMOTE_ADDR"]; 

#start the session 
@session_start(); 

#check if the ip is banned 
if($_SESSION['~b']){ 

#check if we can open htaccess 
$fp = @fopen('./.htaccess','a'); 
    if($fp){ 
     #add the ip to htaccess 
     @fwrite($fp,"\r\ndeny from $ip"); 
     #close 
     @fclose($fp); 
     #destroy the session 
     @session_destroy(); 
     @mail("my-email","IP Banned","Ip: $ip"); 
    } 
    #let the user know why we deny him or her access 
    die('To many requests.'); 
    } 
#get the filename and location 
$f = './log/'[email protected]($ip); 

#check if the file exists 
if (@is_file($f)) { 
     #get the last filetime 
     $a = @filemtime($f); 
     #touch the file, give a new filetime 
     @touch($f,time()); 
     #the ip is not banned 
     $_SESSION['~b'] = false; 
     #add the time diff 
     $_SESSION['~r'] += @time()-$a; 
     #add the latest hit 
     $_SESSION['~h'] += 1; 
    }else{ 
     #create the file if it doesn't exist 
     @file_put_contents($f,''); #size: 0kb 
     #if touch() doesn't work 
     #chmod($ipfile,0755); 
    } 

#calculate the diff after 10 hits, and ban when the avg is smaller than 0.25 seconds 
if($_SESSION['~h'] > 10 && ($_SESSION['~r']/$_SESSION['~h']) < 0.25) $_SESSION['~b'] = true; 
?> 

그냥 세션을 피하기 위해 조언을 따라, 그래서 난 쿠키와 세션에 따라 할 필요없이, 그것을 기반으로 파일을 만든 :

<?php 
# get the visitor ip 
$i = $_SERVER["REMOTE_ADDR"]; 
# get the filename and location 
$f = './log/'.ip2long($i).'.dat'; 
# check if the file exists and we can write 
if (is_file($f)) { 
    # get the last filetime 
    $a = filemtime($f); 
    # get the file content 
    $b = file_get_contents($f); 
    # create array from hits & seconds 
    $d = explode(':',$b); 
    # calculate the new result 
    $h = (int)$d[0] + 1; 
    $s = (int)$d[1] + (time()-$a); 
    # add the new data tot text file 
    file_put_contents($f,"$h:$s",LOCK_EX); 
    unset($d); 
}else{ 
    # create the file if it doesn't exist hits:seconds 
    file_put_contents($f,"1:1",LOCK_EX); #size: 3kb 
    # to make sure we can write 
    # chmod($f,0755); 
    # set the hits to zero 
    $h = 0; 
} 
# create a result var 
$r = $h > 10 ? (float)$s/$h : (float)1; 
# calculate the diff after 10 hits, and ban when the avg is smaller than 0.20 seconds (5 hits per second) 
if($r < 0.20) { 
    # check if we can open htaccess 
    $fp = @fopen('./.htaccess','a'); 
    if($fp){ 
     # add the ip to htaccess 
     @fwrite($fp,"\r\ndeny from $i"); 
     # close 
     @fclose($fp); 
     # mail the admin 
     @mail("email","IP Banned","Ip: $i with $r sbh (Seconds Between Hits)"); 
    } 
    # let the user know why we deny him or her access 
    die('To many requests.'); 
    # remove the file 
    unlink($f); 
} 
# if the user leaves, reset 
if($r > 30) { 
    unlink($f); 
} 
echo 'Result: '.$r.'sbh (Seconds Between Hits)'; 
?> 
+0

이것은 PHP와 같은 해석 언어로 처리하면 안됩니다. 이것은 방화벽 및 fail2ban과 같은 로그를 감시하는 다른 스크립트로 처리해야합니다. – pocesar

+0

@ 3eighty이 코드를 사용 해주셔서 감사합니다. 그러나 지난 1 시간 동안 편집되지 않은 로그 폴더의 파일을 삭제하는 방법은 무엇입니까? 따라서 3 일 후에 해당 폴더에 200,000 개의 파일이 저장되지 않도록 할 수 있습니다. – lopata

답변

0

내 두 센트. 그러나 합법적 인 사용자가 웹 사이트에 액세스하지 못하도록 막는 것이 좋습니다. 구글 봇과 같은 로봇에서도 문제가 될 것입니다. 나는 신중할 것입니다. 아마도 사용자 에이전트를 확인하고 그것이 Google로 나타나면 다른 조건과 상관없이 허용하십시오. 물론 이것은 악의적 인 사용자를위한 새로운 구멍을 열어줍니다. 일반적으로 이와 같은 일은 PHP 코드가 아닌 웹 서버에서 수행됩니다. 또 다른 접근법은 토큰 시스템입니다. 즉, 좀 더 세분화하면 접근 방식에 뭔가있을 수 있다고 생각합니다.

또한 .htaccess or PHP protection code against multiple speedy requests 본 적이 있습니까? 그것은 당신이 설계하고있는 것이 이전에 시도 된 것을 제안합니다. 이것은 아마도 당신이 올바른 방향으로 향하고 있음을 말해줍니다.

2

평상시 사용자가 특정 시간 내에 너무 많은 요청을 보내지 않게하려면 으로 스크립트가 작동 할 수 있습니다. catpcha 화면을 가져 오면 비즈니스를 할 수 있습니다.

하지만

진짜 대답은 없는입니다.

이 코드의 주요 실수는 세션에 따라 사용자의 활동 빈도를 결정하는 것입니다. "양호한"공격자는 쿠키가 비활성화 된 요청을 서버에 넘겨 줄 수 있으며 IP를 속일 수 있습니다.

공격을 막는 한 가지 방법은 서버 수준으로 가서 iptables를 설치하는 것입니다. 사실 iptables는 대부분의 리눅스 배포판과 함께 제공됩니다. 구성이 거의 필요 없으며 즉시 사용할 수 있습니다.

또 다른 방법은 서버에 대한 루트 액세스 권한이있는 경우 세션 처리를 Memcached로 이동하는 것입니다. 꽤 보스 인 홍수 조절이라는 기능이 있습니다. DDOS을 방지하기 위해

또 다른 경로는 타사 서비스에서 같은 blockdos http://www.blockdos.net/

일종의 비싼 있지만, 그것은 당신을 위해 일할 수 있습니다.

하지만 PHP 자체로 DDoS 공격을 처리하도록 구성 할 수 없습니다. PHP 스크립트를 실행하기 전에 모든 종류의 어플라이언스 또는 방화벽을 검사해야합니다. 때문에 항상 심하게 종료됩니다 규칙을 차단 요청 속도를 기반으로 IP를 설정하여 DDoS 공격을 완화

0

:

  1. 같은 규칙은 합법적 인 사용자 (위양성) IP 스푸핑에 대한
  2. 에 영향을 미칠 것이다, 그것은 바로 그 일반적이다 이것은 모든 공격자는 아니더라도 대부분의 사람들에게 적용되지 않습니다.

이것은 IPTables에도 해당됩니다. 자세한 내용은 여기에서 확인할 수 있습니다. http://www.incapsula.com/ddos/ddos-protection-service#iptables-ddos-protection

0

해결책은 매우 유용합니다. 한편, @lopata가 물어 본 질문에 대해서는 스크립트에서 unlink() 함수를 주석 처리하고 htaccess에서 IP를 차단 해제하고 언젠가는 파일을 제거하는 cron-job을 설정할 수 있습니다.

<?php 

function unban_ip($ip){ 
    $filename='.htaccess'; 
    $line="deny from $ip"; 
    file_put_contents($filename, str_replace("\r\n".$line, "", file_get_contents($filename))); 
    $f = './log/'[email protected]($ip); 
    if(@is_file($f))unlink($f); 
    return true; 
} 

$time=time(); 
$path='./log'; 
[email protected]($path); 
$x=0; 

while(([email protected]($handle))!==false){ 
    if($file=='.'||$file=='..')continue; 
    $filepath="$path/$file"; 

    if(is_file($filepath)){ 
     [email protected]($filepath); 
     if($time-$ftime>600){ //unban after 10 minutes 
      $ip=long2ip($file); 
      unban_ip($ip); 
      $x++; 
     } 
    } 
} 

echo "$x IPs Unbanned";