Tinutukoy namin ang mga potensyal na "masasamang" bot at hinarangan ang mga ito sa pamamagitan ng IP

Tinutukoy namin ang mga potensyal na "masasamang" bot at hinarangan ang mga ito sa pamamagitan ng IP

Magandang araw! Sa artikulong sasabihin ko sa iyo kung paano mahuli ng mga gumagamit ng regular na pagho-host ang mga IP address na bumubuo ng labis na pag-load sa site at pagkatapos ay i-block ang mga ito gamit ang mga tool sa pagho-host, magkakaroon ng "kaunti" ng php code, ilang mga screenshot.

Input na data:

  1. Website na ginawa sa CMS WordPress
  2. Hosting Beget (ito ay hindi isang advertisement, ngunit ang mga screenshot ng admin panel ay magmumula sa partikular na hosting provider)
  3. Ang WordPress site ay inilunsad sa isang lugar noong unang bahagi ng 2000 at may malaking bilang ng mga artikulo at materyales
  4. PHP bersyon 7.2
  5. Ang WP ay may pinakabagong bersyon
  6. Sa loob ng ilang panahon ngayon, nagsimulang makabuo ang site ng mataas na load sa MySQL ayon sa data ng pagho-host. Araw-araw lumampas ang halagang ito sa 120% ng pamantayan sa bawat account
  7. Ayon sa Yandex. Ang site ng Metrica ay binibisita ng 100-200 tao bawat araw

Una sa lahat, ito ay ginawa:

  1. Ang mga talahanayan ng database ay inalis sa mga naipon na basura
  2. Hindi pinagana ang mga hindi kinakailangang plugin, inalis ang mga seksyon ng lumang code

Kasabay nito, nais kong iguhit ang iyong pansin sa katotohanan na sinubukan ang mga pagpipilian sa pag-cache (mga plugin ng pag-cache), ginawa ang mga obserbasyon - ngunit ang pag-load ng 120% mula sa isang site ay hindi nagbabago at maaari lamang lumaki.

Ano ang hitsura ng tinatayang pagkarga sa mga database ng pagho-host

Tinutukoy namin ang mga potensyal na "masasamang" bot at hinarangan ang mga ito sa pamamagitan ng IP
Sa itaas ay ang site na pinag-uusapan, sa ibaba lamang ng iba pang mga site na may parehong mga cm at humigit-kumulang sa parehong trapiko, ngunit lumilikha ng mas kaunting pag-load.

Pagsusuri

  • Maraming mga pagtatangka ang ginawa gamit ang mga pagpipilian sa pag-cache ng data, ang mga obserbasyon ay isinagawa sa loob ng ilang linggo (sa kabutihang palad, sa panahong ito ang pagho-host ay hindi kailanman sumulat sa akin na ako ay napakasama at madidiskonekta)
  • Nagkaroon ng pagsusuri at paghahanap para sa mabagal na mga query, pagkatapos ay bahagyang binago ang istraktura ng database at uri ng talahanayan
  • Para sa pagsusuri, pangunahing ginamit namin ang built-in na AWStats (nga pala, nakatulong ito sa pagkalkula ng pinakamasamang IP address batay sa dami ng trapiko
  • Sukatan - ang sukatan ay nagbibigay lamang ng impormasyon tungkol sa mga tao, hindi tungkol sa mga bot
  • Nagkaroon ng mga pagtatangka na gumamit ng mga plugin para sa WP na maaaring mag-filter at mag-block ng mga bisita kahit na ayon sa bansang lokasyon at iba't ibang kumbinasyon
  • Ang isang ganap na radikal na paraan ay upang isara ang site para sa isang araw na may tala na "Kami ay nasa ilalim ng pagpapanatili" - ginawa din ito gamit ang sikat na plugin. Sa kasong ito, inaasahan namin na ang pag-load ay bababa, ngunit hindi sa zero na mga halaga, dahil ang WP ideology ay batay sa mga hook at ang mga plugin ay magsisimula ng kanilang aktibidad kapag may "hook" na nangyari, at bago mangyari ang "hook", ang mga kahilingan sa database ay maaaring ginawa na

Idea

  1. Kalkulahin ang mga IP address na gumagawa ng maraming kahilingan sa maikling panahon.
  2. Itala ang bilang ng mga hit sa site
  3. I-block ang access sa site batay sa bilang ng mga hit
  4. I-block gamit ang entry na β€œDeny from” sa .htaccess file
  5. Hindi ko isinaalang-alang ang iba pang mga opsyon, tulad ng mga iptable at panuntunan para sa Nginx, dahil nagsusulat ako tungkol sa pagho-host

May lumitaw na ideya, kaya kailangan itong ipatupad, dahil wala ito...

  • Paglikha ng mga talahanayan upang makaipon ng data
    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;
    
  • Gumawa tayo ng file kung saan ilalagay natin ang code. Ang code ay magtatala sa pagharang sa mga talahanayan ng kandidato at magtatago ng kasaysayan para sa pag-debug.

    File code para sa pagtatala ng mga IP address

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

    Ang kakanyahan ng code ay upang makuha ang IP address ng bisita at isulat ito sa isang talahanayan. Kung ang ip ay nasa talahanayan na, ang cnt field ay tataas (ang bilang ng mga kahilingan sa site)

  • Ngayon ang nakakatakot... Ngayon ay susunugin nila ako para sa aking mga aksyon :)
    Upang maitala ang bawat kahilingan sa site, ikinonekta namin ang file code sa pangunahing file ng WordPress - wp-load.php. Oo, binabago namin ang kernel file at tiyak pagkatapos na umiral na ang global variable na $wpdb

Kaya, ngayon ay makikita natin kung gaano kadalas ito o ang IP address na iyon ay minarkahan sa aming talahanayan at sa isang tabo ng kape ay tumitingin kami doon isang beses bawat 5 minuto upang maunawaan ang larawan

Tinutukoy namin ang mga potensyal na "masasamang" bot at hinarangan ang mga ito sa pamamagitan ng IP

Pagkatapos ay kopyahin lamang ang "nakakapinsalang" IP, buksan ang .htaccess file at idagdag ito sa dulo ng file

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

Iyon lang, ngayon 94.242.55.248 - walang access sa site at hindi bumubuo ng load sa database

Ngunit sa tuwing ang pagkopya sa pamamagitan ng kamay tulad nito ay hindi isang napaka-matuwid na gawain, at bukod pa, ang code ay nilayon na maging awtonomiya.

Magdagdag tayo ng file na isasagawa sa pamamagitan ng CRON tuwing 30 minuto:

Binabago ng file code ang .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)));

Ang code ng file ay medyo simple at primitive at ang pangunahing ideya nito ay kumuha ng mga kandidato para sa pagharang at ilagay ang mga panuntunan sa pagharang sa .htaccess na file sa pagitan ng mga komento
# start_auto_deny_list at # end_auto_deny_list

Ngayon ang mga "nakakapinsalang" IP ay naharang ng kanilang mga sarili, at ang .htaccess file ay mukhang ganito:

# 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

Bilang resulta, pagkatapos magsimulang gumana ang code na ito, makikita mo ang resulta sa panel ng pagho-host:

Tinutukoy namin ang mga potensyal na "masasamang" bot at hinarangan ang mga ito sa pamamagitan ng IP

PS: Ang materyal ay ang may-akda, kahit na nai-publish ko ang bahagi nito sa aking website, nakakuha ako ng mas pinalawak na bersyon sa Habre.

Pinagmulan: www.habr.com

Magdagdag ng komento