Предыстория: У меня есть мой ресурс *.ekzorchik.ru (win.ekzorchik.ru,lin.ekzorchik.ru,net.ekzorchik.ru,ekzorchik.ru,home.ekzorchik.ru) и блокировка тех кто пытается что-то поэксплуатировать на нем, как по SSH, так и в используемой CMS системе подвергаются анализу файлов журналов и при настроенных regex правилах если искомое совпадает, то они получаются бан. За баном следит сервис Fail2ban в связке с надстройкой над iptables: либо ufw, либо firewalld.

Анализируя логи Web-сервиса (к примеру, nginx) увидел, что присутствуют варианты подбора ботами к файлам на сервере, они могут как существовать, так и нет

Вот пример:

sudo tail -f /var/log/nginx/error.log

2022/05/09 13:22:02 [error] 12430#12430: *25930235 "/usr/share/nginx/html/console/index.html" is not found (2: No such file or directory), client: 45.9.20.101, server: , request: "GET /console/ HTTP/1.1", host: "185.98.87.33:80"

2022/05/09 13:45:35 [error] 12430#12430: *25937508 open() "/usr/share/nginx/html/Autodiscover/Autodiscover.xml" failed (2: No such file or directory), client: 45.9.20.101, server: , request: "POST /Autodiscover/Autodiscover.xml HTTP/1.1", host: "185.98.87.33:80"

2022/05/09 13:55:25 [error] 12429#12429: *25940577 open() "/usr/share/nginx/html/nmaplowercheck1652093724" failed (2: No such file or directory), client: 50.31.21.11, server: , request: "GET /nmaplowercheck1652093724 HTTP/1.1", host: "185.98.87.33"

2022/05/09 13:55:25 [error] 12429#12429: *25940583 open() "/usr/share/nginx/html/HNAP1" failed (2: No such file or directory), client: 50.31.21.11, server: , request: "GET /HNAP1 HTTP/1.1", host: "185.98.87.33"

2022/05/09 13:55:25 [error] 12429#12429: *25940585 open() "/usr/share/nginx/html/evox/about" failed (2: No such file or directory), client: 50.31.21.11, server: , request: "GET /evox/about HTTP/1.1", host: "185.98.87.33"

2022/05/09 13:55:26 [error] 12429#12429: *25940591 open() "/usr/share/nginx/html/sdk" failed (2: No such file or directory), client: 50.31.21.11, server: , request: "POST /sdk HTTP/1.1", host: "185.98.87.33"

2022/05/09 14:11:38 [error] 12430#12430: *25945637 open() "/usr/share/nginx/html/_ignition/execute-solution" failed (2: No such file or directory), client: 45.9.20.101, server: , request: "GET /_ignition/execute-solution HTTP/1.1", host: "185.98.87.33:80"

2022/05/09 15:42:30 [error] 12430#12430: *25973060 open() "/usr/share/nginx/html/boaform/admin/formLogin" failed (2: No such file or

directory), client: 111.92.117.240, server: , request: "GET /boaform/admin/formLogin?username=admin&psd=admin HTTP/1.0"

2022/05/09 15:42:59 [error] 12430#12430: *25973218 open() "/usr/share/nginx/html/.aws/credentials" failed (2: No such file or directory), client: 109.237.103.118, server: , request: "GET /.aws/credentials HTTP/1.1", host: "185.98.87.33"

2022/05/09 16:27:49 [error] 12430#12430: *25986773 open() "/usr/share/nginx/html/actuator/gateway/routes" failed (2: No such file or directory), client: 45.9.20.101, server: , request: "GET /actuator/gateway/routes HTTP/1.1", host: "185.98.87.33:80"

Видя такое, я задался целью на основе строке "failed (2: No such file or directory)" с помощью fail2ban вносить этих недоброжелателей в блок лист на неделю.

  • failed (2: No such file or directory)
  • is not found (2: No such file or directory)

Делается – это так:

Шаг №1: Создаю фильтр для Fail2ban который будет разбирать строку лога error.log:

ekzorchik@ekzorchik:~$ sudo nano /etc/fail2ban/filter.d/failed.conf

[INCLUDES]
[Definition]
failregex = ^ \[error\].*open\(\).*failed.*No such file or directory\), client\: <HOST>\, server.*?$
ignoreregex =

После не забываем сохранить внесенные изменения.

Шаг №2: Проверяю, что созданный фильтр при парсинге error.log находит совпадения:

sudo fail2ban-regex /var/log/nginx/error.log /etc/fail2ban/filter.d/failed.conf

Running tests

=============

Use   failregex filter file : failed, basedir: /etc/fail2ban

Use         log file : /var/log/nginx/error.log

Use         encoding : UTF-8

Results

=======

Failregex: 19 total

|-  #) [# of hits] regular expression

|   1) [19] ^ \[error\].*open\(\).*failed.*No such file or directory\), client\: <HOST>\, server.*?$

`-

Ignoreregex: 0 total

Date template hits:

|- [# of hits] date format

|  [20] Year(?P<_sep>[-/.])Month(?P=_sep)Day 24hour:Minute:Second(?:,Microseconds)?

`-

Lines: 20 lines, 0 ignored, 19 matched, 1 missed [processed in 0.00 sec]

|- Missed line(s):

|  2022/05/09 13:22:02 [error] 12430#12430: *25930235 "/usr/share/nginx/html/console/index.html" is not found (2: No such file or directory), client: 45.9.20.101, server: , request: "GET /console/ HTTP/1.1", host: "185.98.87.33:80"

Из вывода вижу, что фильтр находит совпадения (19 matched), значит фильтр работает.

Шаг №3: Создаю действия направленное на блокировку при наличии совпадений (к примеру если используется надстройка над iptables в виде ufw):

ekzorchik@ekzorchik:~$ sudo nano /etc/fail2ban/action.d/failed.conf
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = ufw insert 1 deny from <ip> to any
actionunban = ufw delete deny from <ip> to any

После не забываем сохранить внесенные изменения.

Шаг №4: Создаю настройку через которую сервис fail2ban будет обрабатывать error.log и в случае совпадения с фильтром принимать действие, направленное на блокировку:

sudo nano /etc/fail2ban/jail.local

[failed-nginx]
#включаем созданное правило
enabled=true
#фильтр через который анализируется error.log /etc/fail2ban/filter.d/failed.conf
filter=failed
findtime=3600
#действие /etc/fail2ban/action.d/failed.conf
action=failed
#лог файл Web-сервиса nginx
logpath=/var/log/nginx/error.log
#если совпадение в логе 2 раза, то данных client попадает в бан
maxretry=2
#бан сроком на неделю
bantime=86400

После не забываем сохранить внесенные изменения.

Шаг №5: Перезапускаем сервис fail2ban для принятия внесенных изменений:

sudo systemctl restart fail2ban.service

sudo systemctl status fail2ban.service

Шаг №6: Вывожу на консоль какие задачи по анализу логов у меня выполняет fail2ban:

sudo fail2ban-client status

Status

|- Number of jail:      3

`- Jail list:   failed-nginx, ssh-ufw, wordpress-ufw

Шаг №7: Смотрю статистику обнаруженных совпадений по правилу failed-nginx:

sudo fail2ban-client status failed-nginx

Status for the jail: failed-nginx

|- Filter

|  |- Currently failed: 1

|  |- Total failed:     45

|  `- File list:        /var/log/nginx/error.log

`- Actions

|- Currently banned: 2

|- Total banned:     4

`- Banned IP list:   14.116.189.222 178.159.11.18

Отлично, теперь наиболее настырные отправляются в бан на срок, указанный в директиве bantime, у меня это 1 неделя.

На заметку: Если нужно вытащить из бан листа IP адрес, то

sudo fail2ban-client set failed-nginx unbanip 14.116.189.222

Итого, когда ко мне обратился один из подписчиков моих платных блогов на тему почему у него, появляются ошибки при чтении заметок, мой предварительный анализ выявил все что отображено в заметке выше и после вроде как ситуация нормализовалась. Я учусь и, следовательно, если что интересное узнаю, то опишу. А пока заметка завершена, с уважением автор блога Олло Александр aka ekzorchik.