Nginx基础 - Nginx+Lua实现灰度发布与WAF
Posted https://www.cnblogs.com/wang-h
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx基础 - Nginx+Lua实现灰度发布与WAF相关的知识,希望对你有一定的参考价值。
1.nginx加载Lua环境
默认情况下Nginx不支持Lua模块, 需要安装LuaJIT解释器, 并且需要重新编译Nginx, 建议使用openrestry
1)环境准备
[root@localhost ~]# yum -y install gcc gcc-c++ make pcre-devel zlib-devel openssl-devel
2)下载luajit和ngx_devel_kit以及lua-nginx-module
[root@localhost ~]# cd /usr/local/src [root@localhost src]# wget http://luajit.org/download/LuaJIT-2.0.4.tar.gz [root@localhost src]# wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz [root@localhost src]# wget https://github.com/openresty/lua-nginx-module/archive/v0.10.13.tar.gz
3)解压ngx_devel_kit和lua-nginx-module
[root@localhost src]# tar xf v0.2.19.tar.gz [root@localhost src]# tar xf v0.10.13.tar.gz
4)安装LuaJIT Luajit是Lua即时编译器。
[root@localhost src]# tar zxvf LuaJIT-2.0.3.tar.gz [root@localhost src]# cd LuaJIT-2.0.3 [root@localhost LuaJIT-2.0.3]# make && make install
5)安装Nginx并加载模块
[root@localhost ~]# cd /usr/local/src [root@localhost src]# wget http://nginx.org/download/nginx-1.12.2.tar.gz [root@localhost src]# tar xf nginx-1.12.2.tar.gz [root@localhost src]# cd nginx-1.12.2 [root@localhost nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_dav_module --add-module=../ngx_devel_kit-0.2.19/ --add-module=../lua-nginx-module-0.10.13 [root@localhost nginx-1.12.2]# make -j2 && make install #建立软链接, 不建立会出现share object错误 [root@localhost ~]#ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2 #加载lua库,加入到ld.so.conf文件 [root@localhost ~]# echo "/usr/local/LuaJIT/lib" >> /etc/ld.so.conf [root@localhost ~]# ldconfig
2.Nginx调用Lua指令
Nginx调用Lua模块指令, Nginx的可插拔模块加载执行, 共11个处理阶段
语法 set_by_lua set_by_lua_file 设置Nginx变量,可以实现负载的赋值逻辑 access_by_lua access_by_lua_file 请求访问阶段处理, 用于访问控制 content_by_lua content_by_lua_file 内容处理器, 接受请求处理并输出响应
Nginx调用Lua API
变量 ngx.var nginx变量 ngx.req.get_headers 获取请求头 ngx.req.get_uri_args 获取url请求参数 ngx.redirect 重定向 ngx.print 输出响应内容体 ngx.say 输出响应内容体,最后输出一个换行符 ngx.header 输出响应头
3.Nginx+Lua实现代码灰度发布
使用Nginx结合lua实现代码灰度发布
按照一定的关系区别,分不分的代码进行上线,使代码的发布能平滑过渡上线
1.用户的信息cookie等信息区别
2.根据用户的ip地址, 颗粒度更广
执行过程: 1.用户请求到达前端代理Nginx, 内嵌的lua模块会解析Nginx配置文件中Lua脚本 2.Lua脚本会获取客户端IP地址,查看Memcached缓存中是否存在该键值 3.如果存在则执行@java_test,否则执行@java_prod 4.如果是@java_test, 那么location会将请求转发至新版代码的集群组 5.如果是@java_prod, 那么location会将请求转发至原始版代码集群组 6.最后整个过程执行后结束
实践环境准备:
系统 服务 地址 CentOS7 Nginx+Lua+Memached 10.0.0.11 CentOS7 Tomcat集群8080_Prod 10.0.0.12 CentOS7 Tomcat集群9090_Test 10.0.0.13
1)安装两台服务器Tomcat,分别启动8080和9090端口
[root@tomcat-node1 ~]# yum install java -y [root@tomcat-node1 ~]# cd /usr/local/src [root@tomcat-node1 src]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.36/bin/apache-tomcat-9.0.36.tar.gz [root@tomcat-node1 src]# tar xf apache-tomcat-9.0.36.tar.gz [root@tomcat-node1 src]# cp -r apache-tomcat-9.0.36 /usr/local/tomcat-8080 [root@tomcat-node1 src]# /usr/local/tomcat-8080/bin/startup.sh #tomcat默认监听在8080端口, 如果需要启动9090端口需要修改server.xml配置文件
2)配置Memcached并让其支持Lua调用
#安装memcached服务 [root@localhost ~]# yum install memcached -y #配置memcached支持lua [root@localhost ~]# cd /usr/local/src [root@localhost src]# wget https://github.com/openresty/lua-resty-memcached/archive/lua-resty-memcached-master.zip [root@localhost src]# tar xf v0.11.tar.gz
[root@localhost src]# cp -r lua-resty-memcached-0.11/lib/resty/memcached.lua /usr/local/nginx/lua/ #启动memcached [root@localhost ~]# systemctl start memcached [root@localhost ~]# systemctl enable memcached
3)配置负载均衡调度
#必须在http层 lua_package_path "/usr/local/nginx/lua/memcached.lua"; upstream java_prod { server 10.0.0.12:8080; } upstream java_test { server 10.0.0.13:9090; } server { listen 80; server_name 10.0.0.11; location /hello { default_type ‘text/plain‘; content_by_lua ‘ngx.say("hello ,lua scripts")‘; } location /myip { default_type ‘text/plain‘; content_by_lua ‘ clientIP = ngx.req.get_headers()["x_forwarded_for"] ngx.say("Forwarded_IP:",clientIP) if clientIP == nli then clientIP = ngx.var.remote_addr ngx.say("Remote_IP:",clientIP) end ‘; } location / { default_type ‘text/plain‘; content_by_lua_file /usr/local/nginx/lua/dep.lua; } location @java_prod { proxy_pass http://java_prod; include proxy_params; } location @java_test { proxy_pass http://java_test; include proxy_params; } } #nginx反向代理tomcat,必须配置头部信息否则返回400错误 proxy_redirect default; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 32k; proxy_buffering on; proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 256k;
4)编写Nginx调用灰度发布Lua脚本
[root@localhost ~]# vim /usr/local/nginx/lua/dep.lua --获取x-real-ip clientIP = ngx.req.get_headers()["X-Real-IP"] --如果IP为空-取x_forwarded_for if clientIP == nil then clientIP = ngx.req.get_headers()["x_forwarded_for"] end --如果IP为空-取remote_addr if clientIP == nil then clientIP = ngx.var.remote_addr end --定义本地,加载memcached local memcached = require "resty.memcached" --实例化对象 local memc, err = memcached:new() --判断连接是否存在错误 if not memc then ngx.say("failed to instantiate memc: ", err) return end --建立memcache连接 local ok, err = memc:connect("127.0.0.1", 11211) --无法连接往前端抛出错误信息 if not ok then ngx.say("failed to connect: ", err) return end --获取对象中的ip-存在值赋给res local res, flags, err = memc:get(clientIP) -- --ngx.say("value key: ",res,clientIP) if err then ngx.say("failed to get clientIP ", err) return end --如果值为1则调用local-@java_test if res == "1" then ngx.exec("@java_test") return end --否则调用local-@java_prod ngx.exec("@java_prod") return
5)使用Memcache set IP, 测试灰度发布
#telnet传入值 [root@localhost ~]# telnet 127.0.0.1 11211 # set对应IP set 10.0.0.10 0 0 1 # 输入1 1
4.基本安全概述
1)常见的恶意行为
爬虫行为和恶意抓取,资源盗取
防护手段
基础防盗链功能不让恶意用户能够轻易的爬取网站对外数据
access_moudle->对后台,部分用户服务的数据提供IP防护
解决方法
server { listen 80; server_name localhost; set $ip 0; if ($http_x_forward_for ~ 10.0.0.10){ set $ip 1; } if ($remote_addr ~ 10.0.0.10){ set $ip 1; } # 如果$ip值为0,则返回403, 否则允许访问 location /admin { if ($ip = "0"){ return 403; } default_type application/json; return 200 ‘{"status":"success"}‘; }
2)常见的攻击手段(代码植入)
后台密码撞库,通过猜测密码字典不断对后台系统登陆性尝试,获取后台登陆密码
防护手段
1.后台登陆密码复杂度
2.使用access_module-对后台提供IP防控
3.预警机制
文件上传漏洞,利用上传接口将恶意代码植入到服务器中,再通过url去访问执行代码
执行方式admin.com/1.jpg/1.php
解决办法
location ^~ /upload { root /usr/local/openresty/nginx/html/upload; if ($request_filename ~* (.*).php){ return 403; } }
3)常见的攻击手段(SQL注入)
利用未过滤/未审核的用户输入进行Sql注入的攻击方法, 让应用运行本不应该运行的SQL代码
防护手段
1.php配置开启安全相关限制
2.开发人员对sql提交进行审核,屏蔽常见的注入手段
3.Nginx+Lua构建WAF应用层防火墙, 防止Sql注入
以上是关于Nginx基础 - Nginx+Lua实现灰度发布与WAF的主要内容,如果未能解决你的问题,请参考以下文章