|
| Дата |
|
USD/RUB | 88.4375 | BTC/USD | 68098.4442 |
|
|
|
Скрипты, программы и технические решения Обсуждаем скрипты, программы и новые технологии. |
08.03.2015, 00:22
|
Start Post: Как правильно ддосить wordpress
|
автоматизирую интернеты
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,350
Бабло: $470735
|
Сразу оговорюсь, текст ниже не нарушает правил форума и подобная формулировка названия топика создана лишь для привлечения внимания сообщества, которое до сих пор почему-то продолжает использовать Wordpress без соответствующих защит, несмотря на мои многократные предупреждения за последние 3-4 года
Ниже описана опасность эксплуатации WP, которой подвержены 99,99% сайтов. Причем, ей может воспользоваться любой новичок. Что самое интересное, это не дыра, не баг, не какая-то доп.настройка или плагин....это документированная фича ядра вордпресса!
Я с ней работал несколько лет...имею ввиду, дорабатывал вордпрессы так, чтобы эта фича перестала быть настолько уязвимой, какой она является в дистрибутиве по умолчанию. Сейчас решил поделиться опытом с публикой, а она поможет "распространить" эту информацию до владельцев сайтов
DoS (Denial Of Service) = "отказ в обслуживании", т.е. это ряд мероприятий над сервером или сайтом, а в нашем случае - над вордпрессом, целью которых являются доставление проблемы с работоспособностью веб-ресурса.
DDoS - тоже самое, только действия направлены не из одного источника, а из множества. Именно DDoS отдельно рассматривать не будем, т.к. для защит от распределенных атак нужно:
1) понять алгоритм или характер DoS-а
2) отфильтровать плохие источники запросов. Если ддос не такой сильный, то,возможно, поможет этот топик.
Кстати говоря, понятия нагрузочное тестирование и стресс-тестирование имеют общее с DoS, а именно: их цель - протестировать систему (в том числе) на противостояние DoS- и DDos-атакам. Поэтому, можно сказать, ниже описан способ стресс-тестирования вашего сайта на Wordpress
Описание метода. Теория.
Мой метод тестирования (или доса, как вам удобнее) основан на встроенной возможности вордпресса сортировать объекты(посты, тайтлы, теги - все что угодно) в произвольном порядке, т.е. с помощью random. Сама фича описана на сайте вордпресса тут. Казалось бы, это удобно добавлять к любому URL вордпресса orderby=rand и содержимое списка (например, списка постов) выдается каждый раз в случайном порядке. Тоже самое касается и разработки плагинов, в классах вордпресса есть похожие механизмы получения рандомизированного списка каких-либо объектов, что тоже кажется удобным на первый взгляд и школьники с удовольствием это используют в своих плагинах, многие из которых находятся в топах на сайте wordpress.org
Но ведь каждый программист, имеющий опыт программирования (а не ковыряния пальцем в жопе), знает, что рандом - это иногда плохо, а чем ближе распределение вероятности случайной величины к нормальному ("идеальный рандом"), тем еще хуже и сложнее. Архитекторы нашего "любимого" вордпресса, почему-то решили, что посты нужно сортировать именно методом, близким к идеальному, т.е. используя функцию rand(), которая присутствует в языках программирования или sql.
А теперь подумаем, что такое сортировка в порядке беспорядка? это ведь не просто взяли первые попавшиеся элементы и выдали как есть. Нужно взять элементы и принудительно их все разложить в произвольном порядке, согласно сгенерированной последовательности случайных чисел. Во время сортировки мы всегда будем получать наихудшие расклады, т.е. сложность будет стремится к O(x*x), что очень накладно по использованию ресурсов. Вывод: сортировка данных в произвольном порядке - это очень затратная операция, которую нужно избегать как огня. И, когда нужно, опытные программисты это избегают, о чем делятся своими решениями: раз, два, три, четыре, пять ищите в гугле. Но в случае доса или стресс-тестирования сайта такая сортировка очень хорошо подходит!
То, что процессор будет чего-то делать с данными во время бесконечных сравниваний - это понятно, но как у нас обстоят дела с памятью? Тут многое будет зависеть от количества сортируемых данных: если их много, значит и памяти нужно много, если мало - то мало, но любом случае (внимание!!!) мы никак не можем закешировать данные, кеш бессилен, потому что бессмысленно кешировать бесконечно случайные наборы данных.
Возвращаясь к механизмам оперирования данных именно в вордпрессе, узнаем, что random-сортировка там делается через (my)SQL-запрос с помощью конструкции ORDER BY RAND(). Поэтому далее углубляемся в технические особенности MySQL:
1) чтобы в mysql отсортировать выбранные select-ом данные, необходимо оперировать сразу всеми данными, даже если из них нужна только малая часть. Например, если в БД 1000 постов и нужно на главной показать рандомно первые 10, mysql все равно выберет, потом отсортирует все 1000 постов и лишь затем отсечет нужные 10 элементов. Поэтому происходит оперирование всеми данными одновременно(!)
2) в mysql есть опция в настройках(my.cnf), которая определяет размер временных таблиц в памяти, превышая который, временная таблица перемещается на диск. О существовании этой переменной начинающие админы или владельцы сайтов могут и не знать, и, скорее всего, там установлено какое-то стандартное значение.
А теперь представьте, что и без того не быстрая сортировка перемещается из памяти на диск - это плохо, очень. Временные затраты по железным причинам автоматически возрастают на 1-2 порядка. Выходит, чтобы создать такую ситуацию, нужно сортировать много данных, чтобы они не уместились в памяти во временной таблице и весь процесс ушел в диск.
3) возвращаемся к выборке из 1000 постов...в mysql есть такая неприятная особенность, которая состоит в том, что чем ближе к концу нужны данные из выборки, тем дольше нужно ждать ответа от БД, т.е. запрос первых 10 постов из 1000 (LIMIT 0,10) будет намного быстрее и легче, чем последние 10 (LIMIT 990,10)
4) ну и напоследок сама выборка может быть с условиями, при которых, например затрудняется работ индексов или вообще они отсутствуют. Например, это выборка функции поиска на сайте, т.к. в mysql она будет представляться как-то так WHERE...LIKE '%key%' , а чтобы в ее результате было побольше объектов, искать следует то, что встречается в каждом объекте/посте, например: точку "." - WHERE...LIKE '%.%'
Вывод: нужно выбирать последние элементы из большой выборки, основанной на результате поиска, отсортированном рандомом.
Выполнения таких запросов можно добиться как через URI, так и через просмотр кривых плагинов, которые также не брезгают пользоваться стандартным рандомом вордпресса.
Реальный пример такого URL: http://chesser.ru/blog/ page/8/ ? s=. & orderby=rand
У меня в блоге записей мало, поэтому в диск процесс не уходит, но все равно результат невозможно кешировать, поэтому алгоритм отрабатывает ОТ и ДО. Наибольший эффект получится на вордпресс-сайтах с большим количеством постов.
Практическая часть.
Тут все просто. Понадобится любой инструмент настраиваемой отсылки http-запросов в много потоков, например, wget, curl, ваш любимый парсер или даже программа на дельфи (хотя, надеюсь, эти мамонты умерли). Тестеры используют такие инструменты, из которых многим знаком ab, а мне нравится httperf. Но тут на форуме я покажу пример bash-команды на wget:
Код:
bash> for i in {1..500}; do ( \
wget -O /dev/null --tries=100500 --waitretry=1 --timeout=0.5 \
--post-data='s=.&orderby=rand' \
--user-agent='Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' \
http://chesser.ru/blog/ > /dev/null 2>&1 &); done
Пояснения:
- timeout=0.5 - нужно подобрать опытным путем, чтобы wget успел отресолвить сервер и послать http запрос, а потом коннект должен обрубиться на полуслове, т.к. ждать его ответа смысла нет, лучше за это время еще послать десяток другой запросов
- этот пример НЕ использует особенность из п.3. Для нее необходимо предвариельно вычислять число доступных страниц результата.
- метод POST и указанный юзерагент использованы, чтобы не сильно мусорить в логах
Первоисточником этой команды пусть будет этот адрес: http://wiki.chesser.ru/CMS_Wordpress , постараюсь обновлять там информацию, если придумаю чего-нибудь еще интересное.
Способы решения проблемы:
1) основной способ решения проблемы - это не использовать Wordpress, потому что я пока молчу о других его архитектурных проблемах, которые также удобны в использовании для подобного тестирования, а кто-то наверняка уже использует В качестве альтернативы предлагаю использовать, например, Drupal 1, Drupal 2 или какие-то другие платформы, созданные разработчиками, которые хотя бы закончили школу.
2) Если от вордпресса избавиться нельзя, то проблему нужно решать либо полным удалением возможностей использования, либо модификацией функции сортировки, смысл которой заключается в том, чтобы а) уйти от стандартного качественного рандома к какому-то сильно упрощенному псевдо-рандому, б) либо кешированием результатов сортировки (рандом выборка всегда будет состоять из одного и того же набора данных) в) либо сокращением размеров выборок.
Свои услуги по оптимизации и спасении вордпресса не предлагаю, т.к. для меня это пройденный этап. По деньгам обычно стоило $100-300.
3) Также можно пытаться ловить и фильтровать такие подозрительные запросы, но их структура может меняться и в эти периоды сервер будет спать, что неприятно.
Последний раз редактировалось chesser; 08.03.2015 в 00:35.
|
|
|
08.03.2015, 01:33
|
#12
|
автоматизирую интернеты
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,350
Бабло: $470735
ТС -->
|
ТС
Цитата:
Сообщение от Hector
chesser, подожди, nginx же показывает что метод post.
|
да, что метод POST в дефолтном формате логов он показывает
но этого ты там не увидишь: s=.&orderby=rand
Цитата:
Сообщение от Hector
Если же таких запросов много то копаем дальше.
|
- ну это понятно, включаем логирование POST-данных..а ты представляешь, что это такое? )
- а вдруг это гугл так форму поиска сабмитит, мало ли? а ты вырубишь его
- если все-таки отрубил такие посты, то врубаем тоже самое, только GET-ы
- вместо точки можно искать несколько разных кейвордов одновременно, менять юзерагенты, ip и тд
от всего можно искать и найти защиту, вопрос ведь в потерянном времени/трафе
|
|
|
08.03.2015, 01:36
|
#13
|
hustle
Регистрация: 02.05.2008
Адрес: 3d world
Сообщений: 12,870
Бабло: $1717315
|
Зачем гугл будет сабмитить форму? Даже если так то сделать ему редирект на главную или запретить rand. Get тоже запрещаем для данного юзерагента и урла или отрезаем rand В самом худшем случае запретим вообще rand для всех
Короче такой дос за 5 минут отбивается.
Последний раз редактировалось Hector; 08.03.2015 в 01:50.
|
|
|
08.03.2015, 01:50
|
#14
|
автоматизирую интернеты
Регистрация: 05.07.2009
Адрес: chesser.ru
Сообщений: 3,350
Бабло: $470735
ТС -->
|
ТС
Цитата:
Сообщение от Hector
Зачем гугл будет сабмитить форму? Даже если так то сделать ему редирект на главную или запретить rand. Get тоже запрещаем для данного юзерагента и урла или отрезаем rand
|
ну мало ли зачем так можно подумать про гугл, сеошники чего только не выдумывают про него.
да, я про это писал - отключить эту "фичу"
урл может быть любой
а если отключишь только orderby=rand, то, наверняка, останутся "related posts"-like плагины, которые выводят, например, рандомные тайтлы где-нибудь на странице. В общем, любой рандом доставит хлопот )
|
|
|
08.03.2015, 03:16
|
#15
|
интересующийся
Регистрация: 16.06.2009
Сообщений: 783
Бабло: $153396
|
chesser, молодец, хорошо расписал, спасибо за статью
|
|
|
08.03.2015, 11:40
|
#16
|
Senior Member
Регистрация: 18.08.2010
Сообщений: 359
Бабло: $66120
|
Проблемы с oreder by rand() начинаются только при более менее вминяемом кол-ве записей.
Мне кажется что разрабы вп изначально для себя ставили задачу разработать CMS для "домохозяек". Соответственно и отношение к данной проблеме у них похуестичное.
|
|
|
08.03.2015, 12:10
|
#17
|
Шучу на половину
Регистрация: 23.01.2011
Сообщений: 5,835
Бабло: $1169780
|
varnish софт, 500km норм не лажает
|
|
|
08.03.2015, 12:31
|
#18
|
Шучу на половину
Регистрация: 23.01.2011
Сообщений: 5,835
Бабло: $1169780
|
вот норм плагин - w3 total cache
под cdn ставится и настраивается просто из того что пробовал cloudfront и maxcdn
тут производительность и рекомендации
http://developers.google.com/speed/pagespeed/insights/
Последний раз редактировалось Sultan; 08.03.2015 в 12:37.
|
|
|
08.03.2015, 12:44
|
#19
|
je suis Charlie
Регистрация: 19.08.2009
Сообщений: 1,641
Бабло: $255632
|
Цитата:
Сообщение от chesser
2) Если от вордпресса избавиться нельзя, то проблему нужно решать либо полным удалением возможностей использования, либо модификацией функции сортировки, смысл которой заключается в том, чтобы а) уйти от стандартного качественного рандома к какому-то сильно упрощенному псевдо-рандому, б) либо кешированием результатов сортировки (рандом выборка всегда будет состоять из одного и того же набора данных) в) либо сокращением размеров выборок.
|
Тоже столкнулся с блядским order by rand(), когда писал пирожковый линк-менеджер. На ляме линков order by rand() начинал уже конкретно тупить. Некачественный или псевдо рандом для моей задачи не подходили, поэтому решил проблему так:
запрос
Код:
SELECT * FROM `links` WHERE `active`='1' ORDER BY RAND()
превращаем в
Код:
SELECT `links`.* FROM (SELECT id FROM `links` WHERE `active`='1' ORDER BY RAND() ) as ids JOIN `links` ON `links`.id = ids.id
то есть урезаем рандомную выборку до одного поля (id), суем это во временную таблицу, а потом уже дергаем все по этим айди, но уже без рандома.
|
|
|
08.03.2015, 12:53
|
#20
|
Senior Member
Регистрация: 18.08.2010
Сообщений: 359
Бабло: $66120
|
mr.Charlie, если ты выбираешь все записи, без лимита, то почему бы не перемешать их уже средствами php и прочего. Там на много быстрее
|
|
|
08.03.2015, 13:08
|
#21
|
Senior Member
Регистрация: 24.09.2009
Сообщений: 820
Бабло: $106455
|
Для тех, кому не хочется читать много букв, решение для nginx бесплатно-без смс:
PHP код:
if ($args ~ orderby=rand) {
return 403;
}
ps Да, и то, что Drupal заруливает Wordpress - очень толсто.
Лень писать простыню, где wp проводит шершавым по губам друпалу, уже исписано тысячи раз.
|
|
|
|