首页 > 系统相关 >nginx+lua实现人机身份验证

nginx+lua实现人机身份验证

时间:2023-10-09 16:11:22浏览次数:35  
标签:.. lua -- ip 身份验证 local nginx 人机 ngx

前言

现在很多网站考虑安全,会做人机验证,可以有效的防刷,防爬虫,防止暴力破解。 你是否遇到过这个 0 这个 0 还有这个 0

如何实现?

如何实现人机验证,又不用和前端耦合在一起,类似waf,在第一层做验证,不通过就直接拦截。nginx支持调用lua脚本,于是可以使用nginx_lua_module来实现。 我们先看看Nginx指令处理阶段: 0 访问某个需要人机验证的页面时,在content_by_lua做处理,如果没经过人机验证,我们返回人机验证页面,浏览器人机验证后,做缓存和cookies,我定了12个小时。也就是12小时内任何页面不需要再做人机验证。 大概的流程如下:   0

实现人机验证步骤

1、申请谷歌recaptcha接口参数,https://www.google.com/recaptcha/admin

2、安装lua环境,nginx编译安装lua-nginx-module

3、nginx配置需要做人机验证的页面

 

  1. 111
  2. nginx配置
# 人机验证通过,需要过滤的接口
location ~ ^(/api1|api2|api3)$ { 
    include vhost/valid.conf;
    access_by_lua_file lua/api_filter.lua;
}
  1. 编写recaptcha.lua做页面人机验证逻辑
-- 1、解密cookies,ip是否已存在缓存
-- local headers = ngx.req.get_headers()
-- 如果已存在验证过的cookies  cap,解析正确则不拦截
local zhong_cap = ngx.var.cookie_cap
if zhong_cap and #zhong_cap > 0 then
    local aes_128_cbc_with_iv = assert(aes:new(key,nil, aes.cipher(128,"cbc"), {iv=iv}))
    -- AES 128 CBC with IV and no SALT
    local cipherBytes = ngx.decode_base64(zhong_cap)
    local cache_ip = aes_128_cbc_with_iv:decrypt(cipherBytes)
    if cache_ip ~= nil and cache_ip and #cache_ip > 0 then
        ngx.log(ngx.INFO, "-------------cache_ip-------------"..cache_ip)
        local request_ip = ngx.var.ip
        ngx.log(ngx.INFO, "-------------request_ip-------------"..request_ip)
        if cache_ip == request_ip then
            cap_cache = "1"
            -- redis续期
            redis_util.set_redis("cap:"..request_ip,cap,cap_second)
            -- ip已经缓存过,直接放行
            ngx.log(ngx.INFO, "-------------正常转发-------------")
            ngx.exec("@proxy_pass")
            return;
        end
    end
end

ngx.log(ngx.INFO, "-------------人机验证-------------"..json.encode(ngx.var.request_uri))
local html = 
"<script>"
.."    window.onload = function() {"
.."        window.challenge_conf = {'is_interactive':1,'cserver_addr':'"/recaptcha/html/cap3.html','rule_id':1 };"
.."        var challenge_uri = '"/recaptcha/html/cap3.html';"
.."        var xhr = new XMLHttpRequest();"
.."        xhr.open('GET', challenge_uri + '?&' + Math.random());"
.."        xhr.send();"
.."        xhr.onload = function() {"
.."          if (xhr.status == 200) {"
.."         console.log(xhr.response);"
.."            document.write(xhr.response);"
.."            document.close();"
.."          }"
.."        };"
.."    }"
.."</script>"
.."<p>加载中...</p>"
ngx.header.content_type="text/html;charset=utf8"
ngx.say(html) 
return、
  1. 编写api_filter过滤是否通过人机验证逻辑
-- 判断白名单(白名单直接通过)
for key, value in ipairs(white_apis) do
    local url = value["url"]
    local args = value["args"]
    if(url == request_uri) then
        ngx.log(ngx.INFO,"3")
        if not args then
            -- 白名单,无参数,直接通过
            ngx.exec("@proxy_pass")
            return
        else
            local flag = 1
            for args_k,args_v in pairs(args) do
                local request_v = tostring(arg_json[args_k])
                args_v = tostring(args_v)
                if(args_v=="" or args_v == nil or args_v == 'nil')then
                    if(request_v == "" or request_v == nil or request_v == 'nil')then
                    else
                        flag = 0
                    end
                else
                    if(args_v == request_v) then
                    else
                        flag = 0
                    end
                end
            end

            if(flag == 1)then
                ngx.log(ngx.INFO,"白名单通过"..request_url)
                ngx.exec("@proxy_pass")
                return;
            end

        end
    end
end

-- 判断接口是否已通过人机验证
local remoteIp = ngx.var.ip
local val = redis_util.get_redis("cap:"..remoteIp)
ngx.log(ngx.INFO,"缓存"..json.encode(val))

if(val == "null")then
    ngx.exit(403)
    -- ngx.header.content_type="application/json;charset=UTF-8"
    -- local ret = {
    --     code= "200",
    --     data= {
    --         current= 1,
    --         size=15,
    --     },
    --     msg= "操作成功",
    --     success= true,
    -- }
    -- ngx.say(json.encode(ret)) 
    return;
else
    ngx.exec("@proxy_pass")
    return;
end
  1. 实现效果如下:
0 验证成功后,会自动跳到具体页面,不成功显示失败页面。 我用的是用户端无交互的人机验证。也可以对接需要交互的,就是点击验证码,或者点击什么都可以。可自行自定义  

最后

具体源码不免费,有需要可以联系QQ839293390,可定制化实现、部署。

标签:..,lua,--,ip,身份验证,local,nginx,人机,ngx
From: https://www.cnblogs.com/suruozhong/p/17751984.html

相关文章

  • FastDFS+Nginx,轻轻松松搭建一个本地文件服务器
    前言1.本地搭建FastDFS文件系统2.局域网测试访问FastDFS3.安装cpolar内网穿透4.配置公网访问地址5.固定公网地址6.测试访问固定二级子域名前言FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决......
  • 记一次Smanga 身份验证绕过漏洞挖掘(CVE-2023-36079)
    记录一次本人CVE漏洞挖掘的过程,此漏洞已被分配编号:CVE-2023-36079引言本文介绍了一次针对某开源项目的身份验证绕过漏洞,此开源项目是一个流媒体管理平台。代码审计审计代码发现功能接口点使用check_user_power()函数进行权限校验。跟踪该函数,发现没有使用常规的JWT或者自......
  • 容器初始化配置nginx
    目录#容器初始化,nginx配置apiVersion:"v1"kind:"Pod"metadata:name:nginx-67spec:volumes:-name:guazaiemptyDir:{}initContainers:-name:chesimage:nginx:alpineimagePullPolicy:IfNotPresentargs:["/......
  • Zabbix监控Nginx的七个链接状态
    一、监控nginx链接数状态status#1.开启status页面功能cat>/etc/nginx/conf.d/status.conf<<'EOF'server{listen80;server_namelocalhost;location/nginx_status{stub_statuson;access_logoff;}}EOF#2.访问测试[ro......
  • 正向代理和反向代理的区别、应用场景及在nginx上的应用
    正向代理和反向代理是两种常见的代理服务器架构,它们在网络通信中扮演不同的角色和应用场景。1、正向代理(ForwardProxy):正向代理是一个位于客户端和目标服务器之间的代理服务器。当客户端需要访问互联网上的资源时,它首先将请求发送给正向代理服务器,然后由代理服务器代表客户端发送请......
  • nginx.conf样本
    #usernobody;worker_processes1;#error_loglogs/error.log;#error_loglogs/error.lognotice;#error_loglogs/error.loginfo;#pidlogs/nginx.pid;#这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit-n)与ngin......
  • Flask审计+Nginx读取
    来自:[SUCTF2019]Pythonginx打开还是源码,直接审计:fromflaskimportFlask,Blueprint,request,Response,escape,render_templatefromurllib.parseimporturlsplit,urlunsplit,unquotefromurllibimportparseimporturllib.requestapp=Flask(__name__)#In......
  • nginx实现后端tomcat的负载均衡调度
    1.负载均衡主机和网络地址规划10.0.0.152proxy.magedu.orgnginx10.0.0.150t1.magedu.orgtomcat110.0.0.160t2.magedu.orgtomcat2#只需在10.0.0.52的nginx主机上实现域名解析[root@localhost~]#cat/etc/hosts127.0.0.1localhost......
  • 编译安装nginx,实现多域名 https
     #编译安装nginx[root@centos8~]#yum-yinstallgccpcre-developenssl-develzlib-devel[root@centos8~]#useradd-s/sbin/nologinnginx[root@centos8~]#cd/usr/local/src/[root@centos8src]#wgethttp://nginx.org/download/nginx-1.18.0.tar.gz......
  • nginx负载均衡中常见的算法及原理有哪些?
     #1)轮询(round-robin) 轮询为负载均衡中较为基础也较为简单的算法,它不需要配置额外参数。假设配置文件中共有台服务器,该算法遍历服务器节点列表,并按节点次序每轮选择一台服务器处理请求。当所有节点均被调用过一次后,该算法将从第一个节点开始重新一轮遍历。 特点:由于......