Nginx provides several methods for blocking malicious IP addresses at the web server level. This is an effective first line of defense against attackers, bots, and unwanted traffic. Choosing the right method depends on the size of your IP list and your performance needs.
Method 1: The simple deny Directive
This is the most straightforward way to block a small number of IPs or IP ranges. Place these directives inside your http, server, or location block.
server {
listen 80;
server_name example.com;
# Block specific AI bot IP ranges
deny 142.44.220.0/24;
deny 148.113.128.0/24;
deny 15.235.27.0/24;
deny 198.244.168.0/24;
# Allow specific IPs (optional)
allow 192.168.1.50;
# Deny all others after a specific allow rule. This is crucial.
deny all;
location / {
root /var/www/html;
index index.html;
}
}
Method 2: The geo Module
For managing large lists of blocked IPs (hundreds or thousands), the geo module is the most performant method. It creates an efficient lookup table that is much faster than processing a long list of deny directives. Note that using if in the server block is acceptable, but using it in location blocks should be avoided.
http {
# Define blocked IPs using geo module in the http block
geo $blocked_ip {
default 0;
# AI bot ranges from botective.json
142.44.220.0/24 1;
148.113.128.0/24 1;
15.235.27.0/24 1;
198.244.168.0/24 1;
}
server {
listen 80;
server_name example.com;
# Block if the IP is marked as blocked
if ($blocked_ip) {
return 403;
}
location / {
root /var/www/html;
index index.html;
}
}
}
Method 3: External Blocklist File
To keep your main configuration clean and organized, especially with large lists, use an external file with the include directive. This works well for both the deny and geo methods.
Create /etc/nginx/blocklist.conf for the deny method:
# AI bot IP ranges from botective.json
deny 142.44.220.0/24;
deny 148.113.128.0/24;
deny 15.235.27.0/24;
deny 198.244.168.0/24;
Include it in your server block:
server {
# ...
include /etc/nginx/blocklist.conf;
# ...
}
For the more efficient geo module, the geo map can also be included from an external file, which is the recommended practice for large, frequently updated lists.
Method 4: Enhanced Security with Rate Limiting
Combine IP blocking with rate limiting to defend against brute-force attacks. Rate limiting restricts the number of requests a client can make within a specific time frame.
http {
# Define rate limiting zone: 5 requests/minute
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
listen 80;
server_name example.com;
# Deny malicious IPs first
deny 142.44.220.0/24;
deny 198.244.168.0/24;
location /login {
# Apply rate limiting
limit_req zone=login burst=3 nodelay;
# ...
}
}
}
Dynamic IP Blocking with fail2ban
For an automated defense system, integrate Nginx with Fail2ban. This will automatically block an IP at the firewall level after it exceeds a certain number of failed attempts or triggers a rate limit.
Create /etc/fail2ban/filter.d/nginx-req-limit.conf:
[Definition]
failregex = limiting requests, excess: .* by zone .*, client: <HOST>
ignoreregex =
Add a new jail to /etc/fail2ban/jail.local:
[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
Testing Configuration with nginx -t
The nginx -t command is essential for validating your configuration before applying changes. It performs a syntax check without actually restarting the server.
# Test configuration syntax
nginx -t
# Test with verbose output
nginx -t -v
# Test specific configuration file
nginx -t -c /path/to/nginx.conf
What nginx -t checks:
- Configuration file syntax errors
- File path validity (document roots, log files, etc.)
- Module compatibility
- Directive conflicts
- Include file accessibility
Example output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
If there are errors, you'll see specific line numbers and descriptions:
nginx: [emerg] unexpected "}" in /etc/nginx/nginx.conf:20
nginx: configuration file /etc/nginx/nginx.conf test failed
Always test before reloading:
# Safe workflow
nginx -t && systemctl reload nginx
Best Practices
- Monitor logs: Check what IPs you're blocking
- Keep lists updated: Review blocklists regularly
- Consider performance: Large lists can slow down nginx
- Test before applying: Always run
nginx -tto test configuration syntax before reloading