NGINX: Restrict access by IP address
Crude way to stop an attack in case of an emergency.
Keep in mind that this is a static configuration, which is not very effective against adversarial attacks when an attacker constantly changes their tactics.
Denylisting (that's what NGINX calls it) is done through ngx_http_access_module, which provides static denylisting. For dynamic denylisting we would have to use NGINX Plus.
There are 2 control directives in play here: allow and deny. The configuration can be added either to the main file /etc/nginx/nginx.conf or to any of the virtual hosts /etc/nginx/sites-enabled/website.conf.
NGINX supports adding the directive in the following blocks
http- to protect all hosts that are served from a given NGINX instanceserver- to assert control on the virtual host levellocation- to assert control on the specific pathlimit_except- exclude provided HTTP verbs
http {
deny 8.8.8.8;
}
server {
deny 8.8.8.8;
}
location /login {
deny 8.8.8.8;
}
location / {
limit_except GET {
deny 8.8.8.8;
}
}
Restricting access to multiple IPs
We can also use a CIDR notation to protect from botnets deployed in a single subnet. Adding multiple directives means that all of them are going to be applied.
location /login {
deny 8.8.8.0/24;
deny 2001:0db8::/32;
}
Additional blanket value all can be used to allow the access to a specific subnet while disabling the access to the rest.
location /login {
allow 8.8.8.0/24;
deny all;
}
Managing denylist
We can also manage it through a separate file on a filesystem.
# cat denylist.conf
deny 8.8.8.8
deny 32.32.32.32
For that we need to use include in the NGINX configuration file.
location /login {
include denylist.conf;
}
Customizing error message
By default NGINX will return 403 Forbidden, but we can customize it.
location /login {
deny 8.8.8.8;
error_page 403 /deny_403.html;
location = /deny_403.html {
root /usr/share/nginx/html;
allow all; # this is needed to render the page itself
}
}
Applying configuration
/usr/local/nginx/sbin/nginx -t
to test the config.
/usr/local/nginx/sbin/nginx -s reload
# or
service nginx reload
to reload.
Comments
Join the discussionNo comments yet. Be the first to comment.
Practical Tips
“Theory and practice sometimes clash. And when that happens, theory loses. Every single time.” - Linus Torvalds