• Nginx 中利用 Lua 脚本做访问控制


    使用场景

    需要在后端服务之前做访问控制,或没有后端服务的场景,如静态文件。

    实验环境

    Ubuntu 14.04

    Nginx 1.4.6

    安装 Lua 运行环境

    sudo apt-get install lua5.1 liblua5.1-dev liblua5.1-socket2 libluajit-5.1-2 libluajit-5.1-common nginx-extras

    测试是否支持 lua

    在 Nginx server 配置中增加location块:

     location /lua/test/ {
    
            default_type 'text/html';
    
            content_by_lua 'ngx.say("hello world");';
    
        }

    能看到对应浏览器输出,表示当前Nginx已支持lua脚本:

    简单的签名验证

    举例实现对某个静态文件目录添加签名验证。

    URL参数包含当前时间戳“ts”,以及签名“sign”,lua脚本实现以下功能:

    • 时间戳与当前服务器时间相差上下5分钟以内。
    • 使用secretkey+时间戳做MD5,得到签名字符串,与传入的sign参数对比验证。
    • 如果以上任何一个验证不通过,则返回403错误。

    代码如下:

     location /lua/tmp/ {
    
            alias /tmp/;
    
    
    
            access_by_lua '
    
                -- 配置的app id对应secret key
    
                local appIdKeys = {
    
                    ["app001"] = "secretkey_1",
    
                    ["app002"] = "secretkey_2"
    
                };
    
                local args = ngx.req.get_uri_args();
    
                local timestamp = args["timestamp"];     -- 获取参数的时间戳
    
                local now = os.time();           -- 获取当前时间戳
    
                local offset = math.abs(now - timestamp);  -- 计算时间差绝对值
    
    
    
                -- 时间戳相差超过300秒,返回403
    
                if offset > 300
    
                then                                                                                                     
    
                    ngx.status = ngx.HTTP_FORBIDDEN;
    
                    ngx.say("403 Forbidden<br>"..now);
    
                    ngx.exit(ngx.HTTP_FORBIDDEN);
    
                end
    
    
    
                local appid = args["appid"];  -- 参数中的APP ID
    
                local sign = args["sign"];  -- 参数中的签名
    
                local curr_sign = ngx.md5(appIdKeys[appid] .. timestamp);
    
                -- 如果参数中的 sign 和计算得到的 curr_sign 不相等,则说明访问非法,禁止访问,否则放行访问
    
                if curr_sign ~= sign then
    
                    ngx.status = ngx.HTTP_FORBIDDEN;
    
                    ngx.say("Invalid signature");
    
                    ngx.exit(ngx.HTTP_FORBIDDEN);
    
                end
    
            ';
    
        }

    执行结果:

    多说两句

    配合 lua-nginx-redis 模块,能够读取redis数据,实现更丰富的验证手段。

  • 相关阅读:
    转 mysql front安装与使用教程 mysql 工具
    转 rac中并行 PARALLEL 的设置
    转 oracheck
    OCR 维护 crsd.log
    转 Comparison of Red Hat and Oracle Linux kernel versions and release strings
    转 ORACLE 查看RMAN的备份信息总结
    转载 Some indexes or index [sub]partitions of table VAS.TAB_PUB_CALLLOG have been marked unusable
    ORACLE CBC LATCH 检查
    转 PyCharm 进行调试 以及怎么熟悉一个已经成熟的项目的代码和断点 以及 jetBrains pycharm快捷键
    ecplise 正则替换技巧
  • 原文地址:https://www.cnblogs.com/niehaidong111/p/9668622.html
Copyright © 2020-2023  润新知