# 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: ![](0.png) [ 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:~# ## **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 [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