Biz potentsial "yomon" botlarni aniqlaymiz va ularni IP orqali bloklaymiz

Biz potentsial "yomon" botlarni aniqlaymiz va ularni IP orqali bloklaymiz

Xayrli kun! Maqolada men sizga oddiy xosting foydalanuvchilari qanday qilib saytga haddan tashqari yukni keltirib chiqaradigan IP-manzillarni qo'lga olishlari va keyin hosting vositalaridan foydalangan holda ularni blokirovka qilishlari mumkinligini aytib beraman, PHP kodining "bir oz" kodi, bir nechta skrinshotlar bo'ladi.

Kirish ma'lumotlari:

  1. Veb-sayt CMS WordPress-da yaratilgan
  2. Hosting Beget (bu reklama emas, lekin administrator paneli skrinshotlari ushbu xosting provayderidan olinadi)
  3. WordPress sayti 2000-yil boshida ishga tushirilgan va juda ko'p maqola va materiallarga ega
  4. PHP versiyasi 7.2
  5. WP eng so'nggi versiyasiga ega
  6. Bir muncha vaqtdan beri sayt hosting ma'lumotlariga ko'ra MySQL-da yuqori yuk hosil qila boshladi. Har kuni bu qiymat har bir hisob uchun normaning 120% dan oshdi
  7. Yandex ma'lumotlariga ko'ra. Metrica saytiga kuniga 100-200 kishi tashrif buyuradi

Avvalo, bu amalga oshirildi:

  1. Ma'lumotlar bazasi jadvallari to'plangan axlatdan tozalandi
  2. Keraksiz plaginlar o'chirildi, eskirgan kod bo'limlari olib tashlandi

Shu bilan birga, men sizning e'tiboringizni keshlash variantlari (keshlash plaginlari) sinab ko'rilganiga, kuzatishlar o'tkazilganiga e'tiboringizni qaratmoqchiman - lekin bitta saytdan 120% yuk o'zgarmagan va faqat o'sishi mumkin edi.

Xosting ma'lumotlar bazalariga taxminiy yuk qanday ko'rinishga ega edi

Biz potentsial "yomon" botlarni aniqlaymiz va ularni IP orqali bloklaymiz
Yuqorida ko'rib chiqilayotgan sayt, pastda bir xil sms va taxminan bir xil trafikga ega bo'lgan, ammo kamroq yuk yaratadigan boshqa saytlar mavjud.

Tahlil

  • Ma'lumotlarni keshlash opsiyalari bilan ko'plab urinishlar qilindi, kuzatishlar bir necha hafta davomida o'tkazildi (xayriyatki, bu vaqt davomida hosting menga hech qachon yomon ekanligimni va aloqani uzib qo'yishimni yozmagan)
  • Sekin so'rovlarni tahlil qilish va qidirish amalga oshirildi, keyin ma'lumotlar bazasi tuzilishi va jadval turi biroz o'zgartirildi
  • Tahlil qilish uchun biz birinchi navbatda o'rnatilgan AWStats-dan foydalandik (aytmoqchi, u trafik hajmiga qarab eng yomon IP-manzilni hisoblashga yordam berdi.
  • Metrik - ko'rsatkich botlar haqida emas, balki faqat odamlar haqida ma'lumot beradi
  • WP uchun plaginlardan foydalanishga urinishlar mavjud bo'lib, ular tashrif buyuruvchilarni hatto joylashgan mamlakat va turli kombinatsiyalar bo'yicha filtrlashi va blokirovka qilishi mumkin.
  • "Bizga texnik xizmat ko'rsatilmoqda" yozuvi bilan saytni bir kunga yopish mutlaqo radikal usul bo'ldi - bu mashhur plagin yordamida ham amalga oshirildi. Bunday holda, biz yuk tushishini kutamiz, lekin qiymatlar nolga teng emas, chunki WP mafkurasi ilgaklarga asoslangan va plaginlar "kanca" paydo bo'lganda o'z faoliyatini boshlaydi va "kanca" paydo bo'lishidan oldin ma'lumotlar bazasiga so'rovlar mumkin. allaqachon qilingan

Fikr

  1. Qisqa vaqt ichida juda ko'p so'rovlar yuboradigan IP manzillarini hisoblang.
  2. Saytga tashriflar sonini yozib oling
  3. Xitlar soniga qarab saytga kirishni bloklash
  4. .htaccess faylidagi "Rad etish" yozuvi yordamida blokirovka qiling
  5. Men Nginx uchun iptables va qoidalar kabi boshqa variantlarni ko'rib chiqmadim, chunki men hosting haqida yozyapman

G'oya paydo bo'ldi, shuning uchun uni amalga oshirish kerak, chunki busiz ...

  • Ma'lumotlarni to'plash uchun jadvallar yaratish
    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;
    
  • Keling, kodni joylashtiradigan fayl yarataylik. Kod blokirovka qiluvchi nomzodlar jadvallarida qayd etiladi va disk raskadrovka tarixini saqlaydi.

    IP manzillarini yozish uchun fayl kodi

    <?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);
    
    

    Kodning mohiyati tashrif buyuruvchining IP-manzilini olish va uni jadvalga yozishdir. Agar IP allaqachon jadvalda bo'lsa, cnt maydoni ko'payadi (saytga so'rovlar soni)

  • Endi qo'rqinchli narsa... Endi meni qilmishim uchun kuydirishadi :)
    Saytga har bir so'rovni yozib olish uchun biz fayl kodini asosiy WordPress fayliga ulaymiz - wp-load.php. Ha, biz yadro faylini o'zgartiramiz va $wpdb global o'zgaruvchisi allaqachon mavjud bo'lgandan keyin

Shunday qilib, endi biz u yoki bu IP manzil jadvalimizda qanchalik tez-tez belgilanganligini ko'rishimiz mumkin va biz rasmni tushunish uchun har 5 daqiqada bir marta kofe bilan qaraymiz.

Biz potentsial "yomon" botlarni aniqlaymiz va ularni IP orqali bloklaymiz

Keyin shunchaki "zararli" IP-dan nusxa oling, .htaccess faylini oching va uni faylning oxiriga qo'shing.

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

Mana, endi 94.242.55.248 - saytga kirish imkoni yo'q va ma'lumotlar bazasida yuk yaratmaydi

Ammo har safar qo'lda nusxa ko'chirish unchalik to'g'ri ish emas va bundan tashqari, kod avtonom bo'lishi kerak edi.

Har 30 daqiqada CRON orqali bajariladigan faylni qo'shamiz:

.htaccess fayl kodi o'zgartirilmoqda

<?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)));

Fayl kodi juda oddiy va ibtidoiy bo'lib, uning asosiy g'oyasi blokirovka qilish uchun nomzodlarni qabul qilish va izohlar orasiga .htaccess fayliga blokirovka qilish qoidalarini kiritishdir.
# boshlash_avto_rad etish_ro'yxati va # avtomatik_rad etish_ro'yxatini tugatish

Endi "zararli" IP-lar o'z-o'zidan bloklanadi va .htaccess fayli quyidagicha ko'rinadi:

# 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

Natijada, ushbu kod ishlay boshlagandan so'ng, natijani hosting panelida ko'rishingiz mumkin:

Biz potentsial "yomon" botlarni aniqlaymiz va ularni IP orqali bloklaymiz

PS: Material muallifga tegishli, garchi men uning bir qismini veb-saytimda e'lon qilgan bo'lsam ham, Habre-da kengaytirilgan versiyasini oldim.

Manba: www.habr.com

a Izoh qo'shish