Создайте фильтр cakephp для fail2ban

#regex #logging #cakephp #filter #fail2ban

#регулярное выражение #ведение журнала #cakephp #Фильтр #fail2ban

Вопрос:

я хотел бы создать фильтр в fail2ban для поиска и блокировки неверного запроса, например «Класс контроллера * не найден». Для решения этой проблемы я создал файл cakephp.conf в каталоге filter.d в fail2ban. Содержимое:

 [Definition]

failregex = ^[0-9]{4}-[0-9]{2}-[0-9]{2}.*Error:.*nStack Trace:n(-.*|n)*n.*n.*nClient IP: <HOST>n$

ignoreregex =
  

Мой пример журнала ошибок выглядит следующим образом:

 ...
2020-10-08 19:59:46 Error: [CakeHttpExceptionMissingControllerException] Controller class Webfig could not be found. in /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php on line 158
Stack Trace:
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php:46
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/BaseApplication.php:249
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:77
- /home/myapplication/htdocs/vendor/cakephp/authentication/src/Middleware/AuthenticationMiddleware.php:122
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:77
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php:146
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:58
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php:172
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Routing/Middleware/AssetMiddleware.php:68
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php:121
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:73
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Runner.php:58
- /home/myapplication/htdocs/vendor/cakephp/cakephp/src/Http/Server.php:90
- /home/myapplication/htdocs/webroot/index.php:40

Request URL: /webfig/
Referer URL: http://X.X.X.X/webfig/
Client IP: X.X.X.X
...

  
  • X.X.X заменяются

Но я не могу сопоставить какие-либо IP-адреса. Тестер fail2ban говорит:

 root@test:~# fail2ban-regex /home/myapplication/htdocs/logs/error.log /etc/fail2ban/filter.d/cakephp.conf

Running tests
=============

Use   failregex filter file : cakephp, basedir: /etc/fail2ban
Use         log file : /home/myapplication/htdocs/logs/error.log
Use         encoding : UTF-8


Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [719] {^LN-BEG}ExYear(?P<_sep>[-/.])Month(?P=_sep)Day(?:T|  ?)24hour:Minute:Second(?:[.,]Microseconds)?(?:s*Zone offset)?
`-

Lines: 15447 lines, 0 ignored, 0 matched, 15447 missed
[processed in 10.02 sec]

Missed line(s): too many to print.  Use --print-all-missed to print all 15447 lines
  

я не вижу никаких проблем. Вы можете мне помочь? 🙂
Спасибо

Ответ №1:

Проблема в том, что ваш журнал плохо подходит для анализа — это многострочный лог-файл (IP-адрес указывается в другой строке в качестве сообщения об ошибке). Не говоря уже о том, что строка с IP не имеет никакого идентификатора (общая информация со строкой сбоя), может быть еще хуже, если несколько сообщений пересекаются (таким образом, IP-адрес клиента из другого сообщения, которое не является сбоем, приходит после сообщения об ошибке).

Если вы можете изменить формат журнала, лучше сделайте это (чтобы дата, IP и знак сбоя были в одной строке), например, если вы используете nginx, организуйте условное ведение журнала доступа из php-location в случае ошибки, как это. Для получения дополнительной информации см. Fail2ban :: wiki :: Best practice .

Если вы не можете этого сделать (лучше было бы его изменить), вы можете использовать многострочную буферизацию и синтаксический анализ с использованием maxlines параметра и <SKIPLINES> регулярного выражения.

Ваш фильтр будет примерно таким:

 [Definition]

# we ignore stack trace, so don't need to hold buffer window too large,
# 5 would be enough, but to be sure (if some log-messages crossing):
maxlines = 10
ignoreregex = ^(?:Stack |- /)
failregex = ^s Error: [[^]] ] Controller class S  could not be found..*<SKIPLINES>^((?:Request|Referer) URL:.*<SKIPLINES>)*^Client IP: <HOST>
  

Чтобы протестировать его напрямую, используйте:

 fail2ban-regex --maxlines=5 /path/to/log '^s Error: [[^]] ] Controller class S  could not be found..*<SKIPLINES>^((?:Request|Referer) URL:.*<SKIPLINES>)*^Client IP: <HOST>' '^(?:Stack |- /)'
  

Но, как уже было сказано, это действительно некрасиво — лучше найти способ записать все в одну строку.