Urang ngaidentipikasi poténsi bot "jahat" jeung meungpeuk aranjeunna ku IP

Urang ngaidentipikasi poténsi bot "jahat" jeung meungpeuk aranjeunna ku IP

Wilujeng siang! Dina artikel kuring bakal ngabejaan ka maneh kumaha pamaké tina hosting biasa bisa nyekel alamat IP nu ngahasilkeun beban kaleuleuwihan dina situs lajeng meungpeuk aranjeunna ngagunakeun parabot hosting, bakal aya "saeutik saeutik" kode php, sababaraha Potret layar.

Input data:

  1. Website dijieun dina CMS WordPress
  2. Hosting Beget (ieu sanés iklan, tapi layar admin bakal ti panyadia hosting khusus ieu)
  3. Situs WordPress diluncurkeun di mana waé dina awal 2000 sareng gaduh sajumlah ageung tulisan sareng bahan
  4. PHP Vérsi 7.2
  5. WP gaduh versi panganyarna
  6. Pikeun sawatara waktu ayeuna, situs mimiti ngahasilkeun beban tinggi dina MySQL nurutkeun data hosting. Unggal dinten nilai ieu ngaleuwihan 120% tina norma per akun
  7. Numutkeun kana Yandex. Situs Metrica dilongok ku 100-200 urang per poé

Anu mimiti, ieu dilakukeun:

  1. Tabel database diberesihan tina akumulasi sampah
  2. Plugin anu teu dipikabutuh ditumpurkeun, bagian kodeu anu luntur dipiceun

Dina waktos anu sami, kuring hoyong narik perhatian anjeun kana kanyataan yén pilihan cache (plugin cache) dicoba, observasi dilakukeun - tapi beban 120% tina hiji situs henteu robih sareng ngan ukur tiasa tumbuh.

Sakumaha perkiraan beban dina pangkalan data hosting

Urang ngaidentipikasi poténsi bot "jahat" jeung meungpeuk aranjeunna ku IP
Di luhur nyaéta situs anu dimaksud, di handap aya situs sanés anu gaduh cms anu sami sareng kirang langkung lalulintas anu sami, tapi nyiptakeun beban anu kirang.

analisis

  • Seueur usaha anu dilakukeun ku pilihan caching data, observasi dilaksanakeun salami sababaraha minggu (untungna, salami ieu hosting henteu kantos nyerat ka kuring yén kuring parah pisan sareng bakal dipegatkeun)
  • Aya analisa sareng milarian pamundut anu laun, teras struktur database sareng jinis tabel rada robih
  • Pikeun analisa, kami utamina ngagunakeun AWStats anu diwangun (ku jalan kitu, éta ngabantosan ngitung alamat IP anu paling awon dumasar kana volume lalu lintas.
  • Métrik - métrik ngan ukur masihan inpormasi ngeunaan jalma, sanés ngeunaan bot
  • Aya parantos nyobian nganggo plugins pikeun WP anu tiasa nyaring sareng meungpeuk sémah bahkan ku nagara lokasi sareng sababaraha kombinasi
  • Cara anu radikal tétéla nyaéta nutup situs sadinten kalayan catetan "Kami dina pangropéa" - ieu ogé dilakukeun nganggo plugin anu kasohor. Dina hal ieu, kami ngarepkeun beban turun, tapi henteu kana nilai nol, sabab ideologi WP dumasar kana kait sareng plugins ngamimitian kagiatanana nalika "kait" kajantenan, sareng sateuacan "kait" lumangsung, pamundut ka pangkalan data tiasa. geus dijieun

gagasan

  1. Itung alamat IP anu ngadamel seueur pamundut dina waktos anu pondok.
  2. Catet jumlah hits ka situs
  3. Blok aksés ka situs dumasar kana jumlah hits
  4. Meungpeuk ngagunakeun entri "Deny from" dina file .htaccess
  5. Kuring henteu nganggap pilihan sanés, sapertos iptables sareng aturan pikeun Nginx, sabab kuring nyerat ngeunaan hosting

Gagasan parantos muncul, janten kedah dilaksanakeun, sabab tanpa ieu ...

  • Nyieun tabél pikeun ngumpulkeun 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;
    
  • Hayu urang ngadamel file dimana urang bakal nempatkeun kode. Kode bakal ngarekam dina tabel calon blocking tur nyimpen sajarah pikeun debugging.

    Kode file pikeun ngarékam 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);
    
    

    Intina kode nyaéta kéngingkeun alamat IP sémah sareng nyerat kana méja. Upami ip parantos aya dina tabél, kolom cnt bakal ningkat (jumlah pamundut ka situs)

  • Ayeuna hal anu pikasieuneun ... Ayeuna aranjeunna bakal ngaduruk kuring pikeun tindakan kuring :)
    Pikeun ngarékam unggal pamundut ka situs, urang sambungkeun kodeu file kana file WordPress utama - wp-load.php. Leres, urang ngarobih file kernel sareng pas saatos variabel global $wpdb parantos aya

Janten, ayeuna urang tiasa ningali sabaraha sering alamat IP ieu atanapi éta ditandaan dina méja urang sareng ku cangkir kopi urang tingali di dinya sakali unggal 5 menit pikeun ngartos gambarna.

Urang ngaidentipikasi poténsi bot "jahat" jeung meungpeuk aranjeunna ku IP

Teras salin IP "ngabahayakeun", buka file .htaccess sareng tambahkeun kana tungtung file.

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

Éta éta, ayeuna 94.242.55.248 - henteu gaduh aksés kana situs sareng henteu ngahasilkeun beban dina pangkalan data

Tapi unggal waktos nyalin ku leungeun sapertos ieu sanés tugas anu leres, sareng sajaba ti éta, kodeu dimaksudkeun pikeun otonom.

Hayu urang tambahkeun file anu bakal dieksekusi via CRON unggal 30 menit:

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

Kodeu file anu cukup basajan tur primitif jeung gagasan utamina nyaeta nyandak calon pikeun blocking sarta asupkeun aturan blocking dina file .htaccess antara komentar.
# start_auto_deny_list sareng # end_auto_deny_list

Ayeuna IP "ngabahayakeun" diblokir ku nyalira, sareng file .htaccess sapertos kieu:

# 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

Hasilna, saatos kode ieu mimiti jalan, anjeun tiasa ningali hasilna dina panel hosting:

Urang ngaidentipikasi poténsi bot "jahat" jeung meungpeuk aranjeunna ku IP

PS: Bahanna mangrupikeun panulis, sanaos kuring nyebarkeun bagian éta dina halaman wéb kuring, kuring ngagaduhan versi anu langkung ageung dina Habre.

sumber: www.habr.com

Tambahkeun komentar