Проблема: стандартная нагрузка 4-9%, через время увеличилась нагрузка, но некогда было разбираться и вот в одно утро за несколько часов возрастает до 100%. По списку запросов множество каждую секунду идет пост запросов на адрес /admin/
Быстрое решение: URL переносим там выдаем 403 или вообще ничего (через CaddyFile), но это не дело, надо блочить через firewall. Сделаем это!
У насполучается своего рода honecomb - сладкая приманка для ботов, наши люди не заходят на эти адреса админки, поэтому все кто туда что-то шлет - будут добавлены в блок.
Быстрое решение:
Так как у нас цепь из Caddy - nginx - php-fpm. Мы можем выбрубить в двух местах:
- /var/www/CaddyFile:
#opencart proxy yo nginx
site.com {
root * /var/www/site.com/upload
header -Server
encode gzip zstd@notadmin {
not { path /admin* }
}
reverse_proxy @notadmin 127.0.0.1:8088
} -
NGINX (/etc/nginx/sites-available/site.com):
#limit requests to admin page
location /admin {
deny all;
}
Это остановит на первое время атаку. Но нужно другое. Воспользуемся fail2ban и лимитером запросов от nginx:
Бан по лимиту запросов nginx c помощью fail2ban
1. Настраиваем nginx rate limiter
Сверху файла конфига сайта (до раздела server) нам нужно прописать настройку real_ip так как мы за прокси (Caddy) и ip адрес будет не тот. Ниже создаем две зоны: 1. по запросам к админке с максимум запросов 20 в минуту (раз в 3 секунды) и 2. в общем для админки если будет много ip и будет нападение, чтобы просто отключилась админка и все, не испортила работу сайта в целом.
#to not use $xforwarded but have real user IP behind Caddy proxy
set_real_ip_from 127.0.0.1/16;
real_ip_header X-Forwarded-For;#rate limiter for catalog and admin
limit_req_zone $binary_remote_addr zone=req_admin:10m rate=20r/m;
limit_req_zone $server_name zone=srv_admin:10m rate=10r/s;
В самом разделе дописываем лимиты:
#limit requests to admin page
location /admin {
#no more than 1r per sec from one IP
limit_req zone=req_admin burst=6;
#no more than 10r for /admin/ page in 1 sec
limit_req zone=srv_admin burst=10;
#deny all;
}
burst указывает сколько можно разрешить одновременно отправленных запросов, например когда пользователь заходит в админку ему подгружается весь интерфейс, данные с дашборда, возможно ему нужно много запросов, но потом он сидит и пишет текст и запросов будет уже меньше 1 за 3 секунды, вот чтобы дать ему сделать эти запросы сразу, ставим такую штуку. При этом запросы становятся в очередь, что визуально может казаться как долгий ответ от сервера. Можно этого избежать если ввести nodelay, но для админки это не нужно, пусть ждут.
Теперь nginx сообщает в error.log о всех блокировках по лимитам, надо дать читать это фейл2бану и блокировать негодников. Для проверки можно написать: tail /var/log/site.com.error.log -f
2. Настройка fail2ban для nginx лимитов от ddos
В современных версиях он уже знает все что нужно и имеет преднастроенные фильтры, достаточно только скопировать конфиг (иначе он затрется при обновлении версии)
cp /etc/fail2ban/jail.{conf,local}
и в нем:
- находим раздел nginx-limit... и пишем enabled = true для активации этого анализатора
- сверху находим параметр "increment" и вкючаем его (разкомментируем), чтобы при каждом новом обнаружении IP его банило на дольшее время.
Для проверки можно запросить статус fail2ban-client status nginx-limit-req
Fail2Ban при превышении кол-ва ошибок банит IP вначале на 10минут (по умолчанию), потом на 20, потом на 40, потом на 80 и т.д. В момент большой атаки, можно увеличить базовые 10m на что-то по серьезнее, чтобы быстро пробанить "плохие" IP.
Ускоряем первый бан по IP
В моем случае, была атака ровно на url админки, я перенес админку на другой URL и теперь админка может быть место приманки, для ускорения бана настроим fail2ban фильтр, который отследит в логах обращение к админке и быстрее забанит их, без всяких лимитов.
1. Создаем фильтр fail2ban
Создаем файл фильтра (длинное название файла нельзя, максимум 25 символов)
nano /etc/fail2ban/filter.d/nginx-tps-admpath.conf
тут и POST и GET запросы, хотя атака была именно ПОСТами, может надо чисто его оставить, чтобы нормально админкой пользоваться.
[Definition]
failregex = ^<HOST>[^PG]+(POST|GET) /admin/ HTTP
ignoreregex =
2. В настройка jail.local добавляем новый раздел:
[nginx-tps-admpath]
enabled = true
port = http,https
logpath = /var/log/nginx/nfeya.com.access.log
maxretry = 1
bantime = 3d
Перезапускаем fail2ban: service fail2ban restart
Проверяем как наши дела: tail -f /var/log/fail2ban.log или fail2ban-client status nginx-tps-admpath
- Log in to post comments