openresty+lua在反向代理服务中的玩法

在这里插入图片描述
0x01 起因
几天前学弟给我介绍他用nginx搭建的反代,代理了谷歌和维基百科。

由此我想到了一些邪恶的东西:反代既然是所有流量走我的服务器,那我是不是能够在中途做些手脚,达到一些有趣的目的。 openresty是一款结合了nginx和lua的全功能web服务器,我感觉其角色和tornado类似,既是一个中间件,也结合了一个后端解释器。所以,我们可以在nginx上用lua开发很多“有趣”的东西。

所以,这篇文章也是由此而来。

0x02 openresty的搭建
openresty是国人的一个开源项目,主页在http://openresty.org/ ,其核心nginx版本相对比较高(1.7.10),搭配的一些第三方模块也很丰富。

首先在官网下载openresty源码,然后我还需要一个openresty中没有的第三方库:https://github.com/yaoweibin/ngx_http_substitutions_filter_module ,同样下载下来。

编译:

./configure --with-http_sub_module --with-pcre-jit --with-ipv6 --add-module=/root/requirements/ngx_http_substitutions_filter_module
make && make install

编译选项中: —with-http_sub_module 附带http_sub_module模块,这是nginx自带的一个模块,用来替换返回的http数据包中内容。 –with-pcre-jit —with-ipv6 提供ipv6支持 —add-module=/root/requirements/ngx_http_substitutions_filter_module(此处为你下载的ngx_http_substitutions_filter_module目录) 将刚才下载的http_substitutions_filter_module模块编译进去。http_substitutions_filter_module模块是http_sub_module的加强版,它可以用正则替换,并可以多处替换。

编译安装的过程没有什么难点,很快就安装好了,openresty和luajit都默认在/usr/local/openresty目录下。nginx的二进制文件为 /usr/local/openresty/nginx/sbin/nginx。

然后像正常启动nginx一样启动之。

0x03 反代目标网站
根据目标网站的不同,反代也是有难度之分的。

比如乌云,我们可以很轻松地将其反代下来。因为乌云主站有一个特点:所有链接都是相对地址。所以我甚至不需要修改页面中任何内容即可完整反代。

一个简单demo:http://wooyun.jjfly.party ,其配置文件如下:

在这里插入图片描述
其中,location / 块即为反代乌云的配置块。

proxy_pass 是将请求交给上游处理,而这里的上游就是http://wooyun.com

proxy_cookie_domain是将所有cookie中的domain替换掉成自己的domain,达到能够登陆的效果。

proxy_buffering off用来关闭内存缓冲区。

proxy_set_header是一个重要的配置项,利用这个项可以修改转发时的HTTP头。比如,乌云在登录以后,修改资料的时候会验证referer,如果referer来自wooyun.jjfly.party是会提示错误的。所以我在这里用proxy_set_header将referer设置为wooyun.org域下的地址,从而绕过检查。

这样,做好了一个完美的“钓鱼网站”:
在这里插入图片描述
我甚至可以正常登录、修改信息:
在这里插入图片描述
但是并不是所有网站做反代都这样简单,比如google。谷歌是一个https的站点,所以通常也需要一个https的配置:
在这里插入图片描述
我申请了一个SSL证书,反代方法和乌云类似。但不同的是,谷歌会检查host,如果host不是谷歌自己的域名就会强制302跳转到www.google.com

### 在UOS系统中使用OpenRestyLua实现灰度发布并集成达梦数据库的方案 #### 1. 环境准备 在开始实现灰度发布之前,需要确保以下环境已正确配置: - **UOS系统**:安装并配置好统信UOS操作系统[^2]。 - **OpenResty**:安装并配置OpenResty作为Web服务器。可以通过以下命令安装: ```bash sudo apt update sudo apt install -y openresty ``` - **Lua模块**:OpenResty内置Lua支持,无需额外安装。 - **达梦数据库**:按照引用中的步骤完成达梦数据库的安装与初始化[^1]。 #### 2. 配置达梦数据库连接 在OpenResty中使用Lua连接达梦数据库,可以借助 `lua-resty-mysql` 或自定义 Lua 模块来实现。由于达梦数据库兼容 MySQL 协议,因此可以直接复用 MySQL 连接库。 以下是配置示例代码: ```lua local mysql = require "resty.mysql" local db, err = mysql:new() if not db then ngx.say("failed to instantiate mysql: ", err) return end db:set_timeout(1000) -- 1 second local ok, err, errno, sqlstate = db:connect{ host = "127.0.0.1", port = 5236, -- 达梦数据库默认端口 database = "test_db", user = "v8xuser", password = "v8xuser123", max_packet_size = 1024 * 1024 } if not ok then ngx.say("failed to connect: ", err, ": ", errno, " ", sqlstate) return end ngx.say("connected to DM Database!") ``` #### 3. 实现灰度发布逻辑 灰度发布的核心是根据用户特征(如 IP 地址、用户 ID、Cookie 等)决定流量分发比例。以下是基于 Lua 的灰度发布逻辑: ##### 示例代码 ```lua local function is_gray_user(user_id) -- 假设灰度用户为偶数 ID if tonumber(user_id) % 2 == 0 then return true end return false end local function handle_request() local user_id = ngx.var.arg_user_id -- 获取请求参数中的用户 ID if not user_id or user_id == "" then ngx.say("User ID is required") return end if is_gray_user(user_id) then -- 灰度用户访问新功能 ngx.say("Welcome gray user! You are accessing the new feature.") else -- 普通用户访问旧功能 ngx.say("Welcome normal user! You are accessing the old feature.") end end handle_request() ``` #### 4. 集成达梦数据库查询 在灰度发布逻辑中,可以结合达梦数据库进行更复杂的用户特征判断。例如,从数据库中获取用户的灰度标志位。 ##### 查询用户灰度状态示例 ```lua local function get_user_gray_status(user_id) local res, err = db:query("SELECT para_value FROM v_instance WHERE para_name='GRAY_STATUS' AND user_id=" .. user_id) if not res then ngx.say("Failed to query user gray status: ", err) return false end return res[1].para_value == "true" end local function handle_request_with_db() local user_id = ngx.var.arg_user_id if not user_id or user_id == "" then ngx.say("User ID is required") return end local is_gray = get_user_gray_status(user_id) if is_gray then ngx.say("Welcome gray user! You are accessing the new feature.") else ngx.say("Welcome normal user! You are accessing the old feature.") end end handle_request_with_db() ``` #### 5. 错误处理与日志记录 在实际生产环境中,建议对每个请求进行错误捕获,并将关键信息记录到日志中。可以使用 `ngx.log` 函数记录日志: ```lua local function log_error(err_msg) ngx.log(ngx.ERR, "Error occurred: ", err_msg) end local function safe_query(sql) local res, err = db:query(sql) if not res then log_error("Database query failed: " .. err) return nil, err end return res end ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值