Skip to content

Instantly share code, notes, and snippets.

@nginx-gists
Last active November 9, 2023 09:43
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nginx-gists/2863c4820287e16d51fab2b70ea3847d to your computer and use it in GitHub Desktop.
Save nginx-gists/2863c4820287e16d51fab2b70ea3847d to your computer and use it in GitHub Desktop.
Dynamic IP Denylisting with NGINX Plus and fail2ban
<!DOCTYPE html>
<html>
<head>
<title>Banned</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>You have been banned.</h1>
<p>Sorry, there have been too many login failures from this IP address.<br/>
Please try again later.</p>
</body>
</html>
server {
listen 1111;
allow 127.0.0.1; # Only allow access from localhost,
deny all; # and prevent remote access.
location /api {
api write=on; # The NGINX Plus API endpoint in read/write mode
}
}
keyval_zone zone=denylist:1M;
keyval $remote_addr $num_failures zone=denylist;
server {
listen 80;
location / {
root /usr/share/nginx/html;
if ($num_failures) {
return 403;
}
}
}
vim: syntax=nginx
[DEFAULT]
bantime = 120
banaction = nginx-plus-denylist
[nginx-http-auth]
enabled = true
[Definition]
actionban = curl -s -o /dev/null -d '{"<ip>":"<failures>"}' http://localhost:1111/api/6/http/keyvals/denylist
actionunban = curl -s -o /dev/null -X PATCH -d '{"<ip>":null}' http://localhost:1111/api/6/http/keyvals/denylist
server {
listen 1111;
allow 127.0.0.1; # Only allow access from localhost,
deny all; # and prevent remote access.
location /api {
api write=on; # The NGINX Plus API endpoint in read/write mode
}
}
keyval_zone zone=denylist:1M state=denylist.json;
keyval $remote_addr $num_failures zone=denylist;
limit_req_zone $binary_remote_addr zone=20permin:10M rate=20r/m;
server {
listen 80;
root /usr/share/nginx/html;
location / {
auth_basic "closed site";
auth_basic_user_file users.htpasswd;
if ($num_failures) {
rewrite ^.* /banned.html;
}
}
location = /banned.html {
limit_req zone=20permin burst=100;
}
}
vim: syntax=nginx
@nginx-gists
Copy link
Author

For a discussion of these files, see Dynamic IP Denylisting with NGINX Plus and fail2ban

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment