This chapter describes how to enable the black list of IP addresses and dynamically maintain the list of blackisted addresses.

Table of Contents

Introduction

With NGINX Plus R13 you can blacklist some IP addresses as well as create and maintain the database of blacklisted IP addresses. And, on the contrary, you can explicitly whitelist some IP addresses. The IP addresses database is managed with the NGINX Plus API and NGINX Plus keyval modules.

Prerequisites

  • NGINX Plus R13

Setup

First, enable the database that will store the list of blacklisted/whitelisted IP addresses. This is done with the NGINX keyval module.

  • In NGINX configuration file, enable the zone that would store keys and values, for example, zone one with the size of 1 megabyte. This is done with the the keyval_zone directive specified on the http level:

    http {
    ...
    keyval_zone zone=one:1m;
    }
  • In the keyval_zone directive you can optionally specify a file that would keep the key-value database and makes the changes in the database persistent across NGINX restarts, for example, one.keyval:

    keyval_zone zone=one:1m state=one.keyval;
  • Enable the NGINX API in the read-write mode with the api directive:

    ...
    server {
    listen 80;
    server_name www.example.com;

    location /api {
    api write=on;
    }
    }

  • We strongly recommend restricting access to this location, for example, allow access only from the 127.0.0.1 address:

    ...
    server {
    listen 80;
    server_name www.example.com;

    location /api {
    api write=on;
    allow 127.0.0.1;
    deny all;
    }
    }

  • Populate the key-value database by sending the POST API command in the JSON format. The command can be sent, for example, via curl. If the zone is empty, you can enter several key-value pairs at once, if there is already one or more key-value pairs in the zone, only one pair can be added:

    curl -X POST -d '{
    "10.0.0.1": "1",
    "10.0.0.2": "1",
    "10.0.0.3": "0",
    "10.0.0.4": "0"
    }' -s http://www.example.com/api/1/http/keyvals/one
  • Create a mapping of a user’s IP address and a key-value pair. This can be done with the keyval directive specified on the http level. The directive will create a new variable (specified as the second directive parameter), whose value is looked up by the key (specified as the first directive parameter), in the key-value database (specified in the zone= parameter):

    http {
    ...
    keyval_zone zone=one:1m state=one.keyval;
    keyval $remote_addr $target zone=one; # Client address is the key, $target is the value;
    }
  • Create a rule with the if directive that would either allow or deny the IP address:

    if ($target) {
    return 403;
    }
  • Managing the key-value database

    Updates of the IP address database can be performed on-the-fly with API commands and do not require reload of NGINX Plus.

    • To get the list of all database entries in the zone, for example, in the zone one, send the following curl command:
      curl -X GET http://www.example.com/api/1/http/keyvals/one
    • To update an existing entry, for example, change the value for IP address 10.0.0.4 from “allow” to “deny”, send the following curl command:
      curl -X PATCH -d '{"10.0.0.4": "1"}' -s http://www.example.com/api/1/http/keyvals/one
    • To delete an existing entry, send the following curl command:
      curl -X DELETE -d '{"10.0.0.4": "1"}' -s http://www.example.com/api/1/http/keyvals/one

    Full example

    A piece of NGINX configuration file:

    http {
    ...
    keyval_zone zone=one:1m state=one.keyval;
    keyval $remote_addr $target zone=one;

    server {
    listen 80;
    server_name www.example.com;

    location /api {
    api write=on;
    allow 127.0.0.1;
    deny all;
    }

    if ($target) {
    return 403;
    }
    }
    }

    A curl command that populates the empty keyval zone one with blacklisted (value 1) and whitelisted (value 0) IPs:

    curl -X POST -d '{
    "10.0.0.1": "1",
    "10.0.0.2": "1",
    "10.0.0.3": "0",
    "10.0.0.4": "0"
    }' -s http://www.example.com/api/1/http/keyvals/one

    In this example, we have configured the following:

    • created the keyval zone one of the 1 megabyte size and the one.keyval file – both store key value pairs
    • enabled NGINX Plus API in the write mode so that the keyval zone can populated with IP addresses
    • populated the keyval zone with keys and values of blacklisted and whitelisted IP address by sending the curl API command, where the value for blacklisted IPs is 1, while the value for whitelisted IPs is 0
    • enabled a lookup of the IP address $remote_addr in the key-value database as a key, and put the value of the found key into the $target variable
    • enabled a simple rule to check for the resulting value: if the value of $target is 1 (IP blacklisted), then return the 403 (“Access Forbidden”) error to the client

    See Also