openresty(nginx+lua环境)+redis实现waf,禁封ip 实现访问控制。

WAF 应用型防火墙。
基础环境:CentOS 7.5
openresty :1.15.8.2 搭建直接用官网的搭建,yum安装或者源码编译都随便了。 openresty官网
这里是安装信息,如果编译安装可以参考
redis: redis-5.0.4 官网可自己下载。 我这里用的是编译安装。 这里我就直接附加一个大佬的安装博客吧。(主要是懒得写)redis安装博客

如果是yum安装不用考虑这个

**
sh-4.2# openresty -V
nginx version: openresty/1.15.8.2
built by gcc 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
built with OpenSSL 1.1.0k 28 May 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-cc-opt=’-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl/include’ --add-module=…/ngx_devel_kit-0.3.1rc1 --add-module=…/echo-nginx-module-0.61 --add-module=…/xss-nginx-module-0.06 --add-module=…/ngx_coolkit-0.2 --add-module=…/set-misc-nginx-module-0.32 --add-module=…/form-input-nginx-module-0.12 --add-module=…/encrypted-session-nginx-module-0.08 --add-module=…/srcache-nginx-module-0.31 --add-module=…/ngx_lua-0.10.15 --add-module=…/ngx_lua_upstream-0.07 --add-module=…/headers-more-nginx-module-0.33 --add-module=…/array-var-nginx-module-0.05 --add-module=…/memc-nginx-module-0.19 --add-module=…/redis2-nginx-module-0.15 --add-module=…/redis-nginx-module-0.3.7 --add-module=…/ngx_stream_lua-0.0.7 --with-ld-opt=’-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl/lib’ --with-cc=‘ccache gcc -fdiagnostics-color=always’ --with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-dtrace-probes --with-stream --with-stream_ssl_preread_module --with-http_ssl_module
`

安装完毕后,进去openresty的文件夹中。

我这里默认的在/usr/local/openresty/
在这里插入图片描述
创建一个lua的目录 (用来放置lua脚本,后面取脚本的路径会指向这里)

openresty 是带了nginx 和luajit(lua环境的),这里在你的nginx.conf 中配置。

cat /usr/local/openresty/nginx/conf/nginx.conf


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;

            access_by_lua_file /usr/local/openresty/lua/access_limit.lua;   ## 这里是指向 lua脚本 的路径
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

vim /usr/local/openresty/lua/access_limit.lua 这个路径是我的编译安装路径,路径不同的同学自行修改。

写入下面的代码

-- access_by_lua_file '/usr/local/lua_test/access_by_lua';
ngx.req.read_body()
-- 引入redis的包
local redis = require "resty.redis"
-- 实例化
local red = redis.new()
-- 连接redis
red.connect(red, '127.0.0.1', '6379')
-- redis的密码
red:auth("123456")
-- 用户的真实IP
--local myIP = ngx.req.get_headers()["X-Real-IP"]
--if myIP == nil then
--   myIP = ngx.req.get_headers()["x_forwarded_for"]
--end
--if myIP == nil then
   myIP = ngx.var.remote_addr
--end
-- 匹配需要验证的URI
if ngx.re.match(ngx.var.uri,"/index.html") then
    -- 校验IP是否存在黑名单中
    local hasIP = red:sismember('black.ip',myIP)
    -- 在黑名单
    if hasIP==1 then
        -- ngx.say("This is 'Black List' request")
        ngx.exit(ngx.HTTP_FORBIDDEN)
    end
    --如果访问超过10次 就加入IP到黑名单
        local count = red:get(myIP)
        if count == ngx.null then
           count = 0
        end
        if (tonumber(count)>3) then     ##  这里我设定是每秒三个请求用来测试。 正常情况下要远远大于这个数的。 
          red:sadd('black.ip',myIP)
          ngx.exit(ngx.HTTP_FORBIDDEN)
        end
        --每次访问+1
        red:incr(myIP)
end
~

redis 设置好密码后,测试。
测试访问。确保可以正常访问初始页面。
在这里插入图片描述

当多次刷新后。 出现403
在这里插入图片描述

基本思路, 用户访问,——》 nginx处理——》 调用nginx.conf —— 》local 中调用lua脚本文件。 ——》lua链接redis redis记录url的ip,并计数。——》回到conf中,调用index.html返回给用户。

这个流程中几个点要注意, nginx处理server 如果有转发,是否转发到其他地方。
lua脚本的设置,账号密码是否能链接上, 次数是否合理(结合你自己项目的访问情况设置)
redis的计数问题。如果链接上或者拿不到数据,会报错, 说lua脚本 if (tonumber(count)>3) then 这行存在一个空值和数字比较。

如果是docker部署的话,很多坑!!!!!! 血泪史。个人对docker中的内部通讯不是特别了解。

暂时踩过的坑就这些。希望各位提问。

结尾附加一条视频waf的部署视频:
链接:https://pan.baidu.com/s/1vxAauK36I1GVbNi-lGNbWQ
提取码:r1qu
复制这段内容后打开百度网盘手机App,操作更方便哦

其实。我主要是看这个视频写的这个博客。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值