OpenResty 最佳实践手册推荐地址 : https://moonbingbing.gitbooks.io/openresty-best-practices/content/

echo-nginx-module地址 : https://github.com/openresty/echo-nginx-module

lua-nginx-module地址 : https://github.com/openresty/lua-nginx-module

redis2-nginx-module地址 : https://github.com/openresty/redis2-nginx-module

lua-resty-redis地址 : https://github.com/openresty/lua-resty-redis

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
  
 
# OpenResty 最佳实践手册推荐地址:  https://moonbingbing.gitbooks.io/openresty-best-practices/content/
 
一、安装扩展
1. 安装LuaJIT
> wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
 
> tar -zxvf LuaJIT-2.0.5.tar.gz
 
> make && make install
 
 
2. 安装nginx模块: echo-nginx-module、lua-nginx-module、redis2-nginx-module
> git clone https://github.com/openresty/echo-nginx-module.git
> git clone https://github.com/openresty/lua-nginx-module.git
> git clone https://github.com/openresty/redis2-nginx-module.git
 
 
3. 下载redis.lua类库包
> mkdir /usr/local/nginx/conf/lua
> cd /usr/local/nginx/conf/lua/
> git clone https://github.com/openresty/lua-resty-redis.git
> cd ./lua-resty-redis/lib/resty
> pwd
/usr/local/nginx/conf/lua/lua-resty-redis/lib/resty
 
 
--异常处理:
1. nginx: [emerg] dlopen() "/usr/local/nginx/modules/ngx_http_lua_module.so" failed (libluajit-5.1.so.2: cannot open shared object file: No such file or directory) in /usr/local/nginx/conf/nginx.conf:12
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
#将依赖库软链至 LD_PRELOAD 目录
> ln -s /usr/local/lib/libluajit-5.1.* /usr/lib/
> ln -s /usr/local/lib/libluajit-5.1.* /lib64/
 
 
 
二、开启配置项
 
====================================================================================Nginx启用扩展配置如下  begin
 
1. #编辑nginx.conf配置文件
> vim /usr/local/nginx/conf/nginx.conf
    1. 加载配置
    load_module /usr/local/nginx/modules/ngx_http_echo_module.so;
    load_module /usr/local/nginx/modules/ngx_http_lua_module.so;
    load_module /usr/local/nginx/modules/ngx_http_redis2_module.so;
 
    2. 引入redis类库包
    http
        {
            #more_set_headers 'Node:0' 'Server:JSX/1.0 (Win32)';
            #引入redis类库包
            lua_package_path "/usr/local/nginx/conf/lua/lua-resty-redis/lib/resty/redis.lua;;";
 
            ...
 
        }
 
 
2. 在需要开启的域名配置文件下加入lua处理
> vim /usr/local/nginx/conf/vhost/AXURE/demo.jsx6.com.conf
server {
    listen       80;
    server_name demo.jsx6.com;
    underscores_in_headers on;
    root /data/www/demo/public;
    index index.html index.htm index.php;
    charset utf-8;
    #include /usr/local/nginx/conf/cors;
 
    location / {
 
        #调试模式(即关闭lua脚本缓存,此操作严重影响nginx性能,如果需必要,强烈建议开启lua_code_cache.这里我们调试需要,所以临时关闭lua_code_cache)
        lua_code_cache off;
 
        #引入自动识别封解禁频繁访问IP&&Token鉴权
        access_by_lua_file /usr/local/nginx/conf/lua/confine.lua;
 
        if (!-f $request_filename) {
            rewrite ^/(.+)$ /index.php?url=$1 last;
            break;
        }
    }
 
    error_page 500 /500.html;
    location = /500.html {
        default_type application/json;
        return 500 '{"message":"Permission denied","status":500}';
    }
 
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   unix:/tmp/php-cgi-7.1.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_buffering off;
        include        fastcgi_params;
    }
 
    location ~ /\. {
        deny all;
    }
}
 
 
3. 编辑 confine.lua
> cd /usr/local/nginx/conf/lua
> vim /usr/local/nginx/conf/lua/confine.lua
//----------------------------- confine.lua     内容如下 begin
 
--连接redis
local redis = require "resty.redis_iresty"
local red = redis:new()
--3秒超时
red:set_timeout(3000)
 
--host,prot
--local ok, err = red:connect("unix:/path/to/redis.sock")
local ok, err = red:connect("127.0.0.1""6379")
if not ok then
    return
end
 
--redis认证
local res, err = red:auth("password")
if not res then
    return
end
 
--选择DB库
local res, err = red:select(6)
if not res then
    return
end
 
 
--获取指定cookie
local function GetCookie()
    ngx.header['Content-Type'] = "application/json;charset=utf-8"
    --获取所有cookie,这里获取到的是一个字符串,如果不存在则返回nil
    --ngx.print(ngx.var.http_cookie)
    --获取指定cookie_{name}
    ngx.print(ngx.var.cookie_Token)
end
 
--判断是否是直接请求文件,如果是则检查cookie授权
--请求url:ngx.var.uri; 目录路径关键字匹配:upload/axure
local res = string.match(ngx.var.uri, 'upload/axure')
if res ~= nil then
    GetCookie()
end
 
 
--获取header头 并 检查token是否有效
local function TokenConfine(red, status)
    local headers = ngx.req.get_headers()
    --检查token是否存在
    if headers["token"] == nil then
        ngx.header['Content-Type'] = "application/json;charset=utf-8"
        ngx.status = status
        ngx.print('{"status":' .. status .. ',"message":"请求头缺少token参数,请先登录授权"}')
        ngx.exit(status)
    end
    --ngx.print(headers["token"])
    --检查指定参数是否存在于redis
    isExist, err = red:exists("AUTH:" .. headers["token"])
    if isExist == 0 or isExist == ngx.null then
        ngx.header['Content-Type'] = "application/json;charset=utf-8"
        ngx.status = status
        ngx.print('{"status":' .. status .. ',"message":"token是无效的,登录失效,请登录"}')
        ngx.exit(status)
    end
end
 
--TokenConfine(red, 401)
 
--自动识别封解禁频繁访问IP
local function IpConfine(red, status)
 
    ip_bind_time = 600  --封禁IP时间(秒)
    ip_time_out = 10    --指定ip访问频率时间段(秒)
    connect_count = 100 --指定ip访问频率计数最大值
 
    --查询ip是否在封禁段内,若在则返回403错误代码
    --因封禁时间会大于ip记录时间,故此处不对ip时间key和计数key做处理
    is_bind, err = red:exists("IPCONFINE:" .. ngx.var.remote_addr .. ":bind")
    if is_bind ~= 0 and is_bind ~= ngx.null then
        ngx.header['Content-Type'] = "application/json;charset=utf-8"
        ngx.status = status
        ngx.print('{"status":' .. status .. ',"message":"访问频繁,触发IP封禁.解封倒计时:' .. ip_bind_time .. '秒"}')
        ngx.exit(status)
    end
    start_time, err = red:get("IPCONFINE:" .. ngx.var.remote_addr .. ":time")
    ip_count, err = red:get("IPCONFINE:" .. ngx.var.remote_addr .. ":count")
 
    --如果ip记录时间大于指定时间间隔或者记录时间或者不存在ip时间key则重置时间key和计数key
    --如果ip时间key小于时间间隔,则ip计数+1,且如果ip计数大于ip频率计数,则设置ip的封禁key为1
    --同时设置封禁key的过期时间为封禁ip的时间
    if start_time == ngx.null or os.time() - start_time > ip_time_out then
        res, err = red:set("IPCONFINE:" .. ngx.var.remote_addr .. ":time", os.time())
        res, err = red:expire("IPCONFINE:" .. ngx.var.remote_addr .. ":time", ip_time_out)
        res, err = red:set("IPCONFINE:" .. ngx.var.remote_addr .. ":count", 1)
        res, err = red:expire("IPCONFINE:" .. ngx.var.remote_addr .. ":count", ip_time_out)
    else
        ip_count = ip_count + 1
        res, err = red:incr("IPCONFINE:" .. ngx.var.remote_addr .. ":count")
        if ip_count >= connect_count then
            res, err = red:set("IPCONFINE:" .. ngx.var.remote_addr .. ":bind", 1)
            res, err = red:expire("IPCONFINE:" .. ngx.var.remote_addr .. ":bind", ip_bind_time)
        end
    end
end
 
IpConfine(red, 403)
 
local ok, err = red:close()
 
//----------------------------- confine.lua     内容如下 end
 
 
4. nginx加载配置
    1).测试
    > nginx -t
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
 
    2).加载配置
    > nginx -s reload
====================================================================================Nginx启用扩展配置如下  end
 
 
  

---------------------------------------------------------------------------------------------
不忘初心 方得始终!

唯有志存高远,方能风行天下。

道之所存,虽千万人吾往矣! 情之所钟,虽千万里吾念矣~

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。