2014年8月19日 星期二

超酷的逆向代理(reverse proxy):使用bash one liner

參考 http://www.frameloss.org/2013/12/14/wicked-cool-reverse-proxy-with-bash-and-netcat/

Process substitution 是裏面最重要的概念,使得 pipe 可以同時雙向轉送。

File descriptors 也是滿新鮮的概念。檔案和 socket 因此可視為等效,使得 nc/netcat 的功能實質上可以用 cat 來達成。

或許很多程式一開始只要寫成針對 stdio / stdout 就好,再利用這些上述提到的概念,在 shell 的層次導入 socket / network 的參數。

這個小技巧可以 work ,首先要思考的是 proxy 和 nc 的本質。 proxy 本身同時是 server 和 client ,server端接受外來的連線,再利用 client 端將資料轉送到真實的 server 。nc 依執行時所提供的參數,可以是 client ,也可以是 server ,而資料則轉送到該程式自身的 stdin / stdout 。所以在實質上來看,同時啟動一個 nc server 和 nc client ,然後把它們的 stdin / stdout 串起來,就可以等效於一個 proxy。

延伸--bidirectional filter


理想上一個雙向 bidirectional filter 可以插入到這兩個 nc server/client 之間,但是 bash 的版本可能要在4以上 (2010年3月以後)。先檢查版本:

$ echo $BASH_VERSION

利用 mkfifo 建立 4 個具名管道 a b c d,使用<及>運算子將 a output b input 指定給 nc server 的 io ,c output d input 指定給 nc client ,然後將 a input b output c input d output 作為參數啟動 filter 。自行建立的 fileter 如果是用 perl 撰寫,可參考文件如何使用open打開管道。

如果讀寫之間不需要協調的話,那麼這樣形式的 filter 是更為簡單的,讀、寫各兩個管道,所以不需要使用具名管道。指令的形式如下

[ ! -p $pipefwd ] && mkfifo pipeback;#只需要執行一次

[ ! -p $pipefwd ] && mkfifo pipeback;nc -l -p 9090 <pipeback | perl -e "while(<>){print STDERR;}" | nc 127.0.0.2 9999 | perl -e "while(<>){print STDERR;}" > pipeback

如果需要在螢幕上顯示,可以搭配 tee

[ ! -p $pipefwd ] && mkfifo pipeback;nc -l -p 9090 <pipeback | tee >(perl -e "while(<>){print STDERR;}") | nc 127.0.0.2 9999 | tee >(perl -e "while(<>){print STDERR;}") > pipeback

20170202更新:嚴格說來 ssh 才是比較安全的作法,請參考 http://chimerhapsody.blogspot.tw/2015/09/ssh.html
http://chimerhapsody.blogspot.tw/2015/09/ssh.html

沒有留言:

張貼留言