Nginx结合Openresty通过Lua+Redis实现动态封禁IP

 更新时间:2023年11月28日 10:28:23   作者:乐辞  
为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单,本文主要介绍了Nginx结合Openresty通过Lua+Redis实现动态封禁IP,感兴趣的可以了解一下

需求

为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单。对于黑名单中的 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结合Openresty通过Lua+Redis实现动态封禁IP的文章就介绍到这了,更多相关Nginx 动态封禁IP内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • nginx设置资源请求目录的方式详解

    nginx设置资源请求目录的方式详解

    最近有一个需求.就是url指定路径下访问服务器的静态资源,这篇文章主要给大家介绍了关于nginx设置资源请求目录的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • Nginx跨域访问配置方式(Web反向代理跨域访问配置)

    Nginx跨域访问配置方式(Web反向代理跨域访问配置)

    这篇文章主要介绍了Nginx跨域访问配置方式(Web反向代理跨域访问配置),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • 安装配置php-fpm来搭建Nginx+PHP的生产环境

    安装配置php-fpm来搭建Nginx+PHP的生产环境

    这篇文章主要介绍了安装配置php-fpm来搭建Nginx+PHP的生产环境的方法,php-fpm的作用是将FastCGI进程管理整合进PHP包,需要的朋友可以参考下
    2016-01-01
  • 针对OpenSSL安全漏洞调整Nginx服务器的方法

    针对OpenSSL安全漏洞调整Nginx服务器的方法

    这篇文章主要介绍了针对OpenSSL漏洞调整Nginx服务器的方法,2014年爆出的SSL安全漏洞震惊了全世界,需要的朋友可以参考下
    2015-06-06
  • 启动Nginx.exe出现闪退问题的解决方案

    启动Nginx.exe出现闪退问题的解决方案

    在做项目时,使用老师给的代码,点击Nginx.exe出现闪退的情况,出现这个问题可能出现的情况,端口号被占用或者logs下文件路径有问题,所以本文小编给大家介绍了启动Nginx.exe出现闪退问题的解决方案,需要的朋友可以参考下
    2024-03-03
  • nginx实现数据库端口转发

    nginx实现数据库端口转发

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

    Nginx配置ssl实现https的全过程记录

    这篇文章主要给大家介绍了关于Nginx配置ssl实现https的相关资料,文章通过实例代码介绍的非常详细,对大家学习或者使用Nginx具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03
  • Nginx Gunicorn flask项目部署思路分析详解

    Nginx Gunicorn flask项目部署思路分析详解

    这篇文章主要为大家介绍了Nginx Gunicorn flask项目部署思路分析详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Nginx+Tomcat搭建高性能负载均衡集群的实现方法

    Nginx+Tomcat搭建高性能负载均衡集群的实现方法

    这篇文章主要介绍了Nginx+Tomcat搭建高性能负载均衡集群的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • Nginx搭载负载均衡及前端项目部署

    Nginx搭载负载均衡及前端项目部署

    本文介绍了如何使用Nginx实现负载均衡和前端项目部署,通过配置Nginx的负载均衡功能,可以有效地分发客户端请求,提高服务器的处理能力,感兴趣的可以了解一下
    2023-11-11

最新评论