Skip to main content
Hackers can steal data, spread spyware or ransomware, and even take down entire websites. While legitimate bots index content for search engines, malicious bots scrape data, spam forms, and post fake reviews. Controlling which clients can reach your application is a critical layer of defense.
An infographic titled "Hackers" showing a hooded hacker at a computer with a skull emblem. Three icons list threats: "Steal data," "Spread spyware and ransomware," and "Take down the whole site."
NGINX supports access control through the ngx_http_access_module using the allow and deny directives. You can use these directives inside the http, server, and location blocks to explicitly permit or block individual IPs or CIDR ranges. Example — allow a few IPs and deny everyone else:
To permit or block a network range, specify a CIDR block. Example: deny a /24 and restrict /admin to a specific /24:
Quick CIDR reference: Blocking individual IPs is straightforward but not always scalable: attackers rotate IPs, and long lists of allow/deny directives are hard to maintain. A common automated approach is Fail2Ban, which detects abusive behavior from logs and updates firewall rules automatically. If NGINX is behind a reverse proxy or load balancer, your access logs may show the proxy’s IP instead of the client’s IP. Make sure NGINX records the real client IP by using an appropriate log_format with X-Forwarded-For or by enabling the realip module:
An infographic titled "Blocking Traffic" showing IPs, bots, and network traffic on the left routed toward a block symbol. The block prevents those requests from reaching a website mockup on the right.
Fail2Ban watches service logs for patterns of abuse (failed logins, suspicious requests) and automatically updates firewall rules to temporarily ban offending IPs. It’s a practical way to reduce brute-force attacks and automated scraping without manually maintaining blocklists.
Fail2Ban — quick start and examples Example tail of Fail2Ban activity:
Install Fail2Ban on common distributions:
After installation, create a local configuration override to avoid editing packaged files:
Example NGINX jail entries for jail.local:
Common Fail2Ban parameters explained: Fail2Ban filter files live under /etc/fail2ban/filter.d. They use regular expressions and the <HOST> token to capture the offending IP address. Example snippet from an nginx-http-auth filter:
Inspect jail status and banned IPs:
Example output:
Unban an IP from a specific jail:
Fail2Ban works well with traditional server setups because it manipulates host-level firewall rules and parses log files. If you run NGINX behind load balancers or in containers, adjust your logging and network strategy so Fail2Ban sees real client IPs or use alternative protections.
Fail2Ban relies on host-level logs and firewall control; it is not ideal inside isolated containers where logs are aggregated and firewall control is limited. For containerized environments (Kubernetes, Docker), consider sidecar log monitoring, cluster-level ingress policies, or an external WAF.
Further reading and references Note: This article describes how to use NGINX allow/deny directives and Fail2Ban in typical server environments. In Kubernetes or other orchestrated environments, adapt these patterns to your logging and network model (ingress controllers, cluster policies, or external WAFs).

Watch Video