С помощью fail2ban нетрудно выполнить блокировку. Не буду подробно рассказывать про настройку fail2ban, так как это не тема заметки. Покажу, как я забанил тех, от кого сыпется много 404 кодов ответа веб сервера.
Для начала создаём правило фильтрации в директории
/etc/fail2ban/filter.d. Назвал его nginx-4xx.conf:[Definition]#failregex = ^<HOST>.*"(GET|POST).*" (404|429) .*$failregex = ^<HOST>.*"(GET|POST).*" *.* (status=404|status=429) .*$ignoreregex =Закомментированная строка подойдёт для стандартного формата логов Nginx или Apache. Вторая для моего изменённого. Я обычно использую свой формат, если собираю логи в ELK и анализирую. У меня есть набор готовых grok фильтров для этого. Вот мой модернизированный формат логов:
log_format full '$remote_addr - $host [$time_local] "$request" ' 'request_length=$request_length ' 'status=$status bytes_sent=$bytes_sent ' 'body_bytes_sent=$body_bytes_sent ' 'referer=$http_referer ' 'user_agent="$http_user_agent" ' 'upstream_status=$upstream_status ' 'request_time=$request_time ' 'upstream_response_time=$upstream_response_time ' 'upstream_connect_time=$upstream_connect_time ' 'upstream_header_time=$upstream_header_time';Соответственно, получаем вот такую запись в логе:
178.218.43.55 - site01.ru [01/Oct/2024:13:46:24 +0300] "GET /about HTTP/2.0" request_length=123 status=200 bytes_sent=489 body_bytes_sent=8 referer=https://site01.ru/ user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101" upstream_status=200 request_time=0.075 upstream_response_time=0.069 upstream_connect_time=0.000 upstream_header_time=0.069Для тех, кто использует logstash, покажу grok фильтр для этого формата. Он позволяет анализировать некоторые метрики и выводить их на графики и дашборды. Даю для справки без объяснений, так как это отдельная большая тема.
%{IPORHOST:remote_ip} - %{DATA:virt_host} \[%{HTTPDATE:access_time}\] \"%{WORD:http_method} %{DATA:url} HTTP/%{NUMBER:http_version}\" request_length=%{INT:request_length} status=%{INT:status} bytes_sent=%{INT:bytes_sent} body_bytes_sent=%{NUMBER:body_bytes_sent} referer=%{DATA:referer} user_agent=\"%{DATA:user_agent}\" upstream_status=%{DATA:upstream_status} request_time=%{NUMBER:request_time} upstream_response_time=%{DATA:upstream_response_time} upstream_connect_time=%{DATA:upstream_connect_time} upstream_header_time=%{DATA:upstream_header_time}Приведённая в
nginx-4xx.conf регулярка находит 404 и 429 ответы в таком логе. Я не силён в написании регулярок, поэтому хз, правильно составил или нет, но на практике работает. В составлении регулярок помогают вот эти сервисы:⇨ https://regex101.com/
⇨ https://regexper.com/
Постоянно ими пользуюсь. Вот тут была хорошая подборка по этой теме. Дальше создаём файл настроек блокировки в
/etc/fail2ban/jail.d, назвал его так же nginx-4xx.conf:[nginx-4xx]enabled = truefilter = nginx-4xxport = http,httpsaction = iptables-multiport[name=Nginx404, port="http,https", protocol=tcp]logpath = /web/sites/*/logs/access.logmaxretry = 30findtime = 10mbantime = 30mБаню на 30 минут тех, кто за последние 10 минут получил 30 раз 404 ответ. На мой взгляд это достаточно мягкое условие, которое отсечёт явных ботов, но не тронет легитимных пользователей.
Если кто-то тоже банит по признаку 404 ответа, поделитесь опытом, как это лучше делать и к каким проблемам может привести. Я немного понаблюдал, вроде никто лишний не попадается на это правило.
#fail2ban #webserver