一切源于一篇微信文章
- 早上我上着班,听着歌
- 1.打算使用腾讯云服务器centos-7实验:
- 安装ngx_devel_kit
- mac m1 os 12.7.6 安装openresty
- 测试lua限流: 终于回到初心了!
早上我上着班,听着歌
突然微信推送了一篇文章《Nginx 实现动态封禁IP,详细教程来了》nginx动态封禁ip,然后手抽点进去看了看,然后。。。就打算实践验证一下。。没想到啊,遇到各种问题。。所以记录下。。。
1.打算使用腾讯云服务器centos-7实验:
安装lua-nginx-module
需要先安装LuaJIT,并依赖ngx_devel_kit。
安装LuaJIT
- LuaJIT — a Just-In-Time Compiler for Lua.
https://luajit.org/download.html
下面几个链接我都点进去看了看。。。
https://repo.or.cz/w/luajit-2.0.git
https://github.com/LuaJIT/LuaJIT/tags
https://luajit.org/status.html
所以决定下载2.0版本。
本机下载好后,上传服务器:
jelex@jelexxudeMacBook-Pro Downloads % scp LuaJIT-2.0.ROLLING.tar.gz root@我的tencent服务器ip:/opt
解压后:
安装:
[root@VM-24-5-centos LuaJIT-2.0.ROLLING]# make install PREFIX=/usr/local/LuaJIT
查看:
/etc/profile 文件末尾加入环境变量:
export LUAJIT_LIB=/usr/local/LuaJIT/lib
export LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.0[root@VM-24-5-centos LuaJIT]# source /etc/profile
安装ngx_devel_kit
项目地址:https://github.com/simplresty/ngx_devel_kit
下载并解压,不需要安装:
https://github.com/vision5/ngx_devel_kit/releases/tag/v0.3.3
上传解压:
安装lua-nginx-module
项目地址:https://github.com/openresty/lua-nginx-module
下载并解压,不需要安装:
https://github.com/openresty/lua-nginx-module/tags
编译Nginx
需要安装pcre依赖库(这个服务器可能安装过。。。不管怎样,执行下)
$ yum install readline-devel pcre-devel openssl-devel
所以还需要去下载lua-nginx-module: https://github.com/openresty/lua-nginx-module
查看当前的配置:[root@VM-24-5-centos opt]# /usr/local/nginx/sbin/nginx -V
呃,对,我刚搞音视频,所以有dav, rtmp…
--prefix=/usr/local/nginx --with-http_ssl_module --with-http_dav_module --add-module=../nginx-rtmp-module-1.2.2 --add-module=../nginx-dav-ext-module-master --add-module=../headers-more-nginx-module-0.37
追加参数:
--with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-pcre --with-ld-opt=-Wl,-rpath,/usr/local/LuaJIT/lib --add-module=/opt/ngx_devel_kit-0.3.3 --add-module=/opt/lua-nginx-module-0.10.27
得到完整命令:
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_dav_module --add-module=../nginx-rtmp-module-1.2.2 --add-module=../nginx-dav-ext-module-master --add-module=../headers-more-nginx-module-0.37 --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-pcre --with-ld-opt=-Wl,-rpath,/usr/local/LuaJIT/lib --add-module=/opt/ngx_devel_kit-0.3.3 --add-module=/opt/lua-nginx-module-0.10.27
执行:
[root@VM-24-5-centos opt]# cd nginx-1.26.0/
[root@VM-24-5-centos nginx-1.26.0]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_dav_module --add-module=../nginx-rtmp-module-1.2.2 --add-module=../nginx-dav-ext-module-master --add-module=../headers-more-nginx-module-0.37 --with-ld-opt=-Wl,-rpath,/usr/local/LuaJIT/lib --add-module=/opt/ngx_devel_kit-0.3.3 --add-module=/opt/lua-nginx-module-0.10.27
[root@VM-24-5-centos nginx-1.26.0]# make -j2
报错:/opt/lua-nginx-module-0.10.27/src/ngx_http_lua_ssl_certby.c: In function ‘ngx_http_lua_ffi_ssl_client_random’:
/opt/lua-nginx-module-0.10.27/src/ngx_http_lua_ssl_certby.c:1651:5: error: implicit declaration of function ‘SSL_get_client_random’ [-Werror=implicit-function-declaration]
然后到这步了,提示我:
It is highly recommended to use OpenResty releases which bundle Nginx, ngx_lua (this module), LuaJIT, as well as other powerful companion Nginx modules and Lua libraries.
It is discouraged to build this module with Nginx yourself since it is tricky to set up exactly right.
https://github.com/openresty/lua-nginx-module
而我的nginx正好是1.26版本,不兼容??!!??
白忙了。。。
所以linux到此为止。。。下面研究本机mac安装openresty:
mac m1 os 12.7.6 安装openresty
https://openresty.org/cn/download.html
先更新brew:
brew update
brew install pcre openssl
安装:
jelex@jelexxudeMacBook-Pro ~ % brew install openresty/brew/openresty
解决:https://site.ip138.com/raw.githubusercontent.com/
加入:
jelex@bogon ~ % cat /etc/hosts
185.199.111.133 raw.githubusercontent.com
重新执行:jelex@jelexxudeMacBook-Pro ~ % brew install openresty/brew/openresty
。。。 。。。
what the f**, 你们看看,大佬们,你们看看,它们多嚣张,我试着翻译第一段:
我们(和苹果公司)不会提供macOS 12这个老版本的支持。
一些formulae在这个老版本上构建失效是意料之中的结果。
在这个版本上Homebrew注定会有问题并且很慢.
关于这些问题,不要在Homebrew上的github上提任何issue。
即使你认为这些消息提示没有关联,也不要提任何issue.
全体打开的issue会被立刻关闭(不会有回答)。
不要在社交媒体向Homebrew或它的维护者请求帮助。
你可以从Homebrew的讨论中请求帮助,但是不太可能会有人回复你。
尝试自己解决这问题,提交一个fix…
我们会预览,但是可能会/也可能不会 接受你的pull request…
另外,我的xcode是13.2版本,也过期了。。。
command line 工具也。。。
然后我又去下载新的xcode 14.0 : 兼容12.5.。。7个G大小。。。
稀里糊涂下载了后,又没来及用,。。。
因为我打算使用源码安装试试:
下载一个老的版本:看着1.19.9.1 比较顺眼:
jelex@bogon openresty-1.19.9.1 % pwd
/Users/jelex/Documents/work/openresty-1.19.9.1jelex@bogon openresty-1.19.9.1 % ./configure --with-cc-opt="-I/usr/local/openssl/include/ -I/usr/local/include/pcre/include/" --with-ld-opt="-L/usr/local/openssl/lib/ -L/usr/local/include/pcre/lib/" -j8
下载openssl:https://openssl-library.org/source/
jelex@bogon openssl-3.3.2 % pwd
/Users/jelex/Documents/work/openssl-3.3.2
jelex@bogon openssl-3.3.2 % sudo ./config --prefix=/usr/local/openssl
sudo make
sudo make installjelex@bogon openssl-3.3.2 % openssl versionOpenSSL 3.3.2 3 Sep 2024 (Library: OpenSSL 3.3.2 3 Sep 2024)
jelex@bogon openssl-3.3.2 %
再次:
jelex@bogon openresty-1.19.9.1 % pwd
/Users/jelex/Documents/work/openresty-1.19.9.1./configure --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-cc-opt="-I/usr/local/openssl/include/ -I/usr/local/include/pcre/include/" --with-luajit --without-http_redis2_module --with-ld-opt="-L/usr/local/openssl/lib/ -L/usr/local/include/pcre/lib/" --with-openssl=/Users/jelex/Documents/work/openssl-3.3.2 --with-pcre -j8
运行结果:
sudo make
sudo make install
jelex@bogon bin % pwd
/usr/local/openresty/binjelex@bogon bin % ./openresty -V
jelex@bogon nginx % pwd
/usr/local/openresty/nginxjelex@bogon nginx % cat conf/nginx.conf
location /hello {default_type 'text/plain';return 200 'hello echo!';}location /hello_lua {default_type 'text/plain';content_by_lua 'ngx.say("hello, lua!")';}
启动 & 测试:
jelex@bogon nginx % curl http://127.0.0.1/hello
hello echo!%
jelex@bogon nginx % curl http://127.0.0.1/hello_lua
hello, lua!
jelex@bogon nginx %
测试lua限流: 终于回到初心了!
重启nginx:
jelex@bogon nginx % pwd
/usr/local/openresty/nginxjelex@bogon nginx % sudo ./sbin/nginx -s stop
jelex@bogon nginx % sudo ./sbin/nginxjelex@bogon nginx % tail -200f logs/error.log
修改access_limit.lua权限:还是不行,那就移动位置
再修改nginx.conf配置:
access_by_lua_file access_limit.lua;
重启nginx:
jelex@bogon nginx % sudo ./sbin/nginx -s stop
jelex@bogon nginx % sudo ./sbin/nginx
对这个路径无效:
但是对下面这个有用:
连续快速多点几次:
最后借花献佛,附上大佬的lua脚本:
--连接池超时回收毫秒
local pool_max_idle_time = 10000
--连接池大小
local pool_size = 100
--redis 连接超时时间
local redis_connection_timeout = 100
--redis host
local redis_host = "101.43.xx.xxx"
--redis port
local redis_port = "6379"
--redis auth
local redis_auth = "差点用了真密码~";
--封禁IP时间(秒)
local ip_block_time= 120
--指定ip访问频率时间段(秒)
local ip_time_out = 1
--指定ip访问频率计数最大值(次)
local ip_max_count = 3-- 错误日志记录
local function errlog(msg, ex)ngx.log(ngx.ERR, msg, ex)
end-- 释放连接池
local function close_redis(red)if not red thenreturnendlocal ok, err = red:set_keepalive(pool_max_idle_time, pool_size)if not ok thenngx.say("redis connct err:",err)return red:close()end
end--连接redis
local redis = require "resty.redis"
local client = redis:new()
local ok, err = client:connect(redis_host, redis_port)
-- 连接失败返回服务器错误
if not ok thenclose_redis(client)ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
--设置超时时间
client:set_timeout(redis_connection_timeout)-- 优化验证密码操作 代表连接在连接池使用的次数,如果为0代表未使用,不为0代表复用 在只有为0时才进行密码校验
local connCount, err = client:get_reused_times()
-- 新建连接,需要认证密码
if 0 == connCount thenlocal ok, err = client:auth(redis_auth)if not ok thenerrlog("failed to auth: ", err)returnend--从连接池中获取连接,无需再次认证密码
elseif err thenerrlog("failed to get reused times: ", err)return
end-- 获取请求ip
local function getIp()local clientIP = ngx.req.get_headers()["X-Real-IP"]if clientIP == nil thenclientIP = ngx.req.get_headers()["x_forwarded_for"]endif clientIP == nil thenclientIP = ngx.var.remote_addrendreturn clientIP
endlocal cliendIp = getIp();local incrKey = "lim:cnt:"..cliendIp
local blockKey = "lim:blk:"..cliendIp--查询ip是否被禁止访问,如果存在则返回403错误代码
local is_block,err = client:get(blockKey)
if tonumber(is_block) == 1 thenngx.exit(ngx.HTTP_FORBIDDEN)close_redis(client)
endlocal ip_count, err = client:incr(incrKey)
if tonumber(ip_count) == 1 thenclient:expire(incrKey,ip_time_out)
end
--如果超过单位时间限制的访问次数,则添加限制访问标识,限制时间为ip_block_time
if tonumber(ip_count) > tonumber(ip_max_count) thenclient:set(blockKey,1)client:expire(blockKey,ip_block_time)
endclose_redis(client)
下面是引用链接:
[1]: https://www.cnblogs.com/52fhy/p/10164553.html
[2]: https://mp.weixin.qq.com/s/klh3Ho-UJ-p1LJWCLMHckg
[3]: https://site.ip138.com/raw.githubusercontent.com/
[4]: http://adrai.github.io/flowchart.js/