想用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歡迎螢幕為所有男人的夢想
記錄SQL或shell命令
防止刪庫跑路(命令過濾和禁止)
踢人下線
怎麼做到的
上面的示例是怎麼做到的?不要著急,我們的主人公就要出場了: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事件就能夠自行處理驗證。事件的使用可參見//www.cnblogs.com/yizhu2000/p/13885263.html或英文文檔//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可以擴展協議中某類特定包的解析
三個層次都會發出事件。具體可見下圖
歡迎拍磚
看了上面的介紹,感興趣的同學有問題可以在此留言,或直接在git上提交
//github.com/yizhu2000/suproxy/issues
也可以通過郵件組[email protected],或直接發郵件到[email protected]進行溝通
當然SuProxy當前還在試驗階段,已經支援SSH2,LDAP,TNS,TDS協議,使用示例和文檔將會陸續在部落格園,CSDN部落格,Git上發布,歡迎大家測試,並提出意見與建議,
項目Git地址:
//github.com/yizhu2000/suproxy
文檔地址(英文):
//github.com/yizhu2000/suproxy/blob/main/readme.md