Kita ngenali bot "ala" potensial lan mblokir kanthi IP

Kita ngenali bot "ala" potensial lan mblokir kanthi IP

Sugeng siang! Ing artikel kasebut, aku bakal pitutur marang kowe carane pangguna hosting biasa bisa nyekel alamat IP sing ngasilake beban sing gedhe banget ing situs kasebut lan banjur mblokir nggunakake alat hosting, bakal ana "sethithik" kode php, sawetara gambar.

Input data:

  1. Situs web digawe ing CMS WordPress
  2. Hosting Beget (iki dudu pariwara, nanging gambar panel admin bakal saka panyedhiya hosting tartamtu iki)
  3. Situs WordPress diluncurake ing endi wae ing awal 2000 lan duwe akeh artikel lan materi
  4. PHP versi 7.2
  5. WP duwe versi paling anyar
  6. Kanggo sawetara wektu saiki, situs kasebut wiwit ngasilake beban dhuwur ing MySQL miturut data hosting. Saben dina nilai iki ngluwihi 120% saka norma saben akun
  7. Miturut Yandex. Situs Metrica dibukak dening 100-200 wong saben dina

Kaping pisanan, iki ditindakake:

  1. Tabel database diresiki saka akumulasi sampah
  2. Plugins sing ora perlu dipateni, bagean kode sing wis lawas dibusak

Ing wektu sing padha, aku pengin narik kawigaten sampeyan yen opsi caching (plugin cache) dicoba, pengamatan digawe - nanging beban 120% saka siji situs ora owah lan mung bisa tuwuh.

Apa kira-kira beban ing database hosting katon kaya

Kita ngenali bot "ala" potensial lan mblokir kanthi IP
Ing sisih ndhuwur yaiku situs sing dimaksud, ing ngisor iki ana situs liyane sing duwe cms sing padha lan kira-kira lalu lintas sing padha, nanging nggawe kurang muatan.

Анализ

  • Akeh upaya sing ditindakake kanthi opsi caching data, pengamatan ditindakake sajrone pirang-pirang minggu (untunge, ing wektu iki hosting ora nate nulis yen aku dadi ala lan bakal pedhot)
  • Ana analisis lan nggoleki pitakon alon, banjur struktur database lan jinis tabel rada diganti
  • Kanggo analisis, kita utamane nggunakake AWStats sing dibangun ing (kanthi cara, mbantu ngetung alamat IP paling awon adhedhasar volume lalu lintas.
  • Metrik - metrik mung nyedhiyakake informasi babagan wong, dudu babagan bot
  • Ana upaya kanggo nggunakake plugin kanggo WP sing bisa nyaring lan mblokir pengunjung sanajan miturut negara lokasi lan macem-macem kombinasi
  • Cara sing radikal banget yaiku nutup situs sedina kanthi cathetan "We are under maintenance" - iki uga ditindakake nggunakake plugin sing misuwur. Ing kasus iki, kita ngarepake beban bakal mudhun, nanging ora nganti nol, amarga ideologi WP adhedhasar pancingan lan plugin miwiti kegiatane nalika ana "pancing", lan sadurunge "pancing" kedadeyan, panjaluk menyang database bisa wis digawe

Idea

  1. Etung alamat IP sing nggawe akeh panjaluk ing wektu sing cendhak.
  2. Rekam nomer hits menyang situs
  3. Blokir akses menyang situs adhedhasar jumlah hit
  4. Blokir nggunakake entri "Nolak saka" ing file .htaccess
  5. Aku ora nganggep opsi liyane, kaya iptables lan aturan kanggo Nginx, amarga aku nulis babagan hosting

Ide wis muncul, mula kudu ditindakake, amarga tanpa iki ...

  • Nggawe tabel kanggo nglumpukake 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;
    
  • Ayo nggawe file sing bakal dilebokake kode kasebut. Kode bakal ngrekam ing tabel calon pamblokiran lan nyimpen riwayat kanggo debugging.

    Kode file kanggo ngrekam alamat 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);
    
    

    Inti saka kode kasebut yaiku njaluk alamat IP pengunjung lan nulis ing tabel. Yen ip wis ana ing tabel, kolom cnt bakal ditambah (jumlah panjaluk menyang situs kasebut)

  • Saiki sing medeni... Saiki dheweke bakal ngobong aku amarga tumindakku :)
    Kanggo ngrekam saben panyuwunan menyang situs kasebut, kita nyambungake kode file menyang file WordPress utama - wp-load.php. Ya, kita ngganti file kernel lan persis sawise variabel global $wpdb wis ana

Dadi, saiki kita bisa ndeleng sepira kerepe iki utawa alamat IP kasebut ditandhani ing meja kita lan kanthi cangkir kopi kita katon ana ing kono saben 5 menit kanggo mangerteni gambar kasebut.

Kita ngenali bot "ala" potensial lan mblokir kanthi IP

Banjur mung nyalin IP "mbebayani", bukak file .htaccess lan tambahake menyang mburi file

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

Mekaten, saiki 94.242.55.248 - ora nduweni akses menyang situs kasebut lan ora ngasilake beban ing database

Nanging saben-saben nyalin kanthi tangan kaya iki dudu tugas sing bener, lan saliyane, kode kasebut dimaksudake kanggo otonom.

Ayo nambah file sing bakal dieksekusi liwat CRON saben 30 menit:

Kode file ngowahi .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)));

Kode file cukup prasaja lan primitif lan gagasan utama yaiku njupuk calon kanggo pamblokiran lan ngetik aturan pamblokiran ing file .htaccess antarane komentar
# start_auto_deny_list lan # end_auto_deny_list

Saiki IP "mbebayani" diblokir dhewe, lan file .htaccess katon kaya iki:

# 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

AkibatΓ©, sawise kode iki wiwit digunakake, sampeyan bisa ndeleng asil ing panel hosting:

Kita ngenali bot "ala" potensial lan mblokir kanthi IP

PS: Materi kasebut minangka penulis, sanajan aku nerbitake bagean kasebut ing situs web, aku entuk versi sing luwih lengkap babagan Habre.

Source: www.habr.com

Add a comment