原文 地址:
https://www.superman2014.com/2015/08/30/nginxluaredis-%E9%99%90%E5%88%B6ip%E7%9A%84%E8%AE%BF%E9%97%AE%E6%AC%A1%E6%95%B0/
一、安装环境:
二、安装步骤:
1、安装LuaJIT-2.0.2
1 2 3 4 |
wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz tar -xzvf LuaJIT-2.0.2.tar.gz cd LuaJIT-2.0.2 make && make install |
注:64位系统安装完成后或许还需要将/usr/local/lib/libluajit-5.1.so.2建立软连接到/usr/lib64/libluajit-5.1.so.2,否则在后面nginx启动时会提示找不到依赖库。
2.redis安装过程
1 2 3 4 |
$ wget http://download.redis.io/releases/redis-3.0.3.tar.gz $ tar xzf redis-3.0.3.tar.gz $ cd redis-3.0.3 $ make |
3. nginx1.4.4的安装
1 2 3 4 5 6 7 8 9 10 11 |
wget https://codeload.github.com/chaoslawful/lua-nginx-module/tar.gz/v0.8.3
wget https://codeload.github.com/agentzh/redis2-nginx-module/tar.gz/v0.10
tar -xzvf lua-nginx-module-0.8.3.tar.gz tar -xzvf redis2-nginx-module-0.10.tar.gz
wget http://nginx.org/download/nginx-1.4.4.tar.gz
./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_sub_module --with-http_gzip_static_module --with-http_stub_status_module --with-pcre --with-http_realip_module --with-http_gzip_static_module --add-module=redis2-nginx-module-0.10 --add-module=lua-nginx-module-0.8.3 && make && make install |
4. 下载nginx中lua使用redis需要的依赖包redis.lua到nginx安装目录
https://codeload.github.com/agentzh/lua-resty-redis/tar.gz/v0.15
5. 修改nginx.conf文件
test.lua内容如下:
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 |
$ cat /usr/local/nginx/test.lua
local redis = require "resty.redis" local red = redis:new()
red:set_timeout(1000) -- 1 sec
-- or connect to a unix domain socket file listened -- by a redis server: -- local ok, err = red:connect("unix:/path/to/redis.sock")
local ok, err = red:connect("127.0.0.1", 6379) if not ok then ngx.say("failed to connect: ", err) return end
ok, err = red:set("dog", "an aniaml") if not ok then ngx.say("failed to set dog: ", err) return end
ngx.say("set result: ", ok)
local res, err = red:get("dog") if not res then ngx.say("failed to get dog: ", err) return end
if res == ngx.null then ngx.say("dog not found.") return end
ngx.say("dog: ", res)
red:init_pipeline() red:set("cat", "Marry") red:set("horse", "Bob") red:get("cat") red:get("horse") local results, err = red:commit_pipeline() if not results then ngx.say("failed to commit the pipelined requests: ", err) return end
for i, res in ipairs(results) do if type(res) == "table" then if not res[1] then ngx.say("failed to run command ", i, ": ", res[2]) else -- process the table value end else -- process the scalar value end end
-- put it into the connection pool of size 100, -- with 0 idle timeout local ok, err = red:set_keepalive(0, 100) if not ok then ngx.say("failed to set keepalive: ", err) return end
-- or just close the connection right away: -- local ok, err = red:close() -- if not ok then -- ngx.say("failed to close: ", err) -- return -- end |
6. ip限制access.lua
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 |
$ cat /usr/local/nginx/access.lua ip_bind_time = 600 --封禁IP时间 ip_time_out = 30 --指定ip访问频率时间段 connect_count = 50 --指定ip访问频率计数最大值
--连接redis local redis = require "resty.redis" local red = redis:new() local ok, err = red:connect("127.0.0.1", 6379) red:set_timeout(1000) -- 1 sec
--如果连接失败,跳转到脚本结尾 if not ok then goto A end
-- --查询ip是否在封禁段内,若在则返回403错误代码 --因封禁时间会大于ip记录时间,故此处不对ip时间key和计数key做处理 is_bind, err = red:get("bind:"..ngx.var.remote_addr) if is_bind == '1' then ngx.exit(403) goto A end
--如果ip记录时间大于指定时间间隔或者记录时间或者不存在ip时间key则重置时间key和计数key --如果ip时间key小于时间间隔,则ip计数+1,且如果ip计数大于ip频率计数,则设置ip的封禁key为1 --同时设置封禁key的过期时间为封禁ip的时间 start_time, err = red:get("time:"..ngx.var.remote_addr) ip_count, err = red:get("count:"..ngx.var.remote_addr)
if start_time == ngx.null or os.time() - start_time > ip_time_out then res, err = red:set("time:"..ngx.var.remote_addr , os.time()) res, err = red:set("count:"..ngx.var.remote_addr , 1) else ip_count = ip_count + 1 res, err = red:incr("count:"..ngx.var.remote_addr) if ip_count >= connect_count then res, err = red:set("bind:"..ngx.var.remote_addr, 1) res, err = red:expire("bind:"..ngx.var.remote_addr, ip_bind_time) end end
-- 结束标记 ::A:: local ok, err = red:close() |
7.新的nginx.conf配置如下:
1 2 3 4 5 6 |
location ~ \.php$ { access_by_lua_file /usr/local/nginx/access.lua;
include fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } |
8.访问记录,在redis内的截图:
9.访问次数过多,返回结果:
原文 地址:
https://www.superman2014.com/2015/08/30/nginxluaredis-%E9%99%90%E5%88%B6ip%E7%9A%84%E8%AE%BF%E9%97%AE%E6%AC%A1%E6%95%B0/