OpenResty + Lua + Redis 实现 客户端ip防刷

一、环境说明:

在Centos7上安装openresty
此次安装采用的是下载openresty的yum源来安装

[[email protected] conf]# sudo  yum-config-manager --add-repo https://openresty.org/yum/cn/centos/OpenResty.repo

sudo:yum-config-manager:找不到命令
解决办法:

[[email protected] conf]# yum -y install yum-utils

下载Openresty的yum源:

[[email protected] conf]# sudo yum-config-manager --add-repo https://openresty.org/yum/cn/centos/OpenResty.repo
已加载插件:fastestmirror
Repository epel is listed more than once in the configuration
Repository epel-debuginfo is listed more than once in the configuration
Repository epel-source is listed more than once in the configuration
adding repo from: https://openresty.org/yum/cn/centos/OpenResty.repo
grabbing file https://openresty.org/yum/cn/centos/OpenResty.repo to /etc/yum.repos.d/OpenResty.repo
repo saved to /etc/yum.repos.d/OpenResty.repo

安装命令:


 yum install openresty openresty-resty openresty-opm
[[email protected] conf]#  yum install openresty openresty-resty openresty-opm

Running transaction
  正在安装    : openresty-zlib-1.2.11-3.el7.centos.x86_64                                                                                                                                  1/7
  正在安装    : openresty-openssl-1.1.0h-3.el7.centos.x86_64                                                                                                                               2/7
  正在安装    : openresty-pcre-8.42-1.el7.centos.x86_64                                                                                                                                    3/7
  正在安装    : openresty-1.15.8.1-1.el7.x86_64                                                                                                                                            4/7
  正在安装    : openresty-resty-1.15.8.1-1.el7.noarch                                                                                                                                      5/7
  正在安装    : openresty-doc-1.15.8.1-1.el7.noarch                                                                                                                                        6/7
  正在安装    : openresty-opm-1.15.8.1-1.el7.noarch
[[email protected]-es11 openresty]# which openresty
/usr/bin/openresty
[[email protected] openresty]# openresty -v
nginx version: openresty/1.15.8.1

到此处安装完成

[[email protected] openresty]# ls
bin  COPYRIGHT  luajit  lualib  nginx  openssl  pcre  pod  resty.index  site  zlib
[[email protected] openresty]# pwd
/usr/local/openresty

二、防刷和限流概念介绍:

防刷的概念:
防刷的目的是为了防止有些IP来爬去我们的网页,获取我们的价格等信息。不像普通的搜索引擎,这种爬去行为我们经过统计最高每秒300次访问,平均每秒266次访问。
由于我们的网站的页面都在CDN上,导致我们的CDN流量会定时冒尖。为了防止这种情况,打算将网页页面的访问从CDN切回主站。同时开启防刷功能,目前设置一秒200次访问即视为非法,会阻止10分钟的访问。

限流的概念
限流的目的是在大促或者流量突增期间,我们的后端服务假设某个接口能够扛住的的QPS为10000,这时候同时有20000个请求进来,经过限流模块,会先放10000个请求,其余的请求会阻塞一段时间。不简单粗暴的返回404,让客户端重试,同时又能起到流量销峰的作用。

原文出处:https://blog.csdn.net/fenglvming/article/details/51996406 此处简单引用,入涉及侵权,及时通知删除

三、客户端ip防刷具体实现


[[email protected]_82_178_centos redislua]# cat /usr/local/openresty/nginx/conf/redislua/ipblack.lua
--Lua
--定义关闭redis函数:
local function close_redis(red)
    if not red then
        return
    end
    -- 释放连接(连接池实现),毫秒
    local pool_max_idle_time = 10000
    -- 连接池大小
    local pool_size = 100
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    local log = ngx_log
    if not ok then
        log(ngx_ERR, "set redis keepalive error : ", err)
    end
end

-- 连接redis
local redis = require(‘resty.redis‘)
local red = redis.new()
      red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 20108)
    if not ok then
        ngx.say("failed to connect: ", err)
        return
    end

    local res, err = red:auth("123456")
    if not res then
        ngx.say("failed to authenticate: ", err)
        return
    end

--获取客户端真实的ip:
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

--定义redis key值格式,incrkey 请求的频率,blockKey被阻塞的key,后面会存入redis:

local incrKey = "user:"..clientIP..":freq"
local blockKey = "user:"..clientIP..":block"

local is_block,err = red:get(blockKey) -- check if ip is blocked
if tonumber(is_block) == 1 then
    ngx.exit(403)
    close_redis(red)
end

--incr redis操作 默认是从0开始,执行一次会累加1
inc  = red:incr(incrKey)

if inc < 10 then
   inc = red:expire(incrKey,1)
end
-- 每秒10次以上访问即视为非法,会阻止1分钟的访问
if inc > 10 then
    --设置block 为 True 为1
    red:set(blockKey,1)
    red:expire(blockKey,60)
end

close_redis(red)

nginx配置文件如下:

[[email protected]_82_178_centos redislua]# less /usr/local/openresty/nginx/conf/vhost/01ip-blacklist.conf
server {
     listen       80;
     server_name  01ip-blacklist.com;
      index index.html index.htm index.php;
        root /data/www/test;
     location  / {
     access_by_lua_file   /usr/local/openresty/nginx/conf/redislua/ipblack.lua;
     default_type ‘text/html‘;
     #content_by_lua ‘ngx.say("hello world")‘;
     access_log  /data/wwwlog/01ip_access.log ;
    }
}

四、测试演示:

ab软件压测:
-c10表示并发用户数为10
-n10表示请求总数为10

[[email protected]_82_178_centos ~]# ab -c 10 -n 10 ‘http://01ip-blacklist.com/1.html

压测后登录redis查看redis key值

127.0.0.1:20108> keys *
1) "dog1"
2) "user:119.29.97.131:block"

[[email protected]_82_178_centos ~]# curl http://01ip-blacklist.com/1.html
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>openresty</center>
</body>
</html>

过一分钟恢复,可以正常的请求
[[email protected]_82_178_centos limit]# curl http://01ip-blacklist.com/1.html
1234

原文地址:https://blog.51cto.com/wujianwei/2426461

时间: 2024-08-09 14:41:16

OpenResty + Lua + Redis 实现 客户端ip防刷的相关文章

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

一)需求背景 为了封禁某些爬虫或者恶意用户对服务器的请求,我们需要建立一个动态的 IP 黑名单. 对于黑名单之内的 IP ,拒绝提供服务. 二)设计方案 实现 IP 黑名单的功能有很多途径: 1.在操作系统层面,配置 iptables,拒绝指定 IP 的网络请求: 2.在 Web Server 层面,通过 Nginx 自身的 deny 选项 或者 lua 插件 配置 IP 黑名单: 3.在应用层面,在请求服务之前检查一遍客户端 IP 是否在黑名单. 为了方便管理和共享,我们通过 Nginx+Lu

nginx+lua+redis实现验证码防采集

之前介绍过在nginx里如何嵌入lua模块,利用nginx+lua可以很好的开发开发nginx的业务逻辑,并且达到高并发的效果. 下面我们就来介绍下利用nginx+lua+redis实现防采集的功能. 现象: 网站在为用户提供服务的同时也在被搜索引擎.采集器不断的抓取,可能会造成网站不堪重负,导致页面放回5XX错误.针对此种情况,我们就要对采集器及搜索引擎来进行访问控制,当然对搜索引擎的控制可能会影响网站的收录. 功能描述: nginx+lua在前端实现客户端的访问控制,将客户端的访问信息记入r

CentOS6.4 安装OpenResty和Redis 并在Nginx中利用lua简单读取Redis数据

1.下载OpenResty和Redis OpenResty下载地址:wget http://openresty.org/download/ngx_openresty-1.4.3.6.tar.gz Redis下载地址:wget http://download.redis.io/releases/redis-2.8.6.tar.gz 2.安装依赖包 yum install -y gcc gcc-c++ readline-devel pcre-devel openssl-devel tcl perl

php获取用户真实IP和防刷机制

一. 如何获取用户IP地址 public static function getClientIp() { if (getenv('HTTP_CLIENT_IP')) { $ip = getenv('HTTP_CLIENT_IP'); } if (getenv('HTTP_X_REAL_IP')) { $ip = getenv('HTTP_X_REAL_IP'); } elseif (getenv('HTTP_X_FORWARDED_FOR')) { $ip = getenv('HTTP_X_FO

nginx+lua+redis(openresty)配置

nginx+lua+redis(openresty)配置 2014-07-18 11:10 2494人阅读 评论(1) 收藏 举报 方案一: 1.安装lua解释器 wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz (http://luajit.org/download.html) 配置lua Lib和include/luajit-$version目录为环境变量 2.下载ngx_devel_kit和lua-nginx-module https:

获取客户端IP地址-----以及--------线上开启redis扩展

/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_client_ip($type = 0) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ar

nginx lua redis 访问频率限制(转)

1. 需求分析 Nginx来处理访问控制的方法有多种,实现的效果也有多种,访问IP段,访问内容限制,访问频率限制等. 用Nginx+Lua+Redis来做访问限制主要是考虑到高并发环境下快速访问控制的需求. Nginx处理请求的过程一共划分为11个阶段,分别是: post-read.server-rewrite.find-config.rewrite.post-rewrite. preaccess.access.post-access.try-files.content.log. 在openre

openresty+lua在反向代理服务中的玩法

openresty+lua在反向代理服务中的玩法 phith0n · 2015/06/02 10:35 0x01 起因 几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科. 由此我想到了一些邪恶的东西:反代既然是所有流量走我的服务器,那我是不是能够在中途做些手脚,达到一些有趣的目的. openresty是一款结合了nginx和lua的全功能web服务器,我感觉其角色和tornado类似,既是一个中间件,也结合了一个后端解释器.所以,我们可以在nginx上用lua开发很多“有趣”的东

Nginx+Lua+Redis 对请求进行限制

Nginx+Lua+Redis 对请求进行限制 一.概述 需求:所有访问/myapi/**的请求必须是POST请求,而且根据请求参数过滤不符合规则的非法请求(黑名单), 这些请求一律不转发到后端服务器(Tomcat) 实现思路:通过在Nginx上进行访问限制,通过Lua来灵活实现业务需求,而Redis用于存储黑名单列表. 相关nginx上lua或redis的使用方式可以参考我之前写的一篇文章: openresty(nginx).lua.drizzle调研 http://www.cnblogs.c