openresty 动态黑白名单
动态黑白名单
客户端请求发送到openresty,openresty需要验证黑白名单;
可将黑白名单存放在redis中,openresty直接与redis交互,验证黑白名单;
openresty也可将黑白名单加载到共享内存,在内存中验证黑白名单;
验证通过后,执行后续请求;
验证不通过,向客户端返回403(request forbidden)错误
使用示例
创建redis 容器
docker run -it -d --net fixed --ip 172.18.0.81 --name redis-black redis
default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
location /test {
access_by_lua_block {
local redis = require 'resty.redis';
local red = redis:new();
red:set_timeouts(1000, 1000, 1000);
local ok, err = red:connect("172.18.0.81", 6379);
if not ok then
ngx.log(ngx.ERR, "failed to connect: ", err)
return
end
local remote_addr = ngx.var.remote_addr;
ngx.log(ngx.ERR, "remote_addr ==> ", remote_addr);
ngx.log(ngx.ERR, "red:sismember('balck-list', remote_addr)");
res, err = red:sismember('black-list', remote_addr);
ngx.log(ngx.ERR, "是否在黑名单 ==> ", res);
if res == 1 then
ngx.log(ngx.ERR, "输出 403");
ngx.exit(ngx.HTTP_FORBIDDEN);
else
ngx.log(ngx.ERR, "输出 200");
ngx.exit(ngx.OK);
end
}
echo "test";
content_by_lua_block {
ngx.say("test");
}
}
location /add {
content_by_lua_block {
local redis = require 'resty.redis';
local red = redis:new();
red:set_timeouts(1000, 1000, 1000);
local ok, err = red:connect("172.18.0.81", 6379);
if not ok then
ngx.say("failed to connect: ", err)
return
end
local members = red:smembers("black-list");
if members then
ngx.say("添加前黑名单 ==> ", members);
end
local ip = ngx.var.arg_ip;
ngx.say("red:sadd('balck-list', ip)");
local res, err = red:sadd('black-list', ip);
if not res then
ngx.say("failed to sadd: ", err)
return
end
local members = red:smembers("black-list");
if members then
ngx.say("添加后黑名单 ==> ", members);
end
}
}
location /delete {
content_by_lua_block {
local redis = require 'resty.redis';
local red = redis:new();
red:set_timeouts(1000, 1000, 1000);
local ok, err = red:connect("172.18.0.81", 6379);
if not ok then
ngx.say("failed to connect: ", err)
return
end
local members = red:smembers("black-list");
if members then
ngx.say("删除前黑名单 ==> ", members);
end
local ip = ngx.var.arg_ip;
ngx.say("red:srem('balck-list', ip)");
local res, err = red:srem('black-list', ip);
if not res then
ngx.say("failed to srem: ", err)
return
end
local members = red:smembers("black-list");
if members then
ngx.say("删除后黑名单 ==> ", members);
end
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
}
创建openresty 容器
docker run -it -d --net fixed --ip 172.18.0.82 -p 6001:80 \
-v /Users/huli/lua/openresty/black/default.conf:/etc/nginx/conf.d/default.conf \
--name open-black lihu12344/openresty
使用测试
# 初始黑名单为空
huli@hudeMacBook-Pro black % curl localhost:6001/test
test
# 添加黑名单
huli@hudeMacBook-Pro black % curl --location --request GET 'localhost:6001/add?ip=172.18.0.1'
添加前黑名单 ==> gtlx
red:sadd('balck-list', ip)
添加后黑名单 ==> 172.18.0.1gtlx
huli@hudeMacBook-Pro black % curl localhost:6001/test
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>openresty/1.21.4.1</center>
</body>
</html>
# 删除黑名单
huli@hudeMacBook-Pro black % curl --location --request GET 'localhost:6001/delete?ip=172.18.0.1'
删除前黑名单 ==> 172.18.0.1gtlx
red:srem('balck-list', ip)
删除后黑名单 ==> gtlx
huli@hudeMacBook-Pro black % curl localhost:6001/test
test