想用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代理一切?行文章插图
记录SQL或shell命令
想用Nginx代理一切?行文章插图
想用Nginx代理一切?行文章插图
防止删库跑路(命令过滤和禁止)
想用Nginx代理一切?行文章插图
想用Nginx代理一切?行文章插图
踢人下线
想用Nginx代理一切?行文章插图
怎么做到的上面的示例是怎么做到的?不要着急 , 我们的主人公就要出场了:SuProxy , 一个纯Lua , 事件驱动模型 , 基于包分析的开源代理库 。
纯LUA意味着拷贝可用 , 事件驱动意味着使用方便 , 包分析意味着可以真正自由修改包内容 。
我们来看看怎么修改linux的欢迎屏幕
local function myWelcome(context,source) local digger={"\r\n", [[.-.]].."\r\n", [[/\]].."\r\n", [[_____.....-----|(o) | ]].."\r\n", [[_..--'_..--|.'' ]].."\r\n", [[.'o_..--''|| | ]].."\r\n", [[/_/_..--''|| | ]].."\r\n", [[________// /|| | ]].."\r\n", [[| _____\ / /|| | ]].."\r\n", [[ _.-----._________|| ||\\ /|| | ]].."\r\n", [[|=================||=||_____\\|__|-' ]].."\r\n", [[|suproxy||_||_____//(o\ |]].."\r\n", [[|_________________|_________/|-\|]].."\r\n", [[ `-------------._______.----'/`. ]].."\r\n", [[.,.,.,.,.,.,.,.,.,.,.,.,.,/\]].."\r\n", [[((O) o o o o ======= o o(O))._.'/]].."\r\n", [[`-.,.,.,.,.,.,.,.,.,.,.,-'`.......' ]].."\r\n", [[scan me to login]].."\r\n", "\r\n", }return table.concat(digger),falseendlocal 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事件 , 在事件中修改了默认的欢迎屏幕 。
【想用Nginx代理一切?行】每个协议都有自己独特的事件 , 比如利用TNSProcessor.commandEntered事件 , 我们就能过滤用户输入的命令 , 使用OnAuthenticate事件就能够自行处理验证 。 事件的使用可参见或英文文档
还想更进一步除了上面这些直观的事件 , 在底层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代理一切?行文章插图
如果觉得本文对你有帮助 , 可以转发关注支持一下
原文链接: