美文网首页Java学习笔记Java 杂谈Spring-Boot
Nginx能代理一切吗?恕我直言还真可以!

Nginx能代理一切吗?恕我直言还真可以!

作者: 并发量就是我的发量 | 来源:发表于2020-10-29 15:00 被阅读0次

    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),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事件就能够自行处理验证。

    还想更进一步

    除了上面这些直观的事件,在底层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能代理一切吗?恕我直言还真可以!

        本文链接:https://www.haomeiwen.com/subject/lkgkvktx.html