Назад | Перейти на главную страницу

Регулярное выражение fail2ban не соответствует

Должен признать, регулярные выражения всегда были для меня слабым местом. Я никогда не садился и не тратил достаточно времени на их изучение, чтобы использовать их эффективно. Однако я действительно не понимаю, почему это не совпадает. Я пытаюсь создать собственный failregex, чтобы люди не пытались использовать любые ошибки xmlrpc.php (и они постоянно пытаются это сделать).

Я использую fail2ban v0.9.3 с Apache 2.4.18 на Ubuntu 16.04.2.

Вот мое регулярное выражение:

<HOST> - - \[\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2} +\d{4}\] "POST /xmlrpc.php HTTP/1.0" 200

А вот пример строки, которая не соответствует (IP заменен на 0):

0.0.0.0 - - [06/Apr/2017:07:45:42 +0000] "POST /xmlrpc.php HTTP/1.0" 200 752 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"

Я не могу понять, почему он не совпадает. Насколько я могу судить, это должно быть точное совпадение. Кто-нибудь может пролить свет?

Кроме того, было бы неплохо иметь совпадение смещения часового пояса для знаков + и - ... и я думаю, заменив HTTP/1.0 с участием HTTP/1.\d{1} он должен соответствовать 1.0 и 1.1, верно?

Заранее спасибо!

РЕДАКТИРОВАТЬ: после игры в командной строке с помощью fail2ban-regex я понял это с помощью регулярного выражения <HOST> - - \[ он будет соответствовать всем строкам. Однако, когда я меняю его на <HOST> - - \[\d{2} он вообще не соответствует ни одной строке. В этом нет никакого смысла!

РЕДАКТИРОВАТЬ 2: А пока я использую <HOST> - - \[.* "POST /(xmlrpc|wp-login).php HTTP/1.\d" 200 и это соответствует нужным мне строкам. Тем не менее, мне все равно хотелось бы знать, почему мой исходный не совпадает, поскольку я бы предпочел использовать более конкретное регулярное выражение, чем широкое, которое я использую сейчас.

Попробуйте это регулярное выражение - я тестировал его с помощью regexr.com, и он определенно соответствует:

<HOST> - - \[\d{2}\/\w{3}\/\d{4}(:\d{2}){3} \+0000\] "POST \/xmlrpc.php HTTP\/1.0" 200

Одна из проблем заключалась не в том, чтобы избежать косой черты - это необходимо сделать.

РЕДАКТИРОВАТЬ (после того, как я увидел ваше редактирование): я попытался немного упростить его и придумал это, что соответствует:

failregex = ^<HOST> - - \[.*\] "POST \/xmlrpc.php.*$

Это не совсем то, что вы хотели, но это работает

После пары итераций с fail2ban-regex, Я думаю, что происходит то, что fail2ban пытается выбрать дату из самой строки журнала, прежде чем проверять ее на соответствие вашему шаблону фильтра.

$ line='0.0.0.0 - - [06/Apr/2017:07:45:42 +0000] "POST /xmlrpc.php'

С участием .* вместо метки времени она совпадает, но, как вы заметили, явный поиск числа в начале метки времени не соответствует:

$ ./fail2ban-regex "$line"  '<HOST> - - \[.*\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 1 matched, 0 missed

$ ./fail2ban-regex "$line"  '<HOST> - - \[\d+.*\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 0 matched, 1 missed

Но проверьте это:

$ ./fail2ban-regex "$line"  '<HOST> - - \[ \+0000\].*POST /xmlrpc' |grep ^Lines
Lines: 1 lines, 0 ignored, 1 matched, 0 missed

Я удалил всю метку времени из шаблона, вместо этого ожидая, что это будет пустой (есть только индикатор часового пояса). Он по-прежнему совпадает, намекая, что на самом деле fail2ban удаляет отметка времени перед тестированием по шаблону в конфигурации.

Итак, может быть лучше просто оставить эту часть за пределами шаблона фильтра и сопоставить что-нибудь вместо отметки времени:

<HOST> - - \[.*?\] "POST /xmlrpc.php HTTP/1.0" 200

В качестве примечания: ваш исходный RE имеет некотируемый + там, где начинается метка времени, знак плюс означает «по крайней мере одно повторение предыдущего элемента», поэтому вам нужно его избежать.