nginx_lua的安装

  1. nginx使用luajit进行编译安装

  2. 使用openresty进行yum安装

openresty中将lua和nginx进行封装,详情可查看openresty官网

openresty相关启动命令service openresty start

ngx_lua的相关api使用说明及相关使用

  1. ngx_lua github地址
  2. lua基本语法
  3. openrestry最佳实践

ngx_lua的日常使用场景

ngx_lua的执行顺序,可以看这张图

  1. 通过nginx直接进行一些值的显示,此处用到的一般是content_by_lua模块,lua 1.9.5版本中是content_by_lua_block

  2. 通过nginx作访问权限控制,包括重写等,不过nginx也可以直接重写

ngx_lua的实例

业务场景

老板要求访问一个url时进行用户时作权限控制,有权限者可以查看url,无权限者则直接返回错误

其中开发人员写了一个接口,能通过传入的两个参数(报表名和用户名),返回对应的值

其中实现过程如下

1.登陆入系统lebi.letv.cn中
2.用户需要访问报表链接,其中报表链接均为http://xxx/views/xxx模式
3.访问报表时,nginx先通过lua进行控制,先向开发人员提供的接口http://10.58.91.84:8080/m/api/permission/getSchedulePermission传递报表名和用户名,其中报表名从报表访问链接中获取,用户名从cookie中获取
4.ngx_lua控制访问请求,同时作相关的处理

开发接口返回值说明

开发接口返回值设置三种:

http状态码403为没权限
http状态码200为通过验证
http状态码500为服务错误

相关curl测试状态如下

http 403:

[root@10-110-157-48 conf.d]# curl -i 'http://10.58.91.84:8080/m/api/permission/getSchedulePermission?username=marility&url=http://a/b/c'
HTTP/1.1 403 Forbidden
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 01 Mar 2018 08:26:05 GMT {"success":false,"errorMsg":"没有权限,请联系管理员"} http 200: [root@10-110-157-48 conf.d]# curl -i 'http://10.58.91.84:8080/m/api/permission/getSchedulePermission?username=letv&url=http://a/b/c'
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 01 Mar 2018 09:45:24 GMT {"Msg":"有权限查看","success"} http 500: [root@10-110-157-48 conf.d]# curl -i 'http://10.58.91.84:8080/m/api/permission/getSchedulePermission?username=letv&url='
HTTP/1.1 500 Internal Server Error
Server: Apache-Coyote/1.1
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 01 Mar 2018 10:07:03 GMT
Connection: close {"errorMsg":"java.lang.ArrayIndexOutOfBoundsException: 2","success":false}

以上测试中url中直接传入测试url=http://a/b/c, 实际中应该动态传入访问报表的链接

ngx_lua中的控制
		location ~ ^/views {
access_by_lua '
local res = ngx.location.capture("/matrix_proxy/m/api/permission/getSchedulePermission", {args={username=ngx.var.cookie_example , url=ngx.var.request_uri}})
if res.status == ngx.HTTP_FORBIDDEN then
ngx.exec("@hello")
elseif res.status == ngx.HTTP_OK then
ngx.exec("@/")
elseif res.status == ngx.HTTP_INTERNAL_SERVER_ERROR then
ngx.exec("@servererror")
else
ngx.exec("@error")
end
';}
  1. access_by_lua因为要实现权限控制,所以只能选择access_by_lua,而不能使用content_by_lua

  2. nginx中的lua全文以单引号' '进行囊括

  3. local res, lua中使用local定义一个变量res

  4. 向一个接口发送参数,有两种方法,一种是使用ngx.location.capture方法,另外一种是httpc:request_urihttpc.request_uri为openresty的第三方模块。 httpc.request_url的api使用说明 , openresty加载第三方模块说明 , 本例中使用capture方法

  5. ngx.location.capture方法不能象httpc:request_uri方法一样直接传入url,而只能是$request_uri,所以此处先进行一层的/matrix_proxy/的封装,而/matrix_proxy通过pass_proxy,将请求反代至接口的服务器ip 10.58.91.84:8080

  6. ngx.location.capture api的使用说明

  7. 此处向接口url传递两个参数,因为要传入变量,所以要以{args={ }}的形式来完成。如果使用httpc.request_uri方法的话,应该可以使用lua的..拼接符进行变量与uri的拼接,有兴趣的同学可以自行测试

  8. lua的http状态码与ngx_lua状态对应表

  9. ngx.var.cookie_COOKIE_KEY 获取用户的cookie的value值,上实例中cookie的key为examplengx.var.request_uri 获取nginx中的$request_uri值

  10. 从api说明中可以看到ngx.location.capture有4个slots,其中一个是res.status

  11. 判断res.status的结果与http状态码是否相等,lua中等于判断使用==

  12. lua中多重if判断使用elseif

  13. lua中if完整的语句为 if..else..end

  14. 将四种结果均返回进行执行,ngx.exec表示执行后面的location,@hello 中的 @表示nginx内部的传递,不会进行外部的跳转

完整的ngx_lua配制实例
[root@vm-10-112-42-12 conf.d]# cat matrix-tu.conf
upstream matrix.lebi.letv.cn {
ip_hash;
server 10.112.42.140:8080;
server 10.112.42.141:8080;
server 10.112.42.142:8080;
keepalive 100;
} upstream matrix-tu.lebi.letv.cn {
server 10.110.150.217;
keepalive 100;
} server {
listen 80;
server_name matrix-tu.lebi.letv.cn; access_log /letv/nginx/logs/lebitableau.a.log main;
error_log /letv/nginx/logs/lebitableau.error.log; location = /favicon.ico {
log_not_found off;
log_subrequest off;
}
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_pass http://matrix-tu.lebi.letv.cn;
proxy_send_timeout 18000;
proxy_read_timeout 18000;
proxy_next_upstream error timeout invalid_header http_500;
proxy_connect_timeout 20;
} location = / {
return 403;
} location ~ /authoring/ {
return 403;
} location @/ {
proxy_pass http://matrix-tu.lebi.letv.cn;
} location ~ /matrix_proxy/(.*) {
internal;
proxy_pass http://matrix.lebi.letv.cn/$1$is_args$args;
} location /m/resource/tableauLogin {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_pass http://matrix.lebi.letv.cn;
proxy_send_timeout 18000;
proxy_read_timeout 18000;
proxy_next_upstream error timeout invalid_header http_500;
proxy_connect_timeout 20;
add_header Access-Control-Allow-Origin "http://matrix.lebi.letv.cn";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Credentials true;
} location @error {
default_type 'text/plain';
content_by_lua 'ngx.say("lua error")'; }
location ~ /wenz_img.png$ {
root /etc/nginx/forbidden;
} location ~ /beierx_img.png$ {
root /etc/nginx/forbidden;
} location ~ /error_bg.png$ {
root /etc/nginx/forbidden;
} location @servererror {
default_type 'text/plain';
content_by_lua 'ngx.say("server error")';
} location @forbidden {
return 403;
} location @nousername {
rewrite ^(.*)$ http://matrix.lebi.letv.cn/#/index break; ##所有页面跳转到登录页面
} #proxy_intercept_errors on;
error_page 403 /403.html; location = /403.html {
root /etc/nginx/forbidden;
#internal;
} proxy_intercept_errors on; ##加入将http反代错误拦截并以nginx的错误状态码显示
error_page 404 /404.html; ##自定义nginx的404错误显示页面
location = /404.html {
root /etc/nginx/forbidden;
} location @ok {
default_type 'text/plain';
content_by_lua 'ngx.say("authorized ok, cookie=", ngx.var.cookie_78bdfe11ce353909cb210160a76c330b)';
} location ~ ^/views/ {
#default_type 'text/plain';
access_by_lua '
--local cookie_value = ngx.var.cookie_78bdfe11ce353909cb210160a76c330b
--ngx.say("cookie= ", cookie_value)
local res = ngx.var.cookie_78bdfe11ce353909cb210160a76c330b
if not res then
ngx.exec("@nousername") ##判断是否能获取到用户的cookie,如果不能获取,则直接执行nousername规则,进行用户登录页面的跳转
else
local res = ngx.location.capture("/matrix_proxy/m/api/permission/getSchedulePermission", {args={username=ngx.var.cookie_78bdfe11ce353909cb210160a76c330b , url=ngx.var.request_uri}})
if res.status == ngx.HTTP_FORBIDDEN then
ngx.exec("@forbidden")
elseif res.status == ngx.HTTP_OK then
ngx.exec("@/")
elseif res.status == ngx.HTTP_INTERNAL_SERVER_ERROR then
ngx.exec("@servererror")
else
ngx.exec("@error")
end
end
';}
}

通过lua进行nginx的权限控制的更多相关文章

  1. 使用nginx和iptables做访问权限控制(IP和MAC)

    之前配置的服务器,相当于对整个内网都是公开的 而且,除了可以通过80端口的nginx来间接访问各项服务,也可以绕过nginx,直接ip地址加端口访问对应服务 这是不对的啊,所以我们要做一些限制 因为只 ...

  2. Lua在Nginx的应用

    当 Nginx 标准模块和配置不能灵活地适应系统要求时,就可以考虑使用 Lua 扩展和定制 Nginx 服务.OpenResty集成了大量精良的 Lua 库.第三方模块,可以方便地搭建能够处理超高并发 ...

  3. aProxy: 带认证授权和权限控制的反向代理

    前段时间很多数据库因为没有做好权限控制暴露在外网被删然后遭勒索的事件,而类似的有些内网的web服务也会被开放到公网并且没有做任何权限控制的,这样也会有一定的风险.所以就决定写篇文章简单介绍一个小工具. ...

  4. Kibana访问权限控制

    ELK平台搭建完成后,由于Kibana的服务也是暴露在外网,且默认是没有访问限制的(外部所有人都可以访问到),这明显不是我们想要的,所以我们需要利用Nginx接管所有Kibana请求,通过Nginx配 ...

  5. nginx的权限问题(Permission denied)解决办法

    nginx的权限问题(Permission denied)解决办法 一个nginx带多个tomcat集群环境,老是报如下错误:failed (13: Permission denied) while ...

  6. 「自己开发直播」实现nginx-rtmp-module多频道输入输出与权限控制

    之前写了一篇文章,利用nginx和nginx-rtmp-module实现直播. 不过,之前只是做到了能够直播而已,只能一个人推流,并没有实现多人多频道输入输出,也没有权限控制,只要知道rtmp的URL ...

  7. mysq'l系列之10.mysql优化&权限控制

    网站打开慢如何排查 1.打开网页, 用谷歌浏览器F12, 查看network: 哪个加载时间长就优化哪个 2.如果是数据库问题 2.1 查看大体情况 # top # uptime  //load av ...

  8. 基于ELK 7.50搭建elastalert 监控报警和权限控制

    ELK+监控报警全步骤 需求: 公司要求对出在windows服务器上的日志进行日志分析并根据关键字进行报警,并配置kibana权限控制.下面为详细步骤 环境: centos 7.6 elk版本7.50 ...

  9. Kubernetes-16:一文详解ServiceAccount及RBAC权限控制

    一.ServiceAccount 1.ServiceAccount 介绍 首先Kubernetes中账户区分为:User Accounts(用户账户) 和 Service Accounts(服务账户) ...

随机推荐

  1. MD5文件去重

    //计算文件的MD5码 private string getMD5Hash(string pathName) { string strResult = ""; string str ...

  2. python3 实现堡垒机功能(并发执行命令及上传下载文件)

    转载请注明出处,欢迎提出宝贵意见,谢谢! 功能介绍: 1.主机分组 登录后显示分组主机及主机数量 选择主机组后显示该主机组下所有主机信息,主机名及IP显示输入选择:1.执行命令利用线程并发组内所有主机 ...

  3. 原生js和jquery

    $(document).ready(function() {//jquery的写法 }); (function () { //原生js的写法 })();

  4. spring整合hibernate之买书小测试

    spring来整合hibernate就是用spring来管理hibernate的sessionFactory和让hibernate来使用spring的声明式事务. 一:加入相应的jar包. 二:写hi ...

  5. 【LeetCode 37】解数独

    题目链接 [题解] 回溯法搞一下. 用set和数组下标判重. [代码] class Solution { public: set<int> myset[9]; int hang[9][10 ...

  6. BZOJ 4568: [Scoi2016]幸运数字(倍增+线性基)

    传送门 解题思路 异或最大值肯定线性基了,树上两点那么就倍增搞一搞,就维护每个点到各级祖先的线性基,时间复杂度\(O(nlog^3n)\),并不知道咋过去的. 代码 #include<iostr ...

  7. 自己封装 vue 组件 和 插件

    vue 组件 一.组件的创建,两种方法.(本质上是1.2两种,vue文件,只是创建了一个  组件选项对象,仅是一个js对象)1.定义组件:Vue.component('button-counter', ...

  8. Hadoop 权限管理(转)

    如下图,hadoop访问控制分为两级,其中ServiceLevel Authorization为系统级,用于控制是否可以访问指定的服务,例如用户/组是否可以向集群提交Job,它是最基础的访问控制,优先 ...

  9. Eclipse ALT+/ 代码没有提示功能

    第一种配置如下: 第二: 第三: 以上三种方式是关于eclipse代码提示

  10. mysql常用内置函数-查询语句中不能使用strtotime()函数!

    来自:http://yushine.iteye.com/blog/775407 FROM_UNIXTIME把 unix时间戳转换为标准时间 unix_timestamp把标准时间转换为 unix时间戳 ...