Nou idantifye potansyèl "sa ki mal" bots epi bloke yo pa IP

Nou idantifye potansyèl "sa ki mal" bots epi bloke yo pa IP

Bonjou! Nan atik la mwen pral di w ki jan itilizatè yo nan hosting regilye ka trape adrès IP ki jenere twòp chaj sou sit la ak Lè sa a, bloke yo lè l sèvi avèk zouti hosting, pral gen "yon ti kras" nan kòd php, kèk Ekran.

Done Antre:

  1. Sit entènèt kreye sou CMS WordPress
  2. Hosting Beget (sa a se pa yon reklam, men ekran panèl admin yo pral soti nan founisè hosting patikilye sa a)
  3. Sit WordPress la te lanse yon kote nan kòmansman ane 2000 la e li gen yon gwo kantite atik ak materyèl
  4. PHP vèsyon 7.2
  5. WP gen dènye vèsyon an
  6. Depi kèk tan kounye a, sit la te kòmanse jenere yon chaj segondè sou MySQL dapre done yo hosting. Chak jou valè sa a depase 120% nòmal pou chak kont
  7. Dapre Yandex. Se 100-200 moun vizite sit Metrica chak jou

Premye a tout, sa a te fè:

  1. Tab baz done yo te retire fatra akimile
  2. Plugins ki pa nesesè yo te enfim, seksyon kòd demode yo te retire

An menm tan an, mwen ta renmen atire atansyon ou sou lefèt ke opsyon kachèt (plugins kachèt) yo te eseye, obsèvasyon yo te fè - men chaj la nan 120% nan yon sit pa te chanje epi li te kapab sèlman grandi.

Ki sa ki chaj apwoksimatif sou baz done hosting te sanble

Nou idantifye potansyèl "sa ki mal" bots epi bloke yo pa IP
Nan tèt la se sit la nan kesyon an, jis anba a se lòt sit ki gen menm cms yo ak apeprè menm trafik la, men ki kreye mwens chaj.

Analiz

  • Anpil tantativ te fèt ak opsyon kachèt done, obsèvasyon yo te fèt sou plizyè semèn (ererezman, pandan tan sa a hosting la pa janm ekri m 'ke mwen te tèlman move epi yo ta dwe dekonekte)
  • Te gen yon analiz ak rechèch pou demann dousman, Lè sa a, estrikti baz done a ak kalite tab yo te yon ti kras chanje
  • Pou analiz, nou te itilize prensipalman AWStats yo (nan chemen an, li te ede yo kalkile pi move adrès IP ki baze sou volim trafik.
  • Metrik - metrik la bay enfòmasyon sèlman sou moun, pa sou bots
  • Te gen tantativ pou itilize grefon pou WP ki ka filtre ak bloke vizitè yo menm pa peyi kote yo ye ak divès konbinezon.
  • Yon fason konplètman radikal yo te fèmen sit la pou yon jou ak nòt la "Nou se anba antretyen" - sa a te fè tou lè l sèvi avèk Plugin la pi popilè. Nan ka sa a, nou espere chaj la tonbe, men se pa nan valè zewo, depi ideoloji WP a baze sou kwòk ak grefon kòmanse aktivite yo lè yon "kwòk" rive, epi anvan "kwòk la" rive, demann nan baz done a ka. deja fèt

Lide

  1. Kalkile adrès IP ki fè anpil demann nan yon kout peryòd de tan.
  2. Ekri kantite frape sou sit la
  3. Bloke aksè nan sit la baze sou kantite frape
  4. Bloke lè l sèvi avèk "Refize soti nan" antre nan dosye a .htaccess
  5. Mwen pa t 'konsidere lòt opsyon, tankou iptables ak règ pou Nginx, paske mwen ekri sou hosting

Yon lide te parèt, kidonk li bezwen aplike, tankou san sa a...

  • Kreye tab pou akimile done
    CREATE TABLE `wp_visiters_bot` (
    	`id` INT(11) NOT NULL AUTO_INCREMENT,
    	`ip` VARCHAR(300) NULL DEFAULT NULL,
    	`browser` VARCHAR(500) NULL DEFAULT NULL,
    	`cnt` INT(11) NULL DEFAULT NULL,
    	`request` TEXT NULL,
    	`input` TEXT NULL,
    	`data_update` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    	PRIMARY KEY (`id`),
    	UNIQUE INDEX `ip` (`ip`)
    )
    COMMENT='Кандидаты для блокировки'
    COLLATE='utf8_general_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=1;
    

    CREATE TABLE `wp_visiters_bot_blocked` (
    	`id` INT(11) NOT NULL AUTO_INCREMENT,
    	`ip` VARCHAR(300) NOT NULL,
    	`data_update` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    	PRIMARY KEY (`id`),
    	UNIQUE INDEX `ip` (`ip`)
    )
    COMMENT='Список уже заблокированных'
    COLLATE='utf8_general_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=59;
    

    CREATE TABLE `wp_visiters_bot_history` (
    	`id` INT(11) NOT NULL AUTO_INCREMENT,
    	`ip` VARCHAR(300) NULL DEFAULT NULL,
    	`browser` VARCHAR(500) NULL DEFAULT NULL,
    	`cnt` INT(11) NULL DEFAULT NULL,
    	`data_update` DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    	`data_add` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
    	PRIMARY KEY (`id`),
    	UNIQUE INDEX `ip` (`ip`)
    )
    COMMENT='История всех запросов для дебага'
    COLLATE='utf8_general_ci'
    ENGINE=InnoDB
    AUTO_INCREMENT=1;
    
  • Ann kreye yon fichye kote n ap mete kòd la. Kòd la pral anrejistre nan tab kandida bloke yo epi kenbe yon istwa pou debogaj.

    Fichye kòd pou anrejistre adrès IP

    <?php
    
    if (!defined('ABSPATH')) {
        return;
    }
    
    global $wpdb;
    
    /**
     * Вернёт конкретный IP адрес посетителя
     * @return boolean
     */
    function coderun_get_user_ip() {
    
        $client_ip = '';
    
        $address_headers = array(
            'HTTP_CLIENT_IP',
            'HTTP_X_FORWARDED_FOR',
            'HTTP_X_FORWARDED',
            'HTTP_X_CLUSTER_CLIENT_IP',
            'HTTP_FORWARDED_FOR',
            'HTTP_FORWARDED',
            'REMOTE_ADDR',
        );
    
        foreach ($address_headers as $header) {
            if (array_key_exists($header, $_SERVER)) {
    
                $address_chain = explode(',', $_SERVER[$header]);
                $client_ip = trim($address_chain[0]);
    
                break;
            }
        }
    
        if (!$client_ip) {
            return '';
        }
    
    
        if ('0.0.0.0' === $client_ip || '::' === $client_ip || $client_ip == 'unknown') {
            return '';
        }
    
        return $client_ip;
    }
    
    $ip = esc_sql(coderun_get_user_ip()); // IP адрес посетителя
    
    if (empty($ip)) {// Нет IP, ну и идите лесом...
        header('Content-type: application/json;');
        die('Big big bolt....');
    }
    
    $browser = esc_sql($_SERVER['HTTP_USER_AGENT']); //Данные для анализа браузера
    
    $request = esc_sql(wp_json_encode($_REQUEST)); //Последний запрос который был к сайту
    
    $input = esc_sql(file_get_contents('php://input')); //Тело запроса, если было
    
    $cnt = 1;
    
    //Запрос в основную таблицу с временными кондидатами на блокировку
    $query = <<<EOT
        INSERT INTO wp_visiters_bot (`ip`,`browser`,`cnt`,`request`,`input`)
            VALUES  ('{$ip}','{$browser}','{$cnt}','{$request}','$input')
             ON DUPLICATE KEY UPDATE cnt=cnt+1,request=VALUES(request),input=VALUES(input),browser=VALUES(browser)
    EOT;
    
    //Запрос для истории
    $query2 = <<<EOT
        INSERT INTO wp_visiters_bot_history (`ip`,`browser`,`cnt`)
            VALUES  ('{$ip}','{$browser}','{$cnt}')
             ON DUPLICATE KEY UPDATE cnt=cnt+1,browser=VALUES(browser)
    EOT;
    
    
    $wpdb->query($query);
    
    $wpdb->query($query2);
    
    

    Sans nan kòd la se jwenn adrès IP vizitè a epi ekri li nan yon tab. Si ip a deja nan tablo a, jaden an cnt ap ogmante (kantite demann nan sit la)

  • Koulye a, bagay la pè ... Koulye a, yo pral boule m 'pou aksyon mwen yo :)
    Pou anrejistre chak demann sou sit la, nou konekte kòd dosye a nan dosye prensipal WordPress - wp-load.php. Wi, nou chanje fichye nwayo a epi jisteman apre varyab global $wpdb la deja egziste

Se konsa, kounye a nou ka wè konbyen fwa adrès IP sa a oswa sa ki make nan tablo nou an epi ak yon tas kafe nou gade la yon fwa chak 5 minit pou konprann foto a.

Nou idantifye potansyèl "sa ki mal" bots epi bloke yo pa IP

Lè sa a, tou senpleman kopye "danjere" IP la, louvri dosye a .htaccess epi ajoute li nan fen dosye a.

Order allow,deny
Allow from all
# start_auto_deny_list
Deny from 94.242.55.248
# end_auto_deny_list

Sa a li, kounye a 94.242.55.248 - pa gen aksè a sit la epi li pa jenere chaj sou baz done a

Men, chak fwa kopye alamen tankou sa a se pa yon travay trè jis, epi anplis, kòd la te gen entansyon yo dwe otonòm.

Ann ajoute yon dosye ki pral egzekite atravè CRON chak 30 minit:

Kòd dosye modifye .htaccess

<?php

/**
 * Файл автоматического задания блокировок по IP адресу
 * Должен запрашиваться через CRON
 */
if (empty($_REQUEST['key'])) {
    die('Hello');
}

require('wp-load.php');

global $wpdb;

$limit_cnt = 70; //Лимит запросов по которым отбирать

$deny_table = $wpdb->get_results("SELECT * FROM wp_visiters_bot WHERE cnt>{$limit_cnt}");

$new_blocked = [];

$exclude_ip = [
    '87.236.16.70'//адрес хостинга
];

foreach ($deny_table as $result) {

    if (in_array($result->ip, $exclude_ip)) {
        continue;
    }

    $wpdb->insert('wp_visiters_bot_blocked', ['ip' => $result->ip], ['%s']);
}

$deny_table_blocked = $wpdb->get_results("SELECT * FROM wp_visiters_bot_blocked");

foreach ($deny_table_blocked as $blocked) {
    $new_blocked[] = $blocked->ip;
}

//Очистка таблицы
$wpdb->query("DELETE FROM wp_visiters_bot");

//echo '<pre>';print_r($new_blocked);echo '</pre>';

$file = '.htaccess';

$start_searche_tag = 'start_auto_deny_list';

$end_searche_tag = 'end_auto_deny_list';

$handle = @fopen($file, "r");
if ($handle) {

    $replace_string = '';//Тест для вставки в файл .htaccess

    $target_content = false; //Флаг нужного нам участка кода

    while (($buffer = fgets($handle, 4096)) !== false) {

        if (stripos($buffer, 'start_auto_deny_list') !== false) {
            $target_content = true;
            continue;
        }

        if (stripos($buffer, 'end_auto_deny_list') !== false) {
            $target_content = false;

            continue;
        }

        if ($target_content) {
            $replace_string .= $buffer;
        }
    }
    if (!feof($handle)) {
        echo "Ошибка: fgets() неожиданно потерпел неудачуn";
    }
    fclose($handle);
}

//Текущий файл .htaccess
$content = file_get_contents($file);

$content = str_replace($replace_string, '', $content);

//Очищаем все блокировки в файле .htaccess
file_put_contents($file, $content);

//Запись новых блокировок
$str = "# {$start_searche_tag}" . PHP_EOL;

foreach ($new_blocked as $key => $value) {
    $str .= "Deny from {$value}" . PHP_EOL;
}

file_put_contents($file, str_replace("# {$start_searche_tag}", $str, file_get_contents($file)));

Kòd dosye a byen senp ak primitif ak lide prensipal li se pran kandida pou bloke epi antre nan règ bloke nan dosye a .htaccess ant kòmantè yo.
# start_auto_deny_list ak # end_auto_deny_list

Koulye a, IP "malfezan" yo bloke pa tèt yo, ak dosye a .htaccess sanble yon bagay tankou sa a:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Order allow,deny
Allow from all

# start_auto_deny_list
Deny from 94.242.55.248
Deny from 207.46.13.122
Deny from 66.249.64.164
Deny from 54.209.162.70
Deny from 40.77.167.86
Deny from 54.146.43.69
Deny from 207.46.13.168
....... ниже другие адреса
# end_auto_deny_list

Kòm yon rezilta, apre kòd sa a kòmanse travay, ou ka wè rezilta a nan panèl hosting la:

Nou idantifye potansyèl "sa ki mal" bots epi bloke yo pa IP

PS: Materyèl la se otè a, byenke mwen pibliye yon pati nan li sou sit entènèt mwen an, mwen te resevwa yon vèsyon pi elaji sou Habre.

Sous: www.habr.com

Add nouvo kòmantè