Nginx实现动态封禁IP的设计方案

 更新时间:2024年12月30日 09:17:16   作者:技术栈人员  
为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单,对于黑名单中的 IP ,我们将拒绝提供服务,并且可以设置封禁失效时间,所以本文给大家介绍了Nginx实现动态封禁IP的设计方案,需要的朋友可以参考下

环境准备

  • linux version: centos7  / ubuntu 等

  • redis version: 5.0.5

  • nginx version: nginx-openresty

设计方案

实现 IP 黑名单的功能有很多途径:

1、在操作系统层面,配置 iptables,来拦截指定 IP 的网络请求。

  • 优点:简单直接,在服务器物理层面上进行拦截

  • 缺点:每次需要手动上服务器修改配置文件,操作繁琐且不灵活

2、在 Web 服务器层面,通过 Nginx 自身的 deny 选项或者 lua 插件配置 IP 黑名单。

  • 优点:可动态实现封禁 ip,通过设置封禁时间可以做到分布式封禁

  • 缺点:需要了解 Lua 脚本和 Nginx 配置,有一定的学习成本

3、在应用层面,在处理请求之前检查客户端的 IP 地址是否在黑名单中。

  • 优点:通过编写代码来实现,相对简单且易于维护。

  • 缺点:代码可能会变得冗长,而且在高并发情况下可能影响性能。

为了方便管理和共享黑名单,通过 nginx + lua + redis 的架构实现 IP 黑名单的功能

配置 nginx.conf

在需要进行限制的 server 的 location 中添加如下配置:

location / {  
    # 如果该location 下存在静态资源文件可以做一个判断        
    #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; # 加上了这条配置,则会根据 access_limit.lua 的规则进行限流  
    alias /usr/local/web/;  
    index  index.html index.htm;  
}  

配置 lua 脚本

/usr/local/lua/access_limit.lua

-- 可以实现自动将访问频次过高的IP地址加入黑名单封禁一段时间  
  
--连接池超时回收毫秒  
local pool_max_idle_time = 10000  
--连接池大小  
local pool_size = 100  
--redis 连接超时时间  
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";  
--封禁IP时间(秒)  
local ip_block_time= 120  
--指定ip访问频率时间段(秒)  
local ip_time_out = 1  
--指定ip访问频率计数最大值(次)  
local ip_max_count = 3  
  
  
--  错误日志记录  
local function errlog(msg, ex)  
    ngx.log(ngx.ERR, msg, ex)  
end  
  
-- 释放连接池  
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  
        ngx.say("redis connct err:",err)  
        return red:close()  
    end  
end  
  
  
--连接redis  
local redis = require "resty.redis"  
local client = redis:new()  
local ok, err = client:connect(redis_host, redis_port)  
-- 连接失败返回服务器错误  
if not ok then  
    close_redis(client)  
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)  
end  
--设置超时时间  
client:set_timeout(redis_connection_timeout)  
  
-- 优化验证密码操作 代表连接在连接池使用的次数,如果为0代表未使用,不为0代表复用 在只有为0时才进行密码校验  
local connCount, err = client:get_reused_times()  
-- 新建连接,需要认证密码  
if  0 == connCount then  
    local ok, err = client:auth(redis_auth)  
    if not ok then  
        errlog("failed to auth: ", err)  
        return  
    end  
    --从连接池中获取连接,无需再次认证密码  
elseif err then  
    errlog("failed to get reused times: ", err)  
    return  
end  
  
-- 获取请求ip  
local function getIp()  
    local clientIP = ngx.req.get_headers()["X-Real-IP"]  
    if clientIP == nil then  
        clientIP = ngx.req.get_headers()["x_forwarded_for"]  
    end  
    if clientIP == nil then  
        clientIP = ngx.var.remote_addr  
    end  
    return clientIP  
end  
  
local cliendIp = getIp();  
  
local incrKey = "limit:count:"..cliendIp  
local blockKey = "limit:block:"..cliendIp  
  
--查询ip是否被禁止访问,如果存在则返回403错误代码  
local is_block,err = client:get(blockKey)  
if tonumber(is_block) == 1 then  
    ngx.exit(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  
--如果超过单位时间限制的访问次数,则添加限制访问标识,限制时间为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)  

总结

以上,便是 Nginx+Lua+Redis 实现的 IP 黑名单功能,具有如下优点:

  • 配置简单轻量,对服务器性能影响小。

  • 多台服务器可以通过共享 Redis 实例共享黑名单。

  • 动态配置,可以手工或者通过某种自动化的方式设置 Redis 中的黑名单

扩展

1、IP 黑名单的应用场景

IP 黑名单在实际应用中具有广泛的应用场景,主要用于保护服务器和应用免受恶意攻击、爬虫或滥用行为的影响。下面列举几个常见的应用场景:

  • 防止恶意访问: 黑名单可以阻止那些试图通过暴力破 解密码、SQL 注入、XSS 攻击等方式进行非法访问的 IP 地址。

  • 防止爬虫和数据滥用: 黑名单可以限制那些频繁访问网站并抓取大量数据的爬虫,以减轻服务器负载和保护数据安全。

  • 防止 DDOS 攻击: 黑名单可以封禁那些发起大规模DDoS攻击的IP地址,保护服务器的稳定性和安全性。

  • 限制访问频率: 黑名单可以限制某个IP在特定时间段内的访问次数,防止恶意用户进行暴力破 解、刷票等行为。

2、高级功能和改进

除了基本的 IP 黑名单功能外,还可以进行一些高级功能和改进,以提升安全性和用户体验:

  • 异常检测和自动封禁: 通过分析访问日志和行为模式,可以实现异常检测功能,并自动将异常行为的 IP 地址封禁,提高安全性。

  • 白名单机制: 除了黑名单,还可以引入白名单机制,允许某些 IP 地址绕过黑名单限制,确保合法用户的正常访问。

  • 验证码验证: 对于频繁访问或异常行为的 IP,可以要求其进行验证码验证,以进一步防止恶意行为。

  • 数据统计和分析: 将黑名单相关的数据进行统计和分析,例如记录封禁 IP 的次数、持续时间等信息,以便后续优化和调整策略。

通过不断改进和优化 IP 黑名单功能,可以更好地保护服务器和应用的安全。

到此这篇关于Nginx实现动态封禁IP的设计方案的文章就介绍到这了,更多相关Nginx动态封禁IP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 服务器使用Nginx部署Springboot项目的详细教程(jar包)

    服务器使用Nginx部署Springboot项目的详细教程(jar包)

    这篇文章主要介绍了服务器使用Nginx部署Springboot项目的详细教程(jar包),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • nginx请求时找路径问题解决

    nginx请求时找路径问题解决

    当你安装了nginx的时候,为nginx配置了如下的location,想要去访问路径下面的内容,可是总是出现404,找不到文件,这是什么原因呢,今天我们就来解决这个问题,感兴趣的朋友一起看看吧
    2023-10-10
  • 升级nginx支持HTTP/2服务端推送的方法

    升级nginx支持HTTP/2服务端推送的方法

    这篇文章主要介绍了升级nginx支持HTTP/2服务端推送的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 详解Nginx服务器中HTTP Headers相关的模块配置使用

    详解Nginx服务器中HTTP Headers相关的模块配置使用

    这篇文章主要介绍了详解Nginx服务器中HTTP Headers相关的模块配置使用,包括ngx_http_headers_module与它的增强版ngx_headers_more的配置使用讲解,需要的朋友可以参考下
    2016-01-01
  • Nginx简要安装配置方法图文教程

    Nginx简要安装配置方法图文教程

    这篇文章主要以图文结合的方式为大家详细介绍了Nginx简要安装配置方法教程,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • nginx实现IP地址透传的示例代码

    nginx实现IP地址透传的示例代码

    默认后端服务器只能看到是前端nginx调度器访问的本机,本文主要介绍了nginx实现IP地址透传的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • 生产环境部署Nginx服务器双机热备部署keepalived的步骤(多种模式教程)

    生产环境部署Nginx服务器双机热备部署keepalived的步骤(多种模式教程)

    今天演示下生产环境keepalived的部署方式,安装模式有很多,比如说主备模型和双主模型,主备分:抢占模式 和 非抢占模式,对Nginx keepalived 双机热备部署相关知识感兴趣的朋友跟随小编一起看看吧
    2024-07-07
  • 国外著名论坛程序IPB(Invision Power Board)在nginx下的配置示例

    国外著名论坛程序IPB(Invision Power Board)在nginx下的配置示例

    这篇文章主要介绍了国外著名论坛程序IPB(Invision Power Board)在nginx下的配置示例,使用fastcgi配置模式,需要的朋友可以参考下
    2014-07-07
  • Nginx定义域名访问方式

    Nginx定义域名访问方式

    这篇文章主要介绍了Nginx定义域名访问方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-05-05
  • nginx进行端口转发的实现

    nginx进行端口转发的实现

    本文主要介绍了nginx进行端口转发的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03

最新评论