高频访问IP弹验证码架构图 让被误伤的用户能及时自行解封的策略
高频访问IP限制 --Openresty(nginx + lua) [反爬虫之旅] - Silbert Monaphia - CSDN博客 https://blog.csdn.net/qq_29245097/article/details/77461719

我不准备在web应用中做ip的统计和查封,应用就应该只做业务功能,这些基础东西应该由我们应用的前部——专业的Nginx实现
Nginx本身就有根据ip访问频率的设置,比如“服务器访问频率限制和IP限制”就有提到。不过Nginx只能强硬地返回个403状态码什么的,但是我们这次ip封禁时间比较久,那么如果误伤到用户,我们仅仅强硬地返回个403,用户将会毫无办法证明自己是人,然后要等很久,那就伤用户就伤得很深了,因此我们需要一种可以让被误伤的用户能及时自行解封的策略,验证码就是一个不错的选择,可是Nginx该怎么接入验证码呢?
-anti_spider
-conf/
-nginx.conf
-lua/
-access.lua
-log/
-error.log
-geetest_web/
-demo/
-sdk/
-geetest.py
-setup.py
-requirements.txt
worker_processes ;
error_log logs/error.log;
events {
worker_connections ;
}
http {
server {
listen ;
location / {
access_by_lua_file 'lua/access.lua';
content_by_lua 'ngx.say("Welcome PENIS!")';
}
}
}
access.lua
-- package.path = '/usr/local/openresty/nginx/lua/?.lua;/usr/local/openresty/nginx/lua/lib/?.lua;'
-- package.cpath = '/usr/local/openresty/nginx/lua/?.so;/usr/local//openresty/nginx/lua/lib/?.so;' -- 连接redis
local redis = require 'resty.redis'
local cache = redis.new()
local ok ,err = cache.connect(cache,'127.0.0.1','6379')
cache:set_timeout(60000)
-- 如果连接失败,跳转到label处
if not ok then
goto label
end -- 白名单
is_white ,err = cache:sismember('white_list', ngx.var.remote_addr)
if is_white == 1 then
goto label
end -- 黑名单
is_black ,err = cache:sismember('black_list', ngx.var.remote_addr)
if is_black == 1 then
ngx.exit(ngx.HTTP_FORBIDDEN)
goto label
end -- ip访问频率时间段
ip_time_out = 60
-- ip访问频率计数最大值
connect_count = 45
-- 60s内达到45次就ban -- 封禁ip时间(加入突曲线增长算法)
ip_ban_time, err = cache:get('ip_ban_time:' .. ngx.var.remote_addr)
if ip_ban_time == ngx.null then
ip_ban_time = 300
res , err = cache:set('ip_ban_time:' .. ngx.var.remote_addr, ip_ban_time)
res , err = cache:expire('ip_ban_time:' .. ngx.var.remote_addr, 43200) -- 12h重置
end -- 查询ip是否在封禁时间段内,若在则跳转到验证码页面
is_ban , err = cache:get('ban:' .. ngx.var.remote_addr)
if tonumber(is_ban) == 1 then
-- source携带了之前用户请求的地址信息,方便验证成功后返回原用户请求地址
local source = ngx.encode_base64(ngx.var.scheme .. '://' ..
ngx.var.host .. ':' .. ngx.var.server_port .. ngx.var.request_uri)
local dest = 'http://127.0.0.1:5000/' .. '?continue=' .. source
ngx.redirect(dest,302)
goto label
end -- ip记录时间key
start_time , err = cache:get('time:' .. ngx.var.remote_addr)
-- ip计数key
ip_count , err = cache:get('count:' .. ngx.var.remote_addr) -- 如果ip记录时间的key不存在或者当前时间减去ip记录时间大于指定时间间隔,则重置时间key和计数key
-- 如果当前时间减去ip记录时间小于指定时间间隔,则ip计数+1,
-- 并且ip计数大于指定ip访问频率,则设置ip的封禁key为1,同时设置封禁key的过期时间为封禁ip时间 if start_time == ngx.null or os.time() - tonumber(start_time) > ip_time_out then
res , err = cache:set('time:' .. ngx.var.remote_addr , os.time())
res , err = cache:set('count:' .. ngx.var.remote_addr , 1)
else
ip_count = ip_count + 1
res , err = cache:incr('count:' .. ngx.var.remote_addr)
-- 统计当日访问ip集合
res , err = cache:sadd('statistic_total_ip:' .. os.date('%x'), ngx.var.remote_addr)
if ip_count >= connect_count then
res , err = cache:set('ban:' .. ngx.var.remote_addr , 1)
res , err = cache:expire('ban:' .. ngx.var.remote_addr , ip_ban_time)
res , err = cache:incrby('ip_ban_time:' .. ngx.var.remote_addr, ip_ban_time)
-- 统计当日屏蔽ip总数
res , err = cache:sadd('statistic_ban_ip:' .. os.date('%x'), ngx.var.remote_addr)
end
end ::label::
local ok , err = cache:close()
高频访问IP弹验证码架构图 让被误伤的用户能及时自行解封的策略的更多相关文章
- Linux上的ftp服务器vsftpd之配置满天飞--设置匿名用户访问(不弹出用户名密码框)以及其他用户可正常上传
一.问题背景 没事谁折腾这鬼玩意哦...还不是因为bug. 我们的应用,用户头像是存在ftp上的.之前的ftp服务器是一台windows,我们后台服务器程序收到用户上传头像的请求时,会用一个ROOT/ ...
- 网络知识--OSI七层网络与TCP/IP五层网络架构及二层/三层网络
作为一个合格的运维人员,一定要熟悉掌握OSI七层网络和TCP/IP五层网络结构知识. 废话不多说!下面就逐一展开对这两个网络架构知识的说明:一.OSI七层网络协议OSI是Open System Int ...
- 网络知识梳理--OSI七层网络与TCP/IP五层网络架构及二层/三层网络(转)
reference:https://www.cnblogs.com/kevingrace/p/5909719.html https://www.cnblogs.com/awkflf11/p/9190 ...
- Linux(7)- Nginx.conf主配置文件、Nginx虚拟主机/访问日志/限制访问IP/错误页面优化、Nginx反向代理、Nginx负载均衡
一.Nginx.conf主配置文件 Nginx主配置文件conf/nginx.conf是一个纯文本类型的文件,整个配置文件是以区块的形式组织的.一般,每个区块以一对大括号{}来表示开始与结束. 核心模 ...
- java异常架构图 和几个面试题
1.java异常架构图 粉红色的是受检查的异常(checked exceptions),其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明.受检查的异常必须在编译时被 ...
- C# C/S系统软件开发平台架构图(原创)
企业版V4.0 - 架构图 企业版V4.0 - 桥接功能.后台连接策略 桥接功能是指应用策略模式,由用户配置本地INI文件选择ADO直连(ADO-Direct)或者调用WCF服务接口访问远程服务器后台 ...
- FastDFS简介和架构图(内容来自于阅读fastdfs官方文档的总结)
一.FastDFS简介 1. FastDFS是一个轻量级的开源分布式文件系统 2. FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡 3. FastDFS实现了软件 ...
- centos服务器如何监控访问ip,并将非法ip通过防火墙禁用
centos服务器如何监控访问ip,并将非法ip通过防火墙禁用 上周给朋友帮忙,上架了一款小游戏(年年有鱼),项目刚一上线,就遇到了ddos攻击,阿里云连续给出了6次ddos预警提示,服务器一度处于黑 ...
- 纯净得只剩下字的访问IP查询API
纯净得只剩下字的访问IP查询API 实用资源 / 2018-02-26 / 3 条评论 看到一个好玩的,就随手收藏一下,本API作用:获取用户真实IP,而获取用户IP常见的坑有两个,开发支付的时候也需 ...
随机推荐
- PhoneGap开发不可或缺的五件装备
PhoneGap是一种介于WebApp和NativeApp之间的解决方案,它为每种移动客户端提供一个Native的壳,这种壳里边包着一个Web应 用.借助于壳,Web应用可以被安装,可以被发布到各大市 ...
- CentOS 7 Minimal编译安装MySQL5.6
写在前面,编译安装MySQL的优势:平台无关.可设定参数按需安装.安装的MySQL目录独立(方便清楚).更好的平台耦合及运行性能(很多运维的观点):缺点:编译安装较慢. 一.撤换系统防火墙 注:Cen ...
- C++编程 - tuple、any容器
C++编程 - tuple.any容器 flyfish 2014-10-29 一 tuple tuple是固定大小的容器,每一个元素类型能够不同 作用1 替换struct struct t1 { in ...
- windows cmd中查看某个命令所在的路径
需求描述: 之前用linux环境下的which命令就能看到某个命令的绝对路径, 然后想在windows下的cmd中是否也能够查看到命令的绝对路径呢 操作过程: 1.windows环境下,通过where ...
- 浅谈无缓存I/O操作和标准I/O文件操作差别
首先,先略微了解系统调用的概念: 系统调用,英文名system call,每一个操作系统都在内核里有一些内建的函数库,这些函数能够用来完毕一些系统系统调用把应用程序的请求传给内核,调用对 ...
- Mac普通用户修改了/etc/sudoers文件的解决办法
1.开启 Root 账户 打开“系统偏好设置”,进入“用户与群组”面板,记得把面板左下角的小锁打开,然后选择面板里的“登录选项”.在面板右边你会看到“网络账户服务 器”,点击它旁边的“加入…”按钮,再 ...
- excel中,一系列单元格中包含某一个字段的单元格数量?
excel中,一系列单元格中包含某一个字段的单元格数量?这个怎么写公式?如:A列单元格A1-A7的内容分别为 A.AB.BC.AC.CD.AD.EA,怎么数这一列中几个单元格的内容包含A字母? 任意单 ...
- python2.0_day21_web聊天室一
bbs系统项目中我们用到的ajax不多,但是在聊天室里用到的全是ajax,所以本项目的主要内容就是:前端使用ajax传输json格式的数据是本节的重点以及 前端函数的的使用.http协议的特点是:短链 ...
- ios Instruments 内存泄露
本文转载至 http://my.oschina.net/sunqichao/blog?disp=2&p=3 虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是 ...
- springjdbc的批量操作
这里主要是看的官方文档,如何翻译: NamedParameterJdbcTemplate The NamedParameterJdbcTemplate class adds support for p ...