fail2ban scan for 403 in nginx access logs

3.5k views Asked by At

I have setup some specific rules on nginx, blocking some urls and some extensions (aspx, sh, jsp, etc..). I have also enable a custom access log file only for 403|429|410 errors, so that in only 1 place i can have all my access denied log.

My goal is to have fail2ban read this log and for every GET/POST that ends in a 403 error, IP should be banned.

1) nginx.conf will be logging the custom error log file like this:

log_format limit '$time_local - $remote_addr "$request" $status';

and this is a log entry:

03/Jan/2017:15:53:01 +0100 - 1.2.3.4 "GET /aaa.jsp HTTP/1.1" 403

2) i have a fail2ban filter like this (taken from here)

^<HOST> .* "(GET|POST) [^"]+" 403

3) i have tried with fail2ban-regex

fail2ban-regex /var/log/nginx/access-live-limitbot-website.log /etc/fail2ban/filter.d/nginx-403.conf

and this is the output

Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [1] Day/MONTH/Year:Hour:Minute:Second
`-

Lines: 2 lines, 0 ignored, 0 matched, 2 missed
|- Missed line(s):
|  217.19.158.242 "POST /wp-login.php HTTP/1.1" 403
|  03/Jan/2017:15:53:01 +0100 - 217.19.158.242 "GET /aaa.jsp HTTP/1.1" 403
`-

and i will never get the entry matching the error code.

Will someone please help me with the regex based on my custom log?

thank you

1

There are 1 answers

0
jeffmcneill On

Fail2ban is picky about the date format. Also, for ease of matching, I suggest reordering the items in the log.

For date format, see documentation here:

In order for a log line to match your failregex, it actually has to match in two parts: the beginning of the line has to match a timestamp pattern or regex, and the remainder of the line has to match your failregex. If the failregex is anchored with a leading ^, then the anchor refers to the start of the remainder of the line, after the timestamp and intervening whitespace.

The pattern or regex to match the time stamp is currently not documented, and not available for users to read or set. See Debian bug #491253. This is a problem if your log has a timestamp format that fail2ban doesn't expect, since it will then fail to match any lines. Because of this, you should test any new failregex against a sample log line, as in the examples below, to be sure that it will match. If fail2ban doesn't recognize your log timestamp, then you have two options: either reconfigure your daemon to log with a timestamp in a more common format, such as in the example log line above; or file a bug report asking to have your timestamp format included.

For the reorder, something like datetime - status - host (- other stuff), would help create a simple pattern such as 403.

Therefore your log should look like:

03-01-2017 15:53:01 403 1.2.3.4 "GET /aaa.jsp HTTP/1.1"

and your pattern can be

403 <HOST>

You can run this from the command line to validate as:

fail2ban-regex '03-01-2017 15:53:01 403 1.2.3.4 "GET /aaa.jsp HTTP/1.1"' '403 <HOST>'

Which produces the output:

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

Use regex line : 403 <HOST>
Use single line: 03-01-2017 15:53:01 403 1.2.3.4 "GET /aaa.jsp HTTP...

Matched time template Day-Month-Year Hour:Minute:Second
Got time using template Day-Month-Year Hour:Minute:Second

Results
=======

Failregex: 1 total
|- #) [# of hits] regular expression
|  1) [1] 403 <HOST>
`-

Ignoreregex: 0 total

Summary
=======

Addresses found:
[1]
    1.2.3.4 (Tue Jan 03 15:53:01 2017)

Date template hits:
2 hit(s): Day-Month-Year Hour:Minute:Second

Success, the total number of match is 1