
Roj baş! Di gotarê de ez ê ji we re vebêjim ka bikarhênerên mêvandariya birêkûpêk çawa dikarin navnîşanên IP-yê yên ku li ser malperê barek zêde çêdikin bigirin û dûv re wan bi karanîna amûrên mêvandariyê asteng bikin, dê "piçek" koda php-ê, çend dîmenên dîmenderê hebin.
Daneyên têketinê:
- Malper li ser CMS-ê hatî çêkirin WordPress
- Hosting Beget (ev reklam nîne, lê ekranên rêveberiyê dê ji vê dabînkerê mêvandariyê bin)
- WordPress Malper di destpêka salên 2000an de hate destpêkirin û hejmareke mezin ji gotar û materyalan tê de hene.
- Guhertoya PHP 7.2
- WP guhertoya herî dawî heye
- Demek berê, malper li gorî daneyên mêvandariyê dest bi hilberandina barek mezin li MySQL kir. Her roj ev nirx ji sedî 120 ji normê her hesabek derbas bû
- Li gorî Yandex. Malpera Metrica rojane ji hêla 100-200 kesan ve tê ziyaret kirin
Berî her tiştî, ev hate kirin:
- Tabloyên databasê ji çopê kombûyî hatin paqijkirin
- Pêvekên nehewce hatin neçalak kirin, beşên koda kevnar hatin rakirin
Di heman demê de, ez dixwazim bala we bikişînim ser vê yekê ku vebijarkên caching (pêvekên caching) hatin ceribandin, çavdêrî hatin kirin - lê barkirina% 120 ji yek malperê neguherî bû û tenê dikaribû mezin bibe.
Barkirina nêzîkê li ser databasên mêvandariyê çawa xuya dikir

Li jor malpera navborî heye, hema li jêr malperên din hene ku xwedî heman cms û hema hema heman seyrûseferê ne, lê kêm bar diafirînin.
Analysis
- Gelek hewildan bi vebijarkên vegirtina daneyan re hatin kirin, çavdêrî di nav çend hefteyan de hatin kirin (bextane, di vê demê de mêvandar qet ji min re nenivîsand ku ez ew qas xirab bûm û dê were qut kirin)
- Analîzek û lêgerînek ji bo pirsên hêdî bû, dûv re avahiya databasê û celebê tabloyê hinekî hate guheztin
- Ji bo analîzê, me di serî de AWStats-yên çêkirî bikar anîn (bi awayê, ew alîkariya hesabkirina navnîşana IP-ya herî xirab a li ser bingeha qebareya trafîkê kir
- Metrîk - metrîk tenê li ser mirovan, ne li ser botan agahdarî dide
- Hewldan hene ku ji bo WP-ê pêvekan bikar bînin ku dikarin mêvanan fîlter bikin û asteng bikin tewra li gorî welatê cîh û hevbendiyên cihêreng.
- Rêyek bi tevahî radîkal derket holê ku girtina malperê ji bo rojekê bi nîşeya "Em di bin parastinê de ne" - ev jî bi karanîna pêveka navdar hate kirin. Di vê rewşê de, em li bendê ne ku bar dakeve, lê ne ji nirxan sifir, ji ber ku îdeolojiya WP-ê li ser çengelan û pêvekan bingeha xwe digire dema ku "hook" çêbibe dest bi çalakiya xwe dikin, û berî ku "hook" çêbibe, daxwazên ji databasê re dikarin jixwe tê çêkirin
Idea
- Navnîşanên IP-ê yên ku di demek kurt de gelek daxwazan dikin hesab bikin.
- Hejmara lêdanên malperê tomar bikin
- Li ser bingeha hejmara lêdan gihîştina malperê asteng bikin
- Di pelê .htaccess de têketina "Inkarkirina ji" asteng bikin
- Min vebijarkên din, mîna iptables û qaîdeyên ji bo Nginx-ê nehesiband, ji ber ku ez li ser mêvandariyê dinivîsim
Fikrek derketiye holê, ji ber vê yekê pêdivî ye ku were bicîh kirin, wekî bêyî vê yekê ...
- Afirandina tabloyan ji bo berhevkirina daneyan
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; - Ka em pelek ku em ê kodê tê de bi cih bikin çêbikin. Kod dê di tabloyên berendamên astengker de tomar bike û ji bo xeletkirinê dîrokek bigire.
Koda pelê ji bo tomarkirina navnîşanên IP-yê
<?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);Esasê kodê ev e ku meriv navnîşana IP-ya mêvanê bigire û wê li tabloyek binivîse. Ger ip jixwe di tabloyê de be, dê qada cnt zêde bibe (hejmara daxwazên malperê)
- Niha tiştê tirsnak... Niha ew ê min ji bo kirinên min bişewitînin :)
Ji bo tomar kirina her daxwazek ji malperê re, em koda pelê di pelê sereke de vedihewînin. WordPress — wp-load.php. Belê, em pelê bingehîn diguherînin, û bi taybetî piştî ku guhêrbarê gerdûnî $wpdb jixwe heye.
Ji ber vê yekê, naha em dikarin bibînin ka çend caran ev an wê navnîşana IP-yê di tabloya me de tê nîşankirin û bi qehweyek em her 5 hûrdem carekê li wir dinêrin da ku wêneyê fam bikin.

Dûv re tenê IP-ya "xisardar" kopî bikin, pelê .htaccess vekin û li dawiya pelê zêde bikin.
Order allow,deny
Allow from all
# start_auto_deny_list
Deny from 94.242.55.248
# end_auto_deny_list
Ew e, naha 94.242.55.248 - ne gihîştina malperê ye û ne li ser databasê bar dike
Lê her car kopîkirina bi desta bi vî rengî ne karekî pir rast e, û ji bilî vê, kod armanc bû ku xweser be.
Ka em pelek ku dê her 30 hûrdem carekê bi CRON-ê were darve kirin lê zêde bikin:
Koda pelê diguherîne .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)));
Koda pelê pir sade û primitive e û ramana wê ya sereke ev e ku meriv berendamên astengkirinê bigire û qaîdeyên astengkirinê di pelê .htaccess de di navbera şîroveyan de binivîsîne.
# start_auto_deny_list and # end_auto_deny_list
Naha IP-yên "xisardar" bi xwe têne asteng kirin, û pelê .htaccess bi vî rengî xuya dike:
# 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
Wekî encamek, piştî ku ev kod dest bi xebatê dike, hûn dikarin encamê di panela mêvandariyê de bibînin:

PS: Materyal a nivîskar e, her çend min beşek jê di malpera xwe de weşand, min guhertoyek berfirehtir li ser Habre girt.
Source: www.habr.com
