typonaut
typonaut

Reputation: 321

Oddities in fail2ban regex

This appears to be a bug in fail2ban, with different behaviour between the fail2ban-regex tool and a failregex filter

I am attempting to develop a new regex rule for fail2ban, to match:

\"%20and%20\"x\"%3D\"x

When using fail2ban-regex, this appears to produce the desired result:

^<HOST>.*GET.*\\"%20and%20\\"x\\"%3D\\"x.* 200.*$

As does this:

^<HOST>.*GET.*\\\"%20and%20\\\"x\\\"%3D\\\"x.* 200.*$

However, when I put either of these into a filter, I get the following error:

Failed during configuration: '%' must be followed by '%' or '(', found:…

To have this work in a filter you have to double-up the ‘%’, ie ‘%%’:

^<HOST>.*GET.*\\\"%%20and%%20\\\"x\\\"%%3D\\\"x.* 200.*$

While this gets the required hits running as a filter, it gets none running through fail2ban-regex.

I tried the \\\\ as Andre suggested below, but this gets no results in fail2ban-regex.

So, as this appears to be differential behaviour, I am going to file it as a bug.

Upvotes: 4

Views: 1116

Answers (1)

Andre Bezuidenhout
Andre Bezuidenhout

Reputation: 41

According to Python's own site a singe backslash "\" has to be written as "\\\\" and there's no mention of %.

Regular expressions use the backslash character ('') to indicate special forms or to allow special characters to be used without invoking their special meaning. This collides with Python’s usage of the same character for the same purpose in string literals; for example, to match a literal backslash, one might have to write '\\' as the pattern string, because the regular expression must be \, and each backslash must be expressed as \ inside a regular Python string literal

I would just go with:

failregex = (?i)^<HOST> -.*"(GET|POST|HEAD|PUT).*20and.*3d.*$

the .* wil match anything inbetween anyways and (?i) makes the entire regex case-insensitive

Upvotes: 0

Related Questions