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!