jueves, 26 de octubre de 2017

Anti-DDoS PHP Script (Prevenir ataques DDoS en PHP)

Las soluciones contra un ataque DDoS son más bien del lado de la configuración del servidor y el firewall que tenemos allí instalado.

No obstante, es posible a nivel de código tener un pequeño control, que si no evita el ataque completamente, al menos lo puede mitigar en una gran medida. Manos a la obra...


Vamos a crear una carpeta que se llamará "anti_ddos" y pondremos allí dos archivos: "index.php" y "anti_ddos.php".

Contenido del archivo index.php:

 <?php 
 $ad_ddos_query = 10,// ​​number of requests per second to detect DDOS attacks 
 $ad_check_file = 'check.txt';// file to write the current state during the monitoring
 $ad_temp_file = 'all_ip.txt';// temporary file
 $ad_black_file = 'black_ip.txt';// will be entered into a zombie machine ip
 $ad_white_file = 'white_ip.txt';// ip logged visitors
 $ad_dir = 'anti_ddos';// directory with scripts
 $ad_num_query = 0;// ​​current number of requests per second from a file $check_file
 $ad_sec_query = 0;// ​​second from a file $check_file
 $ad_end_defense = 0;// ​​end while protecting the file $check_file
 $ad_sec = date("s");// current second
 $ad_date = date("mdHis");// current time
 $ad_defense_time = 10000;// ddos ​​attack detection time in seconds at which stops monitoring
 
 if (!file_exists ("{$ad_dir}/{$ad_check_file}") or!file_exists ("{$ad_dir}/{$ad_temp_file}") or!file_exists ("{$ad_dir}/{$ad_black_file}") or !file_exists ("{$ad_dir}/{$ad_white_file}") or!file_exists ("{$ad_dir}/anti_ddos.php")) {
    die ("Not enough files.");
 }
 
 require("{$ad_dir}/{$ad_check_file}");
 
 if (($ad_end_defense) && ($ad_end_defense>$ad_date)) {
    require ("{$ad_dir}/anti_ddos.php");
 } else {
    if ($ad_sec == $ad_sec_query) {
       $ad_num_query++;
    } else {
       $ad_num_query = '1';
    }
 
    if ($ad_num_query>=$ad_ddos_query) {
       $ad_file = fopen ("{$ad_dir}/{$ad_check_file}", "w");
       $ad_end_defense = $ad_date + $ad_defense_time;
       $ad_string = '<?php $ad_end_defense ='. $ad_end_defense. ';?>';
       fputs($ad_file, $ad_string);
       fclose($ad_file);
    } else {
       $ad_file = fopen("{$ad_dir}/{$ad_check_file}", "w");
       $ad_string = '<?php $ad_num_query ='. $ad_num_query. '; $ad_sec_query ='. $ad_sec. ';?>';
       fputs($ad_file, $ad_string);
       fclose($ad_file);
    }
 }
 ?>

Y el contenido del archivo anti_ddos.php:

<?php 
function getIP() {
    if(getenv("HTTP_CLIENT_IP") and preg_match("/^[0-9\.]*?[0-9\.]+$/is", getenv("HTTP_CLIENT_IP")) && getenv("HTTP_CLIENT_IP")!='127.0.0.1') {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif(getenv("HTTP_X_FORWARDED_FOR") && preg_match("/^[0-9\.]*?[0-9\.]+$/is", getenv("HTTP_X_FORWARDED_FOR")) && getenv("HTTP_X_FORWARDED_FOR") != '127.0.0.1') {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    } else {
        $ip = getenv("REMOTE_ADDR");
    }
    return $ip;
}
$ad_ip = getIP();
 
 $ad_source = file("{$ad_dir}/{$ad_black_file}");
 $ad_source = explode('', $ad_source[0]);
 if(in_array($ad_ip, $ad_source)) {die();}
 
 $ad_source = file("{$ad_dir}/{$ad_white_file}");
 $ad_source = explode('', $ad_source[0]);
 if(!in_array($ad_ip, $ad_source)) {
 
     $ad_source = file("{$ad_dir}/{$ad_temp_file}");
     $ad_source = explode('', $ad_source[0]);
     if(!in_array($ad_ip, $ad_source)) {
         $ad_file = fopen("{$ad_dir}/{$ad_temp_file}", "a+");
         $ad_string = $ad_ip. '  ';
         fputs($ad_file, "$ad_string");
         fclose($ad_file);
 ?>
<!--
 
 The site is currently subject to DDOS attack, if you're not a machine, zombie attacking the site, click on the button, otherwise your IP(<?=$ad_ip?>) Will be blocked!
 <form method="post">
 <input type="submit" name="ad_white_ip" value="Knopka">
 </form>
-->
 
<?php
         die();
     } elseif($_POST['ad_white_ip']) {
         $ad_file = fopen("{$ad_dir}/{$ad_white_file}", "a+");
         $ad_string = $ad_ip. '  ';
         fputs($ad_file, "$ad_string");
         fclose($ad_file);
     } else {
         $ad_file = fopen("{$ad_dir}/{$ad_black_file}", "a+");
         $ad_string = $ad_ip. '  ';
         fputs($ad_file, "$ad_string");
         fclose($ad_file);
         die();
     }
 }
 ?>
 

Además, para el script se necesitarán 4 archivos check.txt, white_ip.txt, black_ip.txt all_ip.txt y hay que crearlos en el mismo directorio con todos los permisos configurados en 666 (lectura y escritura).

También es deseable durante los ataques, obtener las listas de las direcciones IP de la máquina de los atacantes, esa información será trasnferida al archivo black_ip.txt gradualmente. Y por último usar el archivo .htaccess para bloquearlos, entonces la carga es aún considerablemente menor.

El archivo .htaccess deberá tener una línea por cada IP bloqueada así:

deny from 11.11.11.11

Hay una manera de automarizar esta agregación al archivo .htaccess, pero lo hablaré en otro post.

Para terminar, es necesario incluir en todas las páginas PHP que queremos que controlen el ataque la siguiente línea al comienzo:

require("anti_ddos/index.php");


Y listo... no es una seguridad al 100%, pero estaremos mucho mejor protegidos.

No hay comentarios:

Publicar un comentario

7 razones para no usar Laravel en tu proyecto de PHP

En más de 40 años de experiencia como programador y director de proyectos de programación, he aprendido que cada requerimiento tiene mejores...