Egun ona! Artikuluan kontatuko dizuet nola ohiko hostingaren erabiltzaileek gunean gehiegizko karga sortzen duten IP helbideak harrapatzen dituzten eta ondoren ostalaritza tresnak erabiliz blokeatu ditzaketen, php kodea "pixka bat" egongo da, pantaila-argazki batzuk.
Sarrerako datuak:
- CMS WordPress-en sortutako webgunea
- Hosting Beget (hau ez da iragarki bat, baina administrazio-paneleko pantaila-argazkiak ostalaritza-hornitzaile jakin honenak izango dira)
- WordPress gunea 2000. urtearen hasieran abiarazi zen nonbait eta artikulu eta material ugari ditu
- PHP bertsioa 7.2
- WP-k azken bertsioa du
- Aspalditik, gunea MySQL-n karga handia sortzen hasi zen hosting datuen arabera. Egunero balio horrek arauaren % 120 gainditzen zuen kontu bakoitzeko
- Yandex-en arabera. Metrica gunea egunean 100-200 pertsonak bisitatzen dute
Lehenik eta behin, hau egin zen:
- Datu-baseen taulak metatutako zaborrez garbitu ziren
- Behar ez ziren pluginak desgaitu ziren, zaharkitutako kodearen atalak kendu ziren
Aldi berean, zure arreta erakarri nahi nuke caching aukerak (caching pluginak) probatu zirela, behaketak egin zirela, baina gune bateko % 120ko karga ez zen aldatu eta hazi besterik ezin zen egin.
Nolakoa zen ostalaritza datu-baseen gutxi gorabeherako karga
Goialdean dago aipatutako gunea, behean cms berdinak eta gutxi gorabehera trafiko berdina duten beste gune batzuk daude, baina karga gutxiago sortzen dutenak.
Analisia
- Saiakera asko egin ziren datuen cache-aukerekin, behaketak hainbat astetan egin ziren (zorionez, denbora horretan ostalaritzak ez zidan inoiz idatzi hain gaizki nengoela eta deskonektatuko nintzela)
- Kontsulta geldoen azterketa eta bilaketa egin zen, gero datu-basearen egitura eta taula mota apur bat aldatu ziren
- Analisirako, batez ere AWStats integratua erabili dugu (bide batez, trafiko-bolumenaren arabera IP helbide txarrena kalkulatzen lagundu du.
- Metrika - metrikak pertsonei buruzko informazioa ematen du soilik, ez botei buruzkoa
- WPrako pluginak erabiltzen saiatu dira bisitariak iragazi eta blokeatu ditzaketen kokapenaren herrialdearen eta hainbat konbinazioren arabera ere.
- Erabat erradikala izan zen gunea egun batez ixtea "Mantentze lanetan gaude" oharrarekin - hau ere plugin ospetsua erabiliz egin zen. Kasu honetan, karga jaitsiko dela espero dugu, baina ez zero balioetara, WP ideologia amuetan oinarritzen baita eta plugin-ak "kako" bat gertatzen denean hasten dute beren jarduera, eta "kakoa" gertatu baino lehen, datu-baserako eskaerak egin daitezke. dagoeneko eginak izan
Idea
- Kalkulatu denbora tarte laburrean eskaera asko egiten dituzten IP helbideak.
- Erregistratu webguneko aipamen kopurua
- Blokeatu gunerako sarbidea hit-kopuruaren arabera
- Blokeatu .htaccess fitxategiko "Deny from" sarrera erabiliz
- Ez nuen beste aukerarik kontuan hartu, iptables eta Nginx-erako arauak esaterako, ostalaritzari buruz idazten ari naizelako
Ideia bat agertu da, beraz, gauzatu egin behar da, hau gabe bezala...
- Datuak pilatzeko taulak sortzea
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;
- Sortu dezagun fitxategi bat bertan kokatuko dugun kodea. Kodea blokeatzeko hautagaien tauletan grabatuko da eta arazketarako historia gordeko du.
IP helbideak grabatzeko fitxategi-kodea
<?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);
Kodearen funtsa bisitariaren IP helbidea lortu eta taula batean idaztea da. IP-a taulan badago jada, cnt eremua handituko da (gunerako eskaera kopurua)
- Orain beldurgarria... Orain erreko naute nire ekintzengatik :)
Eskaera bakoitza gunera grabatzeko, fitxategi-kodea WordPress fitxategi nagusiarekin konektatzen dugu - wp-load.php. Bai, nukleoaren fitxategia aldatzen dugu eta, hain zuzen, $wpdb aldagai globala jada existitzen den ondoren
Beraz, orain ikus dezakegu zenbateko maiztasun hau edo beste IP helbide markatzen den gure taulan eta kafe-katilu batekin 5 minutuz behin begiratzen dugu argazkia ulertzeko
Ondoren, kopiatu IP "kaltegarria", ireki .htaccess fitxategia eta gehitu fitxategiaren amaieran
Order allow,deny
Allow from all
# start_auto_deny_list
Deny from 94.242.55.248
# end_auto_deny_list
Hori da, orain 94.242.55.248 - ez du gunerako sarbiderik eta ez du datu-basean kargarik sortzen
Baina horrela eskuz kopiatzea ez da oso lan zuzena, eta gainera, kodea autonomoa izan nahi zuen.
Gehitu dezagun 30 minuturo CRON bidez exekutatuko den fitxategi bat:
Fitxategi-kodea .htaccess aldatzen
<?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)));
Fitxategiaren kodea nahiko sinplea eta primitiboa da eta bere ideia nagusia da blokeatzeko hautagaiak hartzea eta iruzkinen artean .htaccess fitxategian blokeatzeko arauak sartzea.
# start_auto_deny_list eta # end_auto_deny_list
Orain IP "kaltegarriak" beraiek blokeatzen dira, eta .htaccess fitxategiak honelako itxura du:
# 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
Ondorioz, kode hau funtzionatzen hasi ondoren, emaitza ostalaritza panelean ikus dezakezu:
PS: Materiala egilearena da, zati bat nire webgunean argitaratu badut ere, Habre-n bertsio zabalagoa lortu dut.
Iturria: www.habr.com