Necesito evitar que los bots maten a mi servidor web

9

Tengo problemas EXTREMOS de bot en algunos de mis sitios web dentro de mi cuenta de hosting. Los bots utilizan más del 98% de mis recursos de CPU y el 99% de mi ancho de banda para toda mi cuenta de hosting. Estos bots están generando más de 1 GB de tráfico por hora para mis sitios. El tráfico humano real para todos estos sitios es inferior a 100 MB / mes .

He realizado una investigación exhaustiva tanto en el archivo robots.txt como en el archivo .htaccess para bloquear estos bots, pero todos los métodos fallaron.

También puse código en los archivos robots.txt para bloquear el acceso a los directorios de los scripts, pero estos bots (Google, MS Bing y Yahoo) ignoran las reglas y ejecutan los scripts de todos modos.

No quiero bloquear completamente los bots de Google, MS Bing y Yahoo, pero quiero limitar la tasa de rastreo. Además, agregar una declaración de retraso de rastreo en el archivo robots.txt no ralentiza los bots. Mi código actual de robots.txt y .htacces para todos los sitios se indica a continuación.

He configurado las herramientas para webmasters de Microsoft y Google para reducir la velocidad de rastreo al mínimo absoluto, pero todavía están llegando a estos sitios a una velocidad de 10 visitas / segundo.

Además, cada vez que subo un archivo que causa un error, todo el servidor web VPS se cae en segundos, de modo que ni siquiera puedo acceder al sitio para corregir el problema debido a la avalancha de golpes de estos bots.

¿Qué puedo hacer para detener el tráfico en mi sitio web?

Intenté preguntarle a mi empresa de alojamiento web (site5.com) muchas veces sobre este problema en los últimos meses y no pueden ayudarme con este problema.

Lo que realmente necesito es evitar que los Bots ejecuten el script rss2html.php. Probé ambas sesiones y cookies y ambas fallaron.

robots.txt

User-agent: Mediapartners-Google
Disallow: 
User-agent: Googlebot
Disallow: 
User-agent: Adsbot-Google
Disallow: 
User-agent: Googlebot-Image
Disallow: 
User-agent: Googlebot-Mobile
Disallow: 
User-agent: MSNBot
Disallow: 
User-agent: bingbot
Disallow: 
User-agent: Slurp
Disallow: 
User-Agent: Yahoo! Slurp
Disallow: 
# Directories
User-agent: *
Disallow: /
Disallow: /cgi-bin/
Disallow: /ads/
Disallow: /assets/
Disallow: /cgi-bin/
Disallow: /phone/
Disallow: /scripts/
# Files
Disallow: /ads/random_ads.php
Disallow: /scripts/rss2html.php
Disallow: /scripts/search_terms.php
Disallow: /scripts/template.html
Disallow: /scripts/template_mobile.html

.htaccess

ErrorDocument 400 http://english-1329329990.spampoison.com
ErrorDocument 401 http://english-1329329990.spampoison.com
ErrorDocument 403 http://english-1329329990.spampoison.com
ErrorDocument 404 /index.php
SetEnvIfNoCase User-Agent "^Yandex*" bad_bot
SetEnvIfNoCase User-Agent "^baidu*" bad_bot
Order Deny,Allow
Deny from env=bad_bot
RewriteEngine on
RewriteCond %{HTTP_user_agent} bot\* [OR]
RewriteCond %{HTTP_user_agent} \*bot
RewriteRule ^.*$ http://english-1329329990.spampoison.com [R,L]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [OR]
# Block out any script that includes a <script> tag in URL
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
# Send all blocked request to homepage with 403 Forbidden error!
RewriteRule ^(.*)$ index.php [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$  [NC]
RewriteRule (.*) index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
# Don't show directory listings for directories that do not contain an index file (index.php, default.asp etc.)
Options -Indexes
<Files http://english-1329329990.spampoison.com>
order allow,deny
allow from all
</Files>
deny from 108.
deny from 123.
deny from 180.
deny from 100.43.83.132

ACTUALIZAR PARA MOSTRAR AGENTE DE USUARIO AGREGADO BOT CÓDIGO DE VERIFICACIÓN

<?php
function botcheck(){
 $spiders = array(
   array('AdsBot-Google','google.com'),
   array('Googlebot','google.com'),
   array('Googlebot-Image','google.com'),
   array('Googlebot-Mobile','google.com'),
   array('Mediapartners','google.com'),
   array('Mediapartners-Google','google.com'),
   array('msnbot','search.msn.com'),
   array('bingbot','bing.com'),
   array('Slurp','help.yahoo.com'),
   array('Yahoo! Slurp','help.yahoo.com')
 );
 $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
 foreach($spiders as $bot) {
   if(preg_match("/$bot[0]/i",$useragent)){
     $ipaddress = $_SERVER['REMOTE_ADDR']; 
     $hostname = gethostbyaddr($ipaddress);
     $iphostname = gethostbyname($hostname);
     if (preg_match("/$bot[1]/i",$hostname) && $ipaddress == $iphostname){return true;}
   }
 }
}
if(botcheck() == false) {
  // User Login - Read Cookie values
     $username = $_COOKIE['username'];
     $password = $_COOKIE['password'];
     $radio_1 = $_COOKIE['radio_1'];
     $radio_2 = $_COOKIE['radio_2'];
     if (($username == 'm3s36G6S9v' && $password == 'S4er5h8QN2') || ($radio_1 == '2' && $radio_2 == '5')) {
     } else {
       $selected_username = $_POST['username'];
       $selected_password = $_POST['password'];
       $selected_radio_1 = $_POST['group1'];
       $selected_radio_2 = $_POST['group2'];
       if (($selected_username == 'm3s36G6S9v' && $selected_password == 'S4er5h8QN2') || ($selected_radio_1 == '2' && $selected_radio_2 == '5')) {
         setcookie("username", $selected_username, time()+3600, "/");
         setcookie("password", $selected_password, time()+3600, "/");
         setcookie("radio_1", $selected_radio_1, time()+3600, "/");
         setcookie("radio_2", $selected_radio_2, time()+3600, "/");
       } else {
        header("Location: login.html");
       }
     }
}
?>

También agregué lo siguiente a la parte superior del script rss2html.php

// Checks to see if this script was called by the main site pages, (i.e. index.php or mobile.php) and if not, then sends to main page
   session_start();  
   if(isset($_SESSION['views'])){$_SESSION['views'] = $_SESSION['views']+ 1;} else {$_SESSION['views'] = 1;}
   if($_SESSION['views'] > 1) {header("Location: http://website.com/index.php");}
Sammy
fuente
¿Cuándo actualizaste tu robots.txt? A los robots les puede llevar tiempo leer la versión actualizada.
ilanco
hace unos días. Lo que realmente necesito es evitar que los Bots ejecuten el script rss2html.php. Probé ambas sesiones y cookies y ambas fallaron.
¿Cómo está rss2html.phpsiendo utilizado por su sitio? a través de PHP incluyen, redirecciones, Ajax ...?
cHao
Los archivos rss2html.php se llaman mediante un comando file_get_contents ()
file_get_contents...? Parece bastante extraño. ¿El archivo está en otro servidor o algo así?
cHao

Respuestas:

3

Si rss2html.phpel cliente no lo está utilizando directamente (es decir, si es PHP siempre lo está utilizando en lugar de ser un enlace o algo así), entonces olvide intentar bloquear los bots. Todo lo que realmente tiene que hacer es definir una constante o algo en la página principal, luego includeel otro script. En el otro script, verifique si la constante está definida y escupe un error 403 o una página en blanco o lo que sea si no está definido.

Ahora, para que esto funcione, tendrá que usarlo en includelugar de hacerlo file_get_contents, ya que este último simplemente leerá el archivo (si está utilizando una ruta local) o se ejecutará en un proceso completamente diferente (si usted ' estás usando una URL). Pero es el método que cosas como Joomla! se usa para evitar que un script se incluya directamente. Y use una ruta de archivo en lugar de una URL, de modo que el código PHP no se haya analizado antes de intentar ejecutarlo.

Aún mejor sería rss2html.phpsalir de debajo de la raíz del documento, pero algunos hosts hacen que sea difícil hacerlo. Si esa es una opción depende de la configuración de su servidor / host.

cHao
fuente
1
Chao, gracias. Actualmente, estoy reescribiendo mi código para convertir el file_get_contents para incluir en su lugar.
Sammy
4

Puede configurar su secuencia de comandos para que arroje un error 404 basado en la cadena de agente de usuario proporcionada por los bots; rápidamente obtendrán la pista y lo dejarán solo.

if(isset($_SERVER['HTTP_USER_AGENT'])){
   $agent = $_SERVER['HTTP_USER_AGENT'];
}

if(preg_match('/^Googlebot/i',$agent)){
   http_response_code(301);
   header("HTTP/1.1 301 Moved Permanently");
   header("Location: http://www.google.com/");
   exit;
}

Revise sus registros y rechace Bingbot, etc. de una manera similar: no detendrá las solicitudes, pero podría ahorrar algo de ancho de banda. Dele al googlebot una muestra de su propia medicina: ¡Mwhahahahaha!

Actualizado

Mirando su código, creo que su problema está aquí:

if (preg_match("/$bot[1]/i",$hostname) && $ipaddress == $iphostname)

Si son bots maliciosos, podrían provenir de cualquier parte, elimine esa $ipaddresscláusula y envíeles una respuesta 301 o 404.

Pensando justo al lado de la caja

  1. Googlebot nunca acepta cookies , por lo que no puede almacenarlas. De hecho, si necesita cookies para todos los usuarios, eso probablemente evitará que el bot acceda a su página.
  2. Googlebot no entiende los formularios, o JavaScript, por lo que podría generar dinámicamente sus enlaces o hacer que los usuarios hagan clic en un botón para acceder a su código (con un token adecuado adjunto).

    <a href="#" onclick="document.location='rss2html.php?validated=29e0-27fa12-fca4-cae3';">Rss2html.php</a>

    • rss2html.php? validado = 29e0-27fa12-fca4-cae3 - humano
    • rss2html.php - bot
web_bod
fuente
1
No tan rápido como podrías pensar. He visto a bots llegar a la misma página inexistente durante meses, ocasionalmente incluso años después de que la página fue eliminada. Depende de qué tan bien se haya comportado el bot y de qué se trate.
cHao
La forma en que funciona para los visitantes humanos es que el archivo index.php llama al script rss2html.php. Los bots evitan el script index.php y ejecutan directamente el script rss2html.php. ¿Cómo puedo proteger ese archivo rss2html.php si no se accedió a él a través del script index.php?
Intente renombrar rss2html.php a otra cosa y actualice su index.php para hacer referencia al nuevo nombre.
BluesRockAddict
Intenté cambiar el nombre del archivo, pero falla después de unos días. ¿Cómo puedo agregar el código que estoy usando a este hilo? Quiero mostrarte lo que he intentado.
1
ok - Conozco un truco que puedes hacer :) - pon el código de script rss2html.php fuera de tu sitio web (actualizará la respuesta)
2

Límite de PHP / solicitudes de sitios web bloqueados para arañas / bots / clientes, etc.

Aquí he escrito una función PHP que puede bloquear solicitudes no deseadas para reducir el tráfico de su sitio web. Bueno para arañas, bots y clientes molestos.

CLIENTE / Bots Blocker

DEMO: http://szczepan.info/9-webdesign/php/1-php-limit-block-website-requests-for-spiders-bots-clients-etc.html

CÓDIGO:

/* Function which can Block unwanted Requests
 * @return array of error messages
 */
function requestBlocker()
{
        /*
        Version 1.0 11 Jan 2013
        Author: Szczepan K
        http://www.szczepan.info
        me[@] szczepan [dot] info
        ###Description###
        A PHP function which can Block unwanted Requests to reduce your Website-Traffic.
        God for Spiders, Bots and annoying Clients.

        */

        # Before using this function you must 
        # create & set this directory as writeable!!!!
        $dir = 'requestBlocker/';

        $rules   = array(
                #You can add multiple Rules in a array like this one here
                #Notice that large "sec definitions" (like 60*60*60) will blow up your client File
                array(
                        //if >5 requests in 5 Seconds then Block client 15 Seconds
                        'requests' => 5, //5 requests
                        'sek' => 5, //5 requests in 5 Seconds
                        'blockTime' => 15 // Block client 15 Seconds
                ),
                array(
                        //if >10 requests in 30 Seconds then Block client 20 Seconds
                        'requests' => 10, //10 requests
                        'sek' => 30, //10 requests in 30 Seconds
                        'blockTime' => 20 // Block client 20 Seconds
                ),
                array(
                        //if >200 requests in 1 Hour then Block client 10 Minutes
                        'requests' => 200, //200 requests
                        'sek' => 60 * 60, //200 requests in 1 Hour
                        'blockTime' => 60 * 10 // Block client 10 Minutes
                )
        );
        $time    = time();
        $blockIt = array();
        $user    = array();

        #Set Unique Name for each Client-File 
        $user[] = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'IP_unknown';
        $user[] = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
        $user[] = strtolower(gethostbyaddr($user[0]));

        # Notice that I use files because bots do not accept Sessions
        $botFile = $dir . substr($user[0], 0, 8) . '_' . substr(md5(join('', $user)), 0, 5) . '.txt';


        if (file_exists($botFile)) {
                $file   = file_get_contents($botFile);
                $client = unserialize($file);

        } else {
                $client                = array();
                $client['time'][$time] = 0;
        }

        # Set/Unset Blocktime for blocked Clients
        if (isset($client['block'])) {
                foreach ($client['block'] as $ruleNr => $timestampPast) {
                        $elapsed = $time - $timestampPast;
                        if (($elapsed ) > $rules[$ruleNr]['blockTime']) {
                                unset($client['block'][$ruleNr]);
                                continue;
                        }
                        $blockIt[] = 'Block active for Rule: ' . $ruleNr . ' - unlock in ' . ($elapsed - $rules[$ruleNr]['blockTime']) . ' Sec.';
                }
                if (!empty($blockIt)) {
                        return $blockIt;
                }
        }

        # log/count each access
        if (!isset($client['time'][$time])) {
                $client['time'][$time] = 1;
        } else {
                $client['time'][$time]++;

        }

        #check the Rules for Client
        $min = array(
                0
        );
        foreach ($rules as $ruleNr => $v) {
                $i            = 0;
                $tr           = false;
                $sum[$ruleNr] = 0;
                $requests     = $v['requests'];
                $sek          = $v['sek'];
                foreach ($client['time'] as $timestampPast => $count) {
                        if (($time - $timestampPast) < $sek) {
                                $sum[$ruleNr] += $count;
                                if ($tr == false) {
                                        #register non-use Timestamps for File 
                                        $min[] = $i;
                                        unset($min[0]);
                                        $tr = true;
                                }
                        }
                        $i++;
                }

                if ($sum[$ruleNr] > $requests) {
                        $blockIt[]                = 'Limit : ' . $ruleNr . '=' . $requests . ' requests in ' . $sek . ' seconds!';
                        $client['block'][$ruleNr] = $time;
                }
        }
        $min = min($min) - 1;
        #drop non-use Timestamps in File 
        foreach ($client['time'] as $k => $v) {
                if (!($min <= $i)) {
                        unset($client['time'][$k]);
                }
        }
        $file = file_put_contents($botFile, serialize($client));


        return $blockIt;

}


if ($t = requestBlocker()) {
        echo 'dont pass here!';
        print_R($t);
} else {
        echo "go on!";
}
dazzafact
fuente
1

Es probable que su sitio esté siendo indexado por robots de Google falsos. Puede intentar agregar un cheque y servir 404 para todas las solicitudes falsas de bot de Google.

Aquí hay un artículo que explica cómo verificar Googlebot: http://googlewebmastercentral.blogspot.com/2006/09/how-to-verify-googlebot.html

También puede verificar sus registros con robots falsos conocidos: http://stopmalvertising.com/security/fake-google-bots.html

BluesRockAddict
fuente
Gracias, pero en realidad lo intenté también, determinando los agentes de usuario y enviando los bots a una página de inicio de sesión. Esto también falló.
Parece que te estás perdiendo el punto: confiar en el agente de usuario para determinar la autenticidad del bot no es suficiente.
BluesRockAddict
1

En primer lugar, debe asegurarse de que cualquier página solicitada a un agente de uso, de cualquier rastreador abusivo que tenga, recibirá una página estática.

Apache mod_rewrite con una condición o equiv con su servidor http. Para apache, algo como esto:

RewriteCond  %{HTTP_USER_AGENT}  ^GoogleBot [OR]
RewriteCond  %{HTTP_USER_AGENT}  ^OtherAbusiveBot
RewriteRule  ^/$                 /static_page_for_bots.html  [L]
smassey
fuente
gracias, pero no quiero bloquear completamente los bots de Google, MS Bing y Yahoo, pero quiero limitar los accesos directos al archivo de script rss2html.php. Solo necesito agregar algo al comienzo del script rss2html.php que evitará que se ejecute si no se accedió a través del script index.php. Los bots actualmente ejecutan el script rss2html.php sin pasar por el archivo index.php.
Sammy
Esto no los bloquea ... simplemente sirve una versión en caché de su php ... esto es muy fácil para un servidor, es una instancia de php menos / un proceso secundario menos apache. => Costo (archivo estático) <Costo (instancia de php).
smassey
¿Cómo guardaría en caché las páginas? Dado que las páginas son RSS, ¿las páginas almacenadas en caché se actualizarán con la frecuencia suficiente para proporcionar datos nuevos?
Sammy
Por supuesto ... Escribe un cronjob que lo haga por ti. Si dice que llegaron al servidor 10req / s si almacena en caché las páginas durante 1 minuto, ha guardado su servidor 599 instancias php adicionales (que ciertamente incluyen conexiones / consultas db). Y una vez por minuto es mucho más de lo que votaría para: 10 / 15min.
smassey
1

Para continuar en la publicación de smassey, puede poner varias condiciones:

RewriteCond  %{HTTP_USER_AGENT}  ^GoogleBot [OR]
RewriteCond  %{HTTP_USER_AGENT}  ^OtherAbusiveBot
RewriteRule  ^rss2html\.php$     /static.html  [L]

De esta manera, los bots aún acceden a sus páginas, pero no esa. Como es extraño que los bots (legítimos) no cumplan con las reglas, ¿tiene algún referente que empuje a los bots a su página desde otras fuentes (reenvío de nombres de dominio, ...)

ndrix
fuente
1

He resuelto el mismo problema con el script disponible en http://perishablepress.com/blackhole-bad-bots/ . Con este enfoque de agujero negro, recopilé una lista de ip maliciosas, y luego usando .htaccess las denegué. (Lo cual no es obligatorio, ya que el script en sí mismo hace la prohibición. Pero necesito reducir la carga del servidor evitando el análisis de php para los ips no deseados conocidos) en tres días mi tráfico bajó de 5 GB por día a 300 MB, lo cual es silencioso.

Consulte esta página también para obtener una lista completa de las reglas de htaccess para bloquear muchos robots basura conocidos. http://www.askapache.com/htaccess/blocking-bad-bots-and-scrapers-with-htaccess.html

Nishad TR
fuente
0
// Checks to see if this script was called by the main site pages,
// (i.e. index.php or mobile.php) and if not, then sends to main page
session_start();  
if (isset($_SESSION['views'])) {$_SESSION['views'] = $_SESSION['views']+ 1;} else {$_SESSION['views'] = 1;}
if ($_SESSION['views'] > 1) {header("Location: http://website.com/index.php");}

Este script no hace lo que dice el comentario, de hecho, hace todo lo contrario. Esto siempre dejará pasar a los bots, ya que la variable de sesión nunca se establecerá cuando el bot solicite su script. Todo lo que hará es evitar que las solicitudes legítimas (de index.php o mobile.php) llamen al script más de una vez.

Para evitar que un bot acceda a su script, solo debe permitir el acceso si una variable de sesión (o cookie) está realmente configurada. Suponiendo, por supuesto, que el bot (malicioso) no acepte cookies. (Sabemos que el verdadero robot de Google no lo hace).

Como ya se mencionó, colocar rss2html.php sobre la raíz web (fuera del espacio web público) evitaría que un bot acceda al script directamente, pero ¿dice que esto causa otros problemas? O colóquelo en un directorio y protéjalo con .htaccess. ¿O incluso podría proteger solo el archivo en .htaccess de las solicitudes directas?

Señor White
fuente
0

Configure su dominio en Cloudflare (servicio gratuito para esto). Bloquean bots maliciosos a nivel de dominio antes de que lleguen a su servidor. Tarda unos 20 minutos, nunca tiene que mono con el código.

Uso este servicio en todos mis sitios y todos los sitios de clientes. Identifican bots maliciosos basados ​​en una serie de técnicas, incluido el aprovechamiento del proyecto Honey pot.

Brett Bumeter
fuente
0

Lo que debe hacer es instalar un Certificado SSL en su servidor para apache / nginx / email / ftp. Habilite HSTS y también necesita editar su archivo ssl.conf para que SSLv2 SSLv3 TLSv1 estén deshabilitados y no permitan conexiones entrantes. Fortalezca su servidor de la manera correcta y no tendrá ningún problema con los bots.

Robert
fuente
No me queda claro qué problema SSL / TLS está resolviendo en este caso. Parece que estás rogando la pregunta y llegando al resultado. Explique cómo esta solución controla el problema.