想用Nginx代理一切?行! Nginx能代理一切吗? 我们来看几个示例 怎么做到的 还想更进一步 实现方式 欢迎拍砖

是的,Nginx可以作为一个优秀的http网关,但nginx能代理SSH2,MySQL,Oracle的连接吗?也算行吧,nginx有stream-module,专门处理TCP,UDP连接。不过即使忽略

  • stream-module反人类的使用方式、
  • nginx内部复杂的阶段划分、
  • 各个阶段对使用方式的限制、
  • 以及为了完成某个功能不得不重新编译下载的一系列缺点,

Stream-module的功能也远远不够。不信你可以试试修改一个包的内容,或者自动回复某种类型的包试试,更别提完成这样几个操作:修改一下客户端输入的sql语句,或者更进一步,加入一个身份验证。

如果你是一个nginx+lua或Openresty或KONG或APISix的网关重度依赖用户,那么你肯定急切的希望把网关的能力扩展到TCP/IP领域。

我们来看几个示例

修改Linux|Unix欢迎屏幕为所有男人的梦想

想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖

记录SQL或shell命令

想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖
想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖

防止删库跑路(命令过滤和禁止)

想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖
想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖

踢人下线

想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖

怎么做到的

上面的示例是怎么做到的?不要着急,我们的主人公就要出场了:SuProxy,一个纯Lua,事件驱动模型,基于包分析的开源代理库。

纯LUA意味着拷贝可用,事件驱动意味着使用方便,包分析意味着可以真正自由修改包内容

我们来看看怎么修改linux的欢迎屏幕

local function myWelcome(context,source)
	local digger={"
",
	[[                                                     .-.   ]].."
",
	[[                                                    /     ]].."
",
	[[                                     _____.....-----|(o) | ]].."
",
	[[                               _..--'          _..--|  .'' ]].."
",
	[[                             .'  o      _..--''     |  | | ]].."
",
	[[                            /  _/_..--''            |  | | ]].."
",
	[[                   ________/  / /                   |  | | ]].."
",
	[[                  | _  ____ / /                    |  | | ]].."
",
	[[ _.-----._________|| ||    \ /                     |  | | ]].."
",
	[[|=================||=||_____\                      |__|-' ]].."
",
	[[|   suproxy       ||_||_____//                      (o |  ]].."
",
	[[|_________________|_________/                        |-|  ]].."
",
	[[ `-------------._______.----'                        /  `. ]].."
",
	[[    .,.,.,.,.,.,.,.,.,.,.,.,.,                      /     ]].."
",
	[[   ((O) o o o o ======= o o(O))                 ._.'      /]].."
",
	[[    `-.,.,.,.,.,.,.,.,.,.,.,-'                   `.......' ]].."
",
	[[                   scan me to login                        ]].."
",
	"
",
	}                      
	return table.concat(digger),false
end

local ssh=require("suproxy.ssh2"):new()
local cmd=require("suproxy.ssh2.commandCollector"):new()
cmd.BeforeWelcomeEvent:addHandler(ssh,myWelcome)
local channel=require("suproxy.channel"):new({{ip="127.0.0.1",port=2222}},ssh)
channel:run()

上面的例子里,通过处理commandCollector.BeforeWelcomeEvent事件,在事件中修改了默认的欢迎屏幕。

每个协议都有自己独特的事件,比如利用TNSProcessor.commandEntered事件,我们就能过滤用户输入的命令,使用OnAuthenticate事件就能够自行处理验证。事件的使用可参见https://www.cnblogs.com/yizhu2000/p/13885263.html或英文文档https://github.com/yizhu2000/suproxy

还想更进一步

除了上面这些直观的事件,在底层SuProxy还为高级用户提供了协议解析事件,这些事件把协议内部的包往来暴露出来,用户可以处理这些事件从而修改包的内容,实现更高级的逻辑,比如SSH2协议提供了如下事件(C2P意味着从Client到SuProxy,S2P意味着从SuProxy到Server)

C2PParser.events.KeyXInitEvent,C2PParser.events.AuthReqEvent,C2PParser.events.DHKeyXInitEvent,C2PParser.events.NewKeysEvent,C2PParser.events.ChannelDataEvent,S2PParser.events.KeyXInitEvent,S2PParser.events.DHKeyXReplyEvent,S2PParser.events.AuthSuccessEvent,S2PParser.events.AuthFailEvent,S2PParser.events.NewKeysEvent,S2PParser.events.ChannelDataEvent

熟悉SSH2协议的同学可以自行解析扩展。

实现方式

SuProxy自行处理了request socket的数据,并在上下游间建立通道,在通道中使用不同处理器处理协议相关的内容

Channel 负责管理连接,数据收发

Parser负责进行解析和打包

Processor 负责处理加解密及对解析后的包进行业务处理

其中processor和parser用户都可以自行扩展,增加processor可以扩展协议,增加parser可以扩展协议中某类特定包的解析

三个层次都会发出事件。具体可见下图

想用Nginx代理一切?行!
Nginx能代理一切吗?
我们来看几个示例
怎么做到的
还想更进一步
实现方式
欢迎拍砖

欢迎拍砖

看了上面的介绍,感兴趣的同学有问题可以在此留言,或直接在git上提交
https://github.com/yizhu2000/suproxy/issues

也可以通过邮件组suproxy@googlegroups.com,或直接发邮件到yizhu2000@hotmail.com进行沟通

当然SuProxy当前还在试验阶段,已经支持SSH2,LDAP,TNS,TDS协议,使用示例和文档将会陆续在博客园,****博客,Git上发布,欢迎大家测试,并提出意见与建议,

项目Git地址:
https://github.com/yizhu2000/suproxy

文档地址(英文):
https://github.com/yizhu2000/suproxy/blob/main/readme.md