Banning IP addresses with Nginx
In the previous lesson we created some helper scripts to identify bad actors from our Nginx access logs. We'll need a quick and easy way to ban some of these IPs, and my favorite approach is a simple Bash script.
In this lesson we'll create a shared geo blacklist in Nginx, and block any traffic originating from IPs that match. We'll then make a couple of scripts to ban and unban IP addresses using this list.
Nginx geo blacklist
Previously we've already added a $blacklisted_fail2ban variable to our main
nginx.conf file, managed by Fail2ban. Using a similar pattern, let's now add a
geo block for manual bans and call it $blacklisted_manual:
http {
# ...
geo $blacklisted_manual {
default 0;
include /etc/nginx/blacklisted-manual.geo;
}
}
This $blacklisted_manual variable should then be used in the server block
to return a 403 response code when there's a match:
server {
# ...
if ($blacklisted_manual) {
return 403;
}
# location ...
}
Let's also create the blacklisted-manual.geo file, make sure our configuration
is correct, and reload the Nginx service.
sudo touch /etc/nginx/blacklisted-manual.geo
sudo nginx -t
sudo systemctl reload nginx.service
You can manually create entries in this file using the following syntax:
123.123.123.123 1; # an optional comment
The beauty of the Nginx geo block is that it supports ranges and CIDR notation. This allows you to quickly block entire subnets during a large attack, for example. Don't forget to reload Nginx after making changes to this file manually.
Ban.sh script
Manually editing the file might be tedious and prone to error, especially during stressful times. This is where a script comes in quite handy. Here's a very simplified version of one I use:
This article is for premium members only. One-time payment of $196 unlocks lifetime access to all existing and future content on wpshell.com, and many other perks.