Nginx + Lua + Redis:打造智能 IP 黑名单系统

news2024/10/30 8:37:59

Nginx + Lua + Redis:打造智能 IP 黑名单系统

nginx通过Lua+Redis实现动态封禁IP

需求背景

在Web服务中,为了防止恶意用户或爬虫对服务器造成不必要的负载和潜在的安全威胁,我们可以通过设置动态IP黑名单来拒绝来自这些IP的请求。本文将详细介绍如何使用Nginx配合Lua脚本及Redis数据库实现这一功能,并允许为每个被封禁的IP设定失效时间。

实现方案对比

在实现 IP 黑名单功能时,有多种方案可供选择:

  • 优点:直接在服务器物理层面拦截指定 IP 的网络请求,操作直接且高效。

  • 缺点:需要手动编辑配置文件,操作繁琐且不灵活,难以动态管理。

  • 优点:通过 Nginx 和 Lua 脚本的结合,可动态实现 IP 封禁,并设置封禁时间,实现分布式封禁。

  • 缺点:需要一定的 Lua 脚本和 Nginx 配置知识,但相对容易学习和掌握。

  • 优点:通过编写代码实现 IP 黑名单功能,相对简单且易于维护。

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

  1. 操作系统层面(iptables):

  2. Web 服务器层面(Nginx + Lua):

  3. 应用层面:

为了兼顾灵活性和管理便捷性,我们选择通过 Nginx + Lua + Redis 的架构来实现 IP 黑名单功能。

这里选择结合Nginx与Lua脚本并通过Redis存储黑名单数据的方法,以达到灵活管理并共享黑名单的目的。

Nginx与Lua脚本并通过Redis存储黑名单数据的方法

操作步骤

1. 安装必要的软件确保你的系统已经安装了OpenResty版Nginx以及Redis服务。可以参考官方文档完成相关安装。

2. 创建Lua脚本文件创建一个名为access_limit.lua的文件,路径根据实际需要调整,例如 /usr/local/lua/access_limit.lua。该脚本负责检查客户端IP是否位于Redis维护的黑名单内,并据此决定是否继续处理请求。

lua脚本具体内容凯哥会放在文末。

配置 Nginx.conf

在 Nginx 配置文件中,我们需要在需要进行限制的 server 的 location 中添加 Lua 脚本的访问控制。

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 文件中,我们编写 Lua 脚本来实现 IP 黑名单的访问控制。该脚本将从 Redis 中读取黑名单列表,并判断当前请求的 IP 是否在黑名单中。

/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 中的黑名单,实现动态管理。

扩展应用场景

  • 防止恶意访问:阻止暴力破解密码、SQL 注入等非法访问。

  • 防止爬虫和数据滥用:减轻服务器负载,保护数据安全。

  • 防止 DDoS 攻击:封禁发起大规模攻击的 IP 地址,保护服务器稳定性。

  • 限制访问频率:防止暴力破解、刷票等恶意行为。

  • 异常检测和自动封禁:通过分析访问日志和行为模式,自动封禁异常行为的 IP。

  • 白名单机制:允许特定 IP 绕过黑名单限制,确保合法用户正常访问。

  • 验证码验证:对频繁访问或异常行为的 IP 进行验证码验证,增强安全性。

  • 数据统计和分析:记录封禁 IP 的次数、持续时间等信息,为后续优化提供依据。

  1. IP 黑名单的实际应用

  2. 高级功能和改进

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2227881.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

京东文字点选验证码识别

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 该文章模型已经上线ocr识别网站,欢迎测试!!,地址:https://yxlocr.windy-rain.cn/ocr/textclick/7 该验证码成品展示效果如下: 京东点选验证码数据集如下:…

2024最新的开源博客系统:vue3.x+SpringBoot 3.x 前后端分离

本文转载自:https://fangcaicoding.cn/article/54 大家好!我是方才,目前是8人后端研发团队的负责人,拥有6年后端经验&3年团队管理经验,截止目前面试过近200位候选人,主导过单表上10亿、累计上100亿数据…

局域网 docker pull 使用代理拉取镜像

局域网 docker pull 使用代理拉取镜像 1、需求: 我有win主机,上面装有代理可连接dockerhub;我另有linux主机,直接pull因墙失败,想走win的代理访问dockerhub拉镜像;两台主机在同一个局域网中; …

项目1 yolov5鱼苗检测计数

yolov5鱼苗检测 1. yolov5鱼苗检测1.1. 环境配置1.2 Predict1.3 Validate1.4 Train1.5 生成 ONNX 2 代码解析2.1 模型2.2 数据集2.3 损失函数2.4 训练2.5 预测 之前做的项目,再回顾一下 环境:GPU1卡,CPU4核,每显卡12GB&#xff0c…

音视频入门基础:FLV专题(18)——Audio Tag简介

一、引言 根据《video_file_format_spec_v10_1.pdf》第75页,如果某个Tag的Tag header中的TagType值为8,表示该Tag为Audio Tag: 这时StreamID之后紧接着的就是AudioTagHeader,也就是说这时Tag header之后的就是AudioTagHeader&…

(二 上)VB 2010 设计初步

目录 一、常用类应用 1.Console类控制台 2.窗体基本控件 二、面向对象程序设计 1.类和对象 2.对象的属性、方法、事件属 1.属性 2.方法 3.事件、事件过程 1.事件 2.事件过程 3.对象浏览器 三、.NET类库与命名空间 1.命名空间 常用命名空间 1.System命名空间 2.…

基于uniapp微信小程序的校园二手书交易系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…

学习threejs,使用粒子实现下雪特效

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Points简介1.11 ☘️…

服务器文件访问协议

服务器文件访问协议 摘要NFS、CIFS、SMB概述SMBWindows SMBLinux SambaPython SMB NFS 摘要 本篇博客参考网上文档和博客,对基于网络的服务器/主机的文件访问、共享协议进行简要总结,完整内容将会不断更新,以便加深理解和记忆 NFS、CIFS、S…

基于ResNet50模型的船型识别与分类系统研究

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【LSTM模型实现光伏发电功率的预测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模…

NVR小程序接入平台/设备EasyNVR多个NVR同时管理视频监控新选择

在数字化转型的浪潮中,视频监控作为安防领域的核心组成部分,正经历着前所未有的技术革新。随着技术的不断进步和应用场景的不断拓展,视频监控系统的兼容性、稳定性以及安全性成为了用户关注的焦点。NVR小程序接入平台/设备EasyNVR&#xff0c…

单元测试详解

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 为什么需要单元测试? 从产品角度而言,常规的功能测试、系统测试都是站在产品局部或全局功能进行测试,能够很好地与用户的需…

基于 ThinkPHP+Mysql 灵活用工_灵活用工系统_灵活用工平台

基于 ThinkPHPMysql 灵活用工灵活用工平台灵活用工系统灵活用工小程序灵活用工源码灵活用工系统源码 开发语言 ThinkPHPMysql 源码合作 提供完整源代码 软件界面展示 一、企业管理后台 二、运用管理平台 三、手机端

【Linux内核揭秘】深入理解命令行参数和环境变量

文章目录 命令行参数什么是命令行参数main函数的参数 环境变量什么是环境变量常见的环境变量PATHHOMESHELLPWDOLDPWD 本地变量总结 命令行参数 什么是命令行参数 形如这样的命令后面带的选项就是命令行参数。 首先我们要了解一下命令行参数的原理。 我们知道像ls,mkdir,touch等…

Pytest-Bdd-Playwright 系列教程(4):基于敏捷的通用步骤定义

Pytest-Bdd-Playwright 系列教程(4):基于敏捷的通用步骤定义 前言一、项目结构二、通用步骤定义三、特性文件设计四、测试脚本实现五、运行测试总结 前言 在敏捷迭代中,为了适应快速、高频的交付,自动化测试框架的设计…

银行信贷风控专题:Python、R 语言机器学习数据挖掘应用实例合集:xgboost、决策树、随机森林、贝叶斯等...

全文链接:https://tecdat.cn/?p38026 分析师:Fanghui Shao 在当今金融领域,风险管控至关重要。无论是汽车贷款违约预测、银行挖掘潜在贷款客户,还是信贷风控模型的构建,以及基于决策树的银行信贷风险预警,…

Ubuntu22.04环境搭建MQTT服务器

官网: https://mosquitto.org 1.引入库 sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa2.升级安装工具 sudo apt-get update 3.安装 sudo apt-get install mosquitto 4.安装客户端 sudo apt-get install mosquitto-clients5.添加修改配置文件 进…

Python | Leetcode Python题解之第519题随机翻转矩阵

题目: 题解: class Solution:def __init__(self, m: int, n: int):self.m mself.n nself.total m * nself.map {}def flip(self) -> List[int]:x random.randint(0, self.total - 1)self.total - 1# 查找位置 x 对应的映射idx self.map.get(x,…

【linux网络编程】| socket套接字 | 实现UDP协议聊天室

前言:本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以, 我们主要就是要实现客户端以及服务端的逻辑代码。 那么, 接下来开始我们的学习吧。 ps:本节内容…

Windows 下实验视频降噪算法 MeshFlow 详细教程

MeshFlow视频降噪算法 Meshflow 视频降噪算法来自于 2017 年电子科技大学一篇高质量论文。 该论文提出了一个新的运动模型MeshFlow,它是一个空间平滑的稀疏运动场 (spatially smooth sparse motion field),其运动矢量 (motion vectors) 仅在网格顶点 (m…