nginx proxy fail2ban on 401

In the setup I've right now I've NGINX that works as proxy for (serveral) internal VMs. Now, I would like to protect these VMs from bruteforce, such that, if there's a huge amount of 401 the IP should be blocked.

I've google around on how to use fail2ban, but I can't figure out how it can work in my case.

The access.log of nginx looks like this (i've hidden some sensitive infos)

148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:43:32 +0100] "POST /v1/schemas/7...b8/documents HTTP/1.1" 200 364 "-" "python-requests/2.10.0"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:43:32 +0100] "DELETE /v1/documents/fd7...09e1?force=true HTTP/1.1" 200 83 "-" "python-requests/2.10.0"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:43:32 +0100] "GET /v1/schemas/713e4ee8-...b8/documents HTTP/1.1" 200 6689 "-" "python-requests/2.10.0"
47.XXX.XXX.XXX - - [09/Jan/2017:13:43:33 +0100] "GET /wp-login.php HTTP/1.1" 301 178 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"
47.XXX.XXX.XXX - - [09/Jan/2017:13:43:39 +0100] "GET /wp-login.php HTTP/1.1" 301 178 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"
47.XXX.XXX.XXX - - [09/Jan/2017:13:43:44 +0100] "GET / HTTP/1.1" 301 178 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:44:33 +0100] "GET /v1/schemas/713e4e...d649b8/documents HTTP/1.1" 200 6689 "-" "python-requests/2.10.0"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:44:33 +0100] "POST /v1/schemas/713e4..fd649b8/documents HTTP/1.1" 200 364 "-" "python-requests/2.10.0"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:44:33 +0100] "DELETE /v1/documents/9f5....cadf29031c?force=true HTTP/1.1" 200 83 "-" "python-requests/2.10.0"
148.XXX.XXX.XXX - 92....396 [09/Jan/2017:13:44:33 +0100] "GET /v1/schemas/713e...649b8/documents HTTP/1.1" 200 6689 "-" "python-requests/2.10.0"
87.XXX.XXX.XXX - {{customerId [09/Jan/2017:13:45:08 +0100] "GET /v1/repositories HTTP/1.1" 401 101 "-" "PostmanRuntime/3.0.9"
87.XXX.XXX.XXX - {{customerId [09/Jan/2017:13:45:09 +0100] "GET /v1/repositories HTTP/1.1" 401 101 "-" "PostmanRuntime/3.0.9"
87.XXX.XXX.XXX - test [09/Jan/2017:13:45:20 +0100] "GET /v1/repositories HTTP/1.1" 401 101 "-" "PostmanRuntime/3.0.9"

As you can see, NGINX works as proxy for the service and for the website and other services. What i would like to prevent are the last 3 lines, where the return code is 401.

As far I understood (mostly from here) I could make a regexp to intercept that lines that contains a 401, setting a burstime of 3600 (60 mins lock) and retries of 100. So that 100 errors per hours are permitted.

Note: I've to figure out this value (any idea?), it may happen that someone gets 401 every now and then.

Yet, I know the thoery but not yet the practice. Can someone help me in setting this up especially on how to write the regexp for that condition.

I came up with ^.* 401 but don't know if it's enough and I would like to avoid to block everybody by mistake.

After finding the regexp, I should add this rule to a file (let's call it nginx-401.conf under /etc/fail2ban/filter.d/ that will look like

[Definition]
failregex = ^<HOST> -.* 401
ignoreregex =

and in jail.conf

[nginx-401]
enabled = true
action = iptables-multiport[name=NoProxy, port="http,https"] # no idea of this, copied from somewhere else. what should I put here?
filter = nginx-401 # should be the file name 
logpath = /var/log/nginx*/*access*.log
maxretry = 100 # my limit
bantime  = 3600 # 1 hour

Here I don't really have idea of what action should be and if the rest is set up correctly.

0
задан 9 January 2017 в 15:03
2 ответа

В конце концов, похоже, это сработало, вот мой конфет только для справки: /etc/fail2ban/filter.d/wrongauth.conf

[Definition]
failregex = ^<HOST> -.* 401
ignoreregex =

в /etc/fail2ban/jail.con

[wrongauth]
enabled = true
filter = wrongauth
action = shorewall 
    %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s", sendername="%(sendername)s"]
logpath = /var/log/nginx*/*access*.log
banTime = 600 # 10 minutes
findTime = 60
maxretry = 60

В качестве действия я использую shorewall, а для отправки электронного письма при возникновении блокировки мне пришлось измените действие в соответствии с настройками, которые вы видите.

0
ответ дан 4 December 2019 в 16:23

Сама страница диалога входа возвращается с кодом 401.

Неудачные входы регистрируются синтаксисом:

<host> - <user> [06/Jun/2018:11:18:55 +0300] "GET / HTTP/1.1" 401 ...

...где данное имя пользователя находится в '', а код возврата 401

[Definition]
failregex = ^<HOST> - [^-[ ]+.+HTTP/1.[0-9]" 401
ignoreregex =

Этот регекс не будет совпадать с попытками входа с пустым именем пользователя. В этом случае имя пользователя будет '-', что неотделимо от страницы диалога входа в систему.

.
1
ответ дан 4 December 2019 в 16:23

Теги

Похожие вопросы