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:
[ 192.168.100.1/24 ] [ /dev/pts/13 ] [~/Nextcloud/blog/Conf]
→ ssh root@ech4.duckdns.org
The authenticity of host 'ech4.duckdns.org (178.128.46.38)' 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 'ech4.duckdns.org,178.128.46.38' (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.
root@debian-s-1vcpu-1gb-lon1-01:~#
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
[Definition]
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:
[nginx-http-auth]
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:
[nginx-req-limit]
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:
[nginx-noscript]
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:
[nginx-badbots]
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
[nginx-nohome]
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:
[nginx-noproxy]
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
[Definition]
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
[Definition]
failregex = ^ -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)
ignoreregex =
sudo nano nginx-nohome.conf
[Definition]
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:
#!/bin/sh
while true;
do
curl ech1.duckdns.org
done
chmod +x mycurlscript.sh
./mycurlscript.sh
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
Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8
Contact: nihilist@contact.nowhere.moe (PGP)