Один из моих серверов пару дней назад подвергся DDoS-атаке, которая длилась 4 дня. Ниже представлен фрагмент логов запроса:
36.224.180.253 - - [14/May/2013:03:11:46 +0800] "GET //?f5b2fd2f860dc=9597624054932145 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:50 +0800] "GET //?d69e553a2e8cc=8383534686131949 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:53 +0800] "GET //?cd28bceecb2f7=8014028628342069 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:59 +0800] "GET //?e39ba4d777ca3=8890936876339672 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:02 +0800] "GET //?3bc0dd265e14b=2334116190596257 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:06 +0800] "GET //?8b645989c8334=5444999657995141 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:09 +0800] "GET //?bb1f56833c451=7309469290160174 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:11 +0800] "GET //?5fb9da415957e=3739296350043726 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
Не говоря уже об IP, это всего лишь один из массовых запросов. Существует более 3000+ разных IP-адресов, использующих один и тот же шаблон запросов GET.
Я использую Nginx (nginx-1.2.8-1.el6.ngx.x86_64) за Varnish (varnish-3.0.3-1.el6.x86_64).
У меня вопрос, как перенаправить такой запрос на конкретную страницу, скажем, 404.html?
Перезапись в Nginx работает только с путями, поэтому вам нужно использовать сравнение переменных отдельно, чтобы идентифицировать их. То, что вы просили, будет выглядеть так:
if ($args ~ "([a-f0-9]{12,})=([a-f0-9]{12,})" ){
rewrite ^/$ /404_rewrite?;
}
location /404_rewrite {
return 404;
}
Соответствие аргументов должно быть заключено в кавычки, иначе {
и }
запутает Nginx.
В ?
в конце перезаписи Nginx отбрасывает все параметры, а не добавляет их к перезаписанному URL-адресу.
Однако вы можете захотеть, чтобы Nginx пытался задерживать каждый запрос в DOS, а не обрабатывать их как можно быстрее.
limit_req_zone $binary_remote_addr zone=dos_attack:20m rate=30r/m;
if ($args ~ "([a-f0-9]{12,})=([a-f0-9]{12,})" ){
rewrite ^/$ /404_rewrite?;
}
location /404_rewrite {
limit_req zone=dos_attack burst=1;
internal;
return 404;
}
Что это значит:
Установите количество запросов на 30р / мин, что составляет 30 запросов в минуту или один запрос каждые две секунды.
Устанавливает пакет на 1. Для нормального ограничения скорости пакет устанавливается на> 1, чтобы позволить клиентам не ограничиваться, если они случайно превышают ограничение скорости в течение короткого периода времени.
Выделяет 20 мегабайт для хранения информации о зоне ограничения скорости. Согласно документация по ограничению скорости каждый $binary_remote_addr
занимает 64 байта для хранения, поэтому это ограничение скорости будет работать до пары сотен тысяч отдельных машин, выполняющих DOS. Если бы машин было больше, ограничение скорости вышло бы из строя.