OpenResty部署WAF防火墙及灰度发布

一、部署环境

系统

IP 地址

主机名

软件

CentOS 7.9

192.168.15.201

cen01

openresty-1.21.4.3

CentOS 7.9

192.168.15.202

cen02

开机即可

二、安装 OpenResty

1. 安装依赖及工具

[root@cen01 ~]# yum -y install readline-devel pcre-devel openssl-devel gcc make git

2. 编译安装 OpenResty

[root@cen01 ~]# wget https://openresty.org/download/openresty-1.21.4.3.tar.gz
[root@cen01 ~]# tar -xf openresty-1.21.4.3.tar.gz -C /usr/local/src/
[root@cen01 ~]# cd /usr/local/src/openresty-1.21.4.3
[root@cen01 openresty-1.21.4.3]# ./configure && make && make install		# 预配置及编译安装
[root@cen01 openresty-1.21.4.3]# cd /usr/local/openresty
[root@cen01 openresty]# cd nginx/sbin
[root@cen01 sbin]# ./nginx

3. 测试访问页面

地址:本机 IP+80 端口

三、WAF 防火墙模块

1. 安装 WAF

[root@cen01 sbin]# cd
[root@cen01 ~]# git clone https://github.com/unixhot/waf.git
正克隆到 'waf'...
remote: Enumerating objects: 103, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 103 (delta 3), reused 9 (delta 2), pack-reused 89
接收对象中: 100% (103/103), 30.07 KiB | 0 bytes/s, done.
处理 delta 中: 100% (36/36), done.
[root@cen01 ~]# cp -r ./waf/waf/ /usr/local/openresty/nginx/conf/

2. 引入 WAF 模块

[root@cen01 ~]# vim /usr/local/openresty/nginx/conf/nginx.conf
 25     #access_log  logs/access.log  main;
 26     lua_shared_dict limit 50m;		# 插入26~29行至nginx配置文件
 27     lua_package_path "/usr/local/openresty/nginx/conf/waf/?.lua";
 28     init_by_lua_file "/usr/local/openresty/nginx/conf/waf/init.lua";
 29     access_by_lua_file "/usr/local/openresty/nginx/conf/waf/access.lua";
 30     sendfile        on;
[root@cen01 ~]# ln -s /usr/local/openresty/lualib/resty/ /usr/local/openresty/nginx/conf/waf/resty
[root@cen01 ~]# /usr/local/openresty/nginx/sbin/nginx -t		# 检查nginx配置文件
nginx: the configuration file /usr/local/openresty/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/openresty/nginx/conf/nginx.conf test is successful
[root@cen01 ~]# /usr/local/openresty/nginx/sbin/nginx -s stop
[root@cen01 ~]# /usr/local/openresty/nginx/sbin/nginx
[root@cen01 ~]# netstat -anpt | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      63183/nginx: master 

3. 访问测试

本地 IP/.sql

 

四、结合 redis 实现灰度发布

1. Redis 配置

安装 redis 略

[root@cen01 ~]# vim /usr/local/redis/redis.conf
  87 bind 0.0.0.0
 111 protected-mode no
 138 port 6379
 309 daemonize yes
 341 pidfile "redis.pid"
 354 logfile "redis.log"
 504 dir /usr/local/redis
1036 requirepass 123456
[root@cen01 ~]# /usr/local/redis/redis-cli
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set 192.168.15.201 192.168.15.201		# 将本机IP添加到redis数据库缓存内,使得本机IP为接受灰度发布的用户
OK
127.0.0.1:6379> exit

2. Nginx 配置

[root@cen01 ~]# vim /usr/local/openresty/nginx/conf/nginx.conf
....
 17 http {
 18     include       mime.types;
 19     default_type  application/octet-stream;
 20 
 21     #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 22     #                  '$status $body_bytes_sent "$http_referer" '
 23     #                  '"$http_user_agent" "$http_x_forwarded_for"';
 24 
 25     #access_log  logs/access.log  main;
 26     #lua_shared_dict limit 50m;
 27     lua_package_path "/usr/local/openresty/lualib/?.lua;;";			# 修改或添加此行,加载lualib库的lua脚本
 28     lua_package_cpath "/usr/local/openresty/lualib/?.so;;";			# 修改或添加此行,加载so脚本
 29     #init_by_lua_file "/usr/local/openresty/nginx/conf/waf/init.lua";
 30     #access_by_lua_file "/usr/local/openresty/nginx/conf/waf/access.lua";
 31     sendfile        on;
 32     #tcp_nopush     on;
 33 
 34     #keepalive_timeout  0;
 35     keepalive_timeout  65;
 36     charset utf-8;
 37 
 38     #gzip  on;
 39     upstream prod1 {		# 设置七层负载均衡服务器组,组名prod1
 40         server 192.168.15.201:5001;
 41     }
 42 
 43     upstream prod2 {		# 服务器组,组名prod2
 44         server 192.168.15.201:5000;
 45     }
 46 
 47     server {
 48         listen       80;
 49         server_name  localhost;
 50 
 51 
 52         #access_log  logs/host.access.log  main;
 53 
 54         location / {
 55                 content_by_lua_file /usr/local/openresty/nginx/lua/gray.lua;		# 为每一个请求执行gray.lua脚本
 56         }
 57 
 58         location @prod1 {		# @表示分隔符,类似“/”,但该location不可被外部客户端访问,可以用“/”,但生产环境使用灰度发布还是得用@
 59                 proxy_pass http://prod1;		# 反向代理,代理到服务器组prod1
 60         }
 61 
 62         location @prod2 {
 63                 proxy_pass http://prod2;		# 反向代理,和上面location一个意思
 64         }
....省略部分内容.....
100     server {		# 因为本次实验没有apache或tomcat等后端主机,所以为了方便演示,这里加一个server虚拟主机,有#号需要取消掉
101         listen       5001;		# 该虚拟server的监听端口
102     #    listen       somename:8080;
103     #    server_name  somename  alias  another.alias;
104 
105         location / {		# #号取消掉,添加该server的跳转location
106             root   html;		# #号取消
107             index  testa.html;		# #号取消,修改该行
108         }		# 取消注释
109     }		# 取消注释
110 
111     server {		# 和上面的server操作方式一样,下面有#号注释的都要取消
112         listen       5000;
113         location / {
114             root    html;
115             index   testb.html;		# 修改改行
116         }		# 取消注释
117     }		# 取消注释
......省略部分内容......
:wq  # 保存退出
[root@cen01 ~]# kill $(cat /usr/local/openresty/nginx/logs/nginx.pid)		# 停掉nginx,如果nginx未启动会报没有那个目录或文件,此时不用管,说明nginx已停止了

3. Lua 灰度发布脚本

[root@cen01 ~]# vim /usr/local/openresty/nginx/lua/gray.lua
local redis = require "resty.redis" -- 引入 resty.redis 模块
local cache = redis.new() -- 创建一个新的 redis 实例
cache:set_timeout(60000) -- 设置超时时间为 60000 毫秒

local ok, err = cache.connect(cache, '127.0.0.1', 6379)  -- 连接到本地的 Redis 服务器
if not ok then
  ngx.say("failed to connect:", err) -- 如果连接失败,打印错误信息并返回
  return
end

local red, err = cache:auth("123456") -- 进行身份验证

if not red then
  ngx.say("failed to authenticate: ", err) -- 如果身份验证失败,打印错误信息并返回
  return
end

local local_ip = ngx.req.get_headers()["X-Real-IP"] -- 获取客户端真实 IP 地址
if local_ip == nil then
  local_ip = ngx.req.get_headers()["x_forwarded_for"] -- 如果 X-Real-IP 不存在,尝试获取 x_forwarded_for 的 IP 地址
end

if local_ip == nil then
  local_ip = ngx.var.remote_addr -- 如果 x_forwarded_for 也不存在,获取远程地址
end


local intercept = cache:get(local_ip)  -- 从缓存中获取 IP 地址

if intercept == local_ip then
  ngx.exec("@prod1") -- 如果缓存中包含该 IP 地址,重定向到 "@prod1"
  return
end

ngx.exec("@prod2") -- 如果缓存中不包含该 IP 地址,重定向到 "@prod2"

local ok, err = cache:close()  -- 关闭与 redis 的连接

if not ok then
  ngx.say("failed to close:", err) -- 如果关闭连接失败,打印错误信息并返回
  return
end

4. 配置 HTML 页面

 

[root@cen01 ~]# vim /usr/local/openresty/nginx/html/testa.html 
gray release app(test)		# 这个是灰度发布演示页面
[root@cen01 ~]# vim /usr/local/openresty/nginx/html/testb.html 
Real production environment(hello world)		# 真实生产环境已发布的页面

5. 启动 Nginx

[root@cen01 ~]# /usr/local/openresty/nginx/sbin/nginx 
[root@cen01 ~]# netstat -anpt | grep nginx
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN      72192/nginx: master 
tcp        0      0 0.0.0.0:5001            0.0.0.0:*               LISTEN      72192/nginx: master 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      72192/nginx: master

6. 访问测试

6.1. 灰度测试用户访问

# 之前在redis内已配置了本机为接收灰度发布的用户,所以先用本机IP进行测试
[root@cen01 ~]# curl 192.168.15.201		# 接收到灰度发布的页面,所以本机IP属于测试用户
gray release app(test)

6.2. 非灰度测试用户访问

6.2.1. Windows 客户端访问

使用 Windows 浏览器访问时,服务端接收到的客户端 IP 为 192.168.15.1,但该 IP 并未在数据库内,所以不在测试用户范围内。

回到 cen01 的终端,登录 redis,将 192.168.15.1 加入到数据库键值对内,就可以访问到灰度发布的测试页面了

[root@cen01 ~]# /usr/local/redis/redis-cli 
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set 192.168.15.1 192.168.15.1
OK

回到浏览器,刷新

6.2.2. Linux 客户端访问

使用另一台虚拟机 cen02 (192.168.15.202)对 cen01 进行访问

[root@cen02 ~]# curl 192.168.15.201
Real production environment(hello world)		# 访问到了生产环境,确定cen02非灰度测试用户

回到 cen01,将 cen02 的 IP 加入到灰度测试用户

[root@cen01 ~]# /usr/local/redis/redis-cli 
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> set 192.168.15.202 192.168.15.202
OK

再回到 cen02,访问 cen01

[root@cen02 ~]# curl 192.168.15.201
gray release app(test)
# cen02可以访问灰度发布页面,成为灰度测试用户

 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值