SoFunction
Updated on 2025-03-04

Design solution for dynamic IP banning in Nginx

Environmental preparation

  • linux version: centos7 / ubuntu etc.

  • redis version: 5.0.5

  • nginx version: nginx-openresty

Design plan

There are many ways to implement the functionality of IP blacklist:

1. At the operating system level, configure iptables to intercept network requests for the specified IP.

  • Advantages: Simple and direct, intercepting at the physical level of the server

  • Disadvantages: You need to manually modify the configuration file every time, the operation is cumbersome and inflexible

2. At the web server level, configure the IP blacklist through Nginx's own deny option or lua plug-in.

  • Advantages: Can dynamically implement ban IP, and can achieve distributed ban by setting ban time.

  • Disadvantages: You need to understand Lua scripts and Nginx configuration, which has a certain learning cost

3. At the application level, check whether the client's IP address is on the blacklist before processing the request.

  • Advantages: It is implemented by writing code, which is relatively simple and easy to maintain.

  • Disadvantages: The code can become verbose and can affect performance in high concurrency situations.

In order to facilitate management and sharing of blacklists, the IP blacklist function is implemented through the nginx + lua + redis architecture

Configuration

Add the following configuration to the location of the server that needs to be restricted:

location / {  
    # If there is a static resource file under this location, you can make a judgment    #if ($request_uri ~ .*\.(html|htm|jpg|js|css)) {  
    # access_by_lua_file /usr/local/lua/access_limit.lua;     
    #}  
      
    access_by_lua_file /usr/local/lua/access_limit.lua; # Add this configuration and the current limit will be performed according to the rules of access_limit.lua    alias /usr/local/web/;  
    index   ;  
}  

Configure lua scripts

/usr/local/lua/access_limit.lua

-- It can automatically make the access frequency too highIPAddress blacklisted for a period of time  
  
--Connection pool timeout recovery milliseconds  
local pool_max_idle_time = 10000  
--Connection pool size  
local pool_size = 100  
--redis Connection timeout  
local redis_connection_timeout = 100  
--redis host  
local redis_host = "your redis host ip"  
--redis port  
local redis_port = "your redis port"  
--redis auth  
local redis_auth = "your redis authpassword";  
--BannedIPtime(Second)  
local ip_block_time= 120  
--Specifyip访问频率time段(Second)  
local ip_time_out = 1  
--SpecifyipMaximum access frequency count(Second-rate)  
local ip_max_count = 3  
  
  
--  Error logging  
local function errlog(msg, ex)  
    (, msg, ex)  
end  
  
-- Release the connection pool  
local function close_redis(red)  
    if not red then  
        return  
    end  
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)  
    if not ok then  
        ("redis connct err:",err)  
        return red:close()  
    end  
end  
  
  
--connectredis  
local redis = require ""  
local client = redis:new()  
local ok, err = client:connect(redis_host, redis_port)  
-- connect失败返回服务器错误  
if not ok then  
    close_redis(client)  
    (ngx.HTTP_INTERNAL_SERVER_ERROR)  
end  
--设置超时time  
client:set_timeout(redis_connection_timeout)  
  
-- Optimize password verification operations 代表connect在connect池使用的Second-rate数,If0Represents not used,Not for0Representative reuse Only for0Password verification is performed only  
local connCount, err = client:get_reused_times()  
-- 新建connect,Need an authentication password  
if  0 == connCount then  
    local ok, err = client:auth(redis_auth)  
    if not ok then  
        errlog("failed to auth: ", err)  
        return  
    end  
    --从connect池中获取connect,无需再Second-rate认证密码  
elseif err then  
    errlog("failed to get reused times: ", err)  
    return  
end  
  
-- Get requestip  
local function getIp()  
    local clientIP = .get_headers()["X-Real-IP"]  
    if clientIP == nil then  
        clientIP = .get_headers()["x_forwarded_for"]  
    end  
    if clientIP == nil then  
        clientIP = .remote_addr  
    end  
    return clientIP  
end  
  
local cliendIp = getIp();  
  
local incrKey = "limit:count:"..cliendIp  
local blockKey = "limit:block:"..cliendIp  
  
--QueryipWhether access is prohibited,If it exists, return403Error code  
local is_block,err = client:get(blockKey)  
if tonumber(is_block) == 1 then  
    (ngx.HTTP_FORBIDDEN)  
    close_redis(client)  
end  
  
local ip_count, err = client:incr(incrKey)  
if tonumber(ip_count) == 1 then  
    client:expire(incrKey,ip_time_out)  
end  
--如果超过单位time限制的访问Second-rate数,Add restricted access identifier,限制time为ip_block_time  
if tonumber(ip_count) > tonumber(ip_max_count) then  
    client:set(blockKey,1)  
    client:expire(blockKey,ip_block_time)  
end  
  
close_redis(client)  

Summarize

The above is the IP blacklist function implemented by Nginx+Lua+Redis, which has the following advantages:

  • Simple and lightweight configuration, with little impact on server performance.

  • Multiple servers can share blacklists by sharing Redis instances.

  • Dynamic configuration, blacklists in Redis can be set manually or through some automated way

Extended

1. Application scenarios of IP blacklist

IP blacklists have a wide range of application scenarios in practical applications, mainly used to protect servers and applications from malicious attacks, crawlers or abuse. Here are some common application scenarios:

  • Prevent malicious access:Blacklists can prevent IP addresses that attempt to illegally access through brute force decryption, SQL injection, XSS attacks, etc.

  • Prevent crawlers and data abuse:Blacklists can limit crawlers who frequently access websites and crawl large amounts of data to reduce server load and protect data security.

  • Prevent DDOS attacks:The blacklist can ban IP addresses that launch large-scale DDoS attacks and protect the stability and security of the server.

  • Limit access frequency:Blacklists can limit the number of visits to a certain IP within a specific time period, preventing malicious users from brute-force cracking, ticket swiping and other behaviors.

2. Advanced features and improvements

In addition to the basic IP blacklisting capabilities, there are some advanced features and improvements available to improve security and user experience:

  • Exception detection and automatic ban:By analyzing access logs and behavior patterns, the abnormal detection function can be implemented, and the IP address of abnormal behavior can be automatically blocked to improve security.

  • Whitelisting mechanism:In addition to blacklisting, a whitelisting mechanism can also be introduced to allow certain IP addresses to bypass blacklist restrictions and ensure normal access to legitimate users.

  • Verification code verification:For IPs with frequent access or abnormal behavior, they can be required to verify the verification code to further prevent malicious behavior.

  • Statistics and analysis:The data related to the blacklist is counted and analyzed, such as recording the number of times and duration of IP blocked, so as to optimize and adjust the strategy in the future.

By continuously improving and optimizing the IP blacklisting feature, you can better protect the security of your servers and applications.

This is the end of this article about Nginx's design plan to implement dynamic IP ban. For more information about Nginx's dynamic IP ban, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!