Magandang araw! Sa artikulong sasabihin ko sa iyo kung paano mahuli ng mga gumagamit ng regular na pagho-host ang mga IP address na bumubuo ng labis na pag-load sa site at pagkatapos ay i-block ang mga ito gamit ang mga tool sa pagho-host, magkakaroon ng "kaunti" ng php code, ilang mga screenshot.
Input na data:
- Website na ginawa sa CMS WordPress
- Hosting Beget (ito ay hindi isang advertisement, ngunit ang mga screenshot ng admin panel ay magmumula sa partikular na hosting provider)
- Ang WordPress site ay inilunsad sa isang lugar noong unang bahagi ng 2000 at may malaking bilang ng mga artikulo at materyales
- PHP bersyon 7.2
- Ang WP ay may pinakabagong bersyon
- Sa loob ng ilang panahon ngayon, nagsimulang makabuo ang site ng mataas na load sa MySQL ayon sa data ng pagho-host. Araw-araw lumampas ang halagang ito sa 120% ng pamantayan sa bawat account
- Ayon sa Yandex. Ang site ng Metrica ay binibisita ng 100-200 tao bawat araw
Una sa lahat, ito ay ginawa:
- Ang mga talahanayan ng database ay inalis sa mga naipon na basura
- Hindi pinagana ang mga hindi kinakailangang plugin, inalis ang mga seksyon ng lumang code
Kasabay nito, nais kong iguhit ang iyong pansin sa katotohanan na sinubukan ang mga pagpipilian sa pag-cache (mga plugin ng pag-cache), ginawa ang mga obserbasyon - ngunit ang pag-load ng 120% mula sa isang site ay hindi nagbabago at maaari lamang lumaki.
Ano ang hitsura ng tinatayang pagkarga sa mga database ng pagho-host
Sa itaas ay ang site na pinag-uusapan, sa ibaba lamang ng iba pang mga site na may parehong mga cm at humigit-kumulang sa parehong trapiko, ngunit lumilikha ng mas kaunting pag-load.
Pagsusuri
- Maraming mga pagtatangka ang ginawa gamit ang mga pagpipilian sa pag-cache ng data, ang mga obserbasyon ay isinagawa sa loob ng ilang linggo (sa kabutihang palad, sa panahong ito ang pagho-host ay hindi kailanman sumulat sa akin na ako ay napakasama at madidiskonekta)
- Nagkaroon ng pagsusuri at paghahanap para sa mabagal na mga query, pagkatapos ay bahagyang binago ang istraktura ng database at uri ng talahanayan
- Para sa pagsusuri, pangunahing ginamit namin ang built-in na AWStats (nga pala, nakatulong ito sa pagkalkula ng pinakamasamang IP address batay sa dami ng trapiko
- Sukatan - ang sukatan ay nagbibigay lamang ng impormasyon tungkol sa mga tao, hindi tungkol sa mga bot
- Nagkaroon ng mga pagtatangka na gumamit ng mga plugin para sa WP na maaaring mag-filter at mag-block ng mga bisita kahit na ayon sa bansang lokasyon at iba't ibang kumbinasyon
- Ang isang ganap na radikal na paraan ay upang isara ang site para sa isang araw na may tala na "Kami ay nasa ilalim ng pagpapanatili" - ginawa din ito gamit ang sikat na plugin. Sa kasong ito, inaasahan namin na ang pag-load ay bababa, ngunit hindi sa zero na mga halaga, dahil ang WP ideology ay batay sa mga hook at ang mga plugin ay magsisimula ng kanilang aktibidad kapag may "hook" na nangyari, at bago mangyari ang "hook", ang mga kahilingan sa database ay maaaring ginawa na
Idea
- Kalkulahin ang mga IP address na gumagawa ng maraming kahilingan sa maikling panahon.
- Itala ang bilang ng mga hit sa site
- I-block ang access sa site batay sa bilang ng mga hit
- I-block gamit ang entry na βDeny fromβ sa .htaccess file
- Hindi ko isinaalang-alang ang iba pang mga opsyon, tulad ng mga iptable at panuntunan para sa Nginx, dahil nagsusulat ako tungkol sa pagho-host
May lumitaw na ideya, kaya kailangan itong ipatupad, dahil wala ito...
- Paglikha ng mga talahanayan upang makaipon ng 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;
- Gumawa tayo ng file kung saan ilalagay natin ang code. Ang code ay magtatala sa pagharang sa mga talahanayan ng kandidato at magtatago ng kasaysayan para sa pag-debug.
File code para sa pagtatala ng mga IP address
<?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);
Ang kakanyahan ng code ay upang makuha ang IP address ng bisita at isulat ito sa isang talahanayan. Kung ang ip ay nasa talahanayan na, ang cnt field ay tataas (ang bilang ng mga kahilingan sa site)
- Ngayon ang nakakatakot... Ngayon ay susunugin nila ako para sa aking mga aksyon :)
Upang maitala ang bawat kahilingan sa site, ikinonekta namin ang file code sa pangunahing file ng WordPress - wp-load.php. Oo, binabago namin ang kernel file at tiyak pagkatapos na umiral na ang global variable na $wpdb
Kaya, ngayon ay makikita natin kung gaano kadalas ito o ang IP address na iyon ay minarkahan sa aming talahanayan at sa isang tabo ng kape ay tumitingin kami doon isang beses bawat 5 minuto upang maunawaan ang larawan
Pagkatapos ay kopyahin lamang ang "nakakapinsalang" IP, buksan ang .htaccess file at idagdag ito sa dulo ng file
Order allow,deny
Allow from all
# start_auto_deny_list
Deny from 94.242.55.248
# end_auto_deny_list
Iyon lang, ngayon 94.242.55.248 - walang access sa site at hindi bumubuo ng load sa database
Ngunit sa tuwing ang pagkopya sa pamamagitan ng kamay tulad nito ay hindi isang napaka-matuwid na gawain, at bukod pa, ang code ay nilayon na maging awtonomiya.
Magdagdag tayo ng file na isasagawa sa pamamagitan ng CRON tuwing 30 minuto:
Binabago ng file code ang .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)));
Ang code ng file ay medyo simple at primitive at ang pangunahing ideya nito ay kumuha ng mga kandidato para sa pagharang at ilagay ang mga panuntunan sa pagharang sa .htaccess na file sa pagitan ng mga komento
# start_auto_deny_list at # end_auto_deny_list
Ngayon ang mga "nakakapinsalang" IP ay naharang ng kanilang mga sarili, at ang .htaccess file ay mukhang ganito:
# 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
Bilang resulta, pagkatapos magsimulang gumana ang code na ito, makikita mo ang resulta sa panel ng pagho-host:
PS: Ang materyal ay ang may-akda, kahit na nai-publish ko ang bahagi nito sa aking website, nakakuha ako ng mas pinalawak na bersyon sa Habre.
Pinagmulan: www.habr.com