Previous Page

nihilist - 00 / 00 / 00

Nginx basic auth + fail2ban

Before we start, you will need a Debian 10+ VPS (you can get one on digitalocean for example), if you prefer to use your own self hosted server, make sure that port 80 and 443 are correctly port forwarded so that the public ip points to the server and not the router. Once that's done, go and ssh into your debian 10 server.

You can use DuckDNS to get a free domain name:

[ ] [ /dev/pts/13 ] [~/Nextcloud/blog/Conf]
→ ssh
The authenticity of host ' (' can't be established.
ECDSA key fingerprint is SHA256:z2HAncB99pfbAUfj9tJY7vlo8EGUzCIUxWBAnjAflcA.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added ',' (ECDSA) to the list of known hosts.
Linux debian-s-1vcpu-1gb-lon1-01 4.19.0-10-cloud-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

Initial setup

First we're going to install nginx and fail2ban:

apt update -y && apt upgrade -y
apt install nginx fail2ban -y

echo 'welcome to my server!' > /var/www/html/index.nginx-debian.html

Then we're going to change fail2ban's configuration to include the nginx module:

nano /etc/fail2ban/filter.d/nginx-req-limit.conf

failregex = limiting requests, excess:.* by zone.*client: 

ignoreregex =

Then create the jail config:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
vim /etc/fail2ban/jail.local

If you have nginx basic auth module, go to the line by writing /nginx-auth in vim and then edit the [nginx-http-auth] like so:


enabled  = true
filter   = nginx-http-auth
port     = http,https
logpath  = /var/log/nginx/error.log

Then we can append the following modules at the end of the config file:


enabled = true
filter = nginx-req-limit
action = iptables-multiport[name=ReqLimit, port="http,https", protocol=tcp]
logpath = /var/log/nginx/*error.log
findtime = 600
bantime = 7200
maxretry = 10

The findtime and maxretry values decide how often offending IPs get banned, making these values smaller, ips will get banned more often so make sure you change the values according to your needs.

Then we have nginx noscript to jaoilban clients that are searching for scripts on the website to execute and exploit , therefore you can use this one if you don't have php:


enabled  = true
port     = http,https
filter   = nginx-noscript
logpath  = /var/log/nginx/access.log
maxretry = 6


This one is to jailban known malicious bot request patterns:


enabled  = true
port     = http,https
filter   = nginx-badbots
logpath  = /var/log/nginx/access.log
maxretry = 2


nginx nohome is used if you don't provide web content from user's home directories


enabled  = true
port     = http,https
filter   = nginx-nohome
logpath  = /var/log/nginx/access.log
maxretry = 2


nginx noproxy is used to block people from attempting to use our nginx server as an openj proxy:


enabled  = true
port     = http,https
filter   = nginx-noproxy
logpath  = /var/log/nginx/access.log
maxretry = 2

Then get the individual modules config files:

cd /etc/fail2ban/filter.d
sudo nano nginx-http-auth.conf



failregex = ^ \[error\] \d+#\d+: \*\d+ user "\S+":? (password mismatch|was not found in ".*"), client: , server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$
            ^ \[error\] \d+#\d+: \*\d+ no user/password was provided for basic authentication, client: , server: \S+, request: "\S+ \S+ HTTP/\d+\.\d+", host: "\S+"\s*$

            ignoreregex =

sudo cp apache-badbots.conf nginx-badbots.conf
sudo nano nginx-noscript.conf


failregex = ^ -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)

ignoreregex =

sudo nano nginx-nohome.conf


failregex = ^ -.*GET http.*

ignoreregex =

Then restart fail2ban with systemctl:

systemctl restart fail2ban

Now from the client point of view, let's get banned by fail2ban by requesting alot of requests at once:

while true;

chmod +x

You can check fail2ban's logs in /var/log/fail2ban.log:

fail2ban-client status nginx-req-limit

you can debug the filter:

fail2ban-client -d
fail2ban-regex /var/log/nginx/dom.ain.error.log /etc/fail2ban/filter.d/nginx-req-limit.conf


Until there is Nothing left.

About nihilist

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8

Contact: (PGP)