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:
- Veb-sayt CMS WordPress-da yaratilgan
- Hosting Beget (bu reklama emas, lekin administrator paneli skrinshotlari ushbu xosting provayderidan olinadi)
- WordPress sayti 2000-yil boshida ishga tushirilgan va juda ko'p maqola va materiallarga ega
- PHP versiyasi 7.2
- WP eng so'nggi versiyasiga ega
- 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
- Yandex ma'lumotlariga ko'ra. Metrica saytiga kuniga 100-200 kishi tashrif buyuradi
Avvalo, bu amalga oshirildi:
- Ma'lumotlar bazasi jadvallari to'plangan axlatdan tozalandi
- 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
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
- Qisqa vaqt ichida juda ko'p so'rovlar yuboradigan IP manzillarini hisoblang.
- Saytga tashriflar sonini yozib oling
- Xitlar soniga qarab saytga kirishni bloklash
- .htaccess faylidagi "Rad etish" yozuvi yordamida blokirovka qiling
- 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.
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:
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