7、Linux 埠轉發特徵總結

FLy_鵬程萬里發表於2018-06-10

Linux 下的埠轉發工具非常多,關於使用方法網上也是非常詳盡。因此在本文中,就不再贅述前人的研究成果,主要側重的是研究不同工具在做埠轉發時的特徵。

為了方便下面的討論,首先交代一下場景:有兩臺主機A(172.17.0.2)和B(172.17.0.3),其中A開放SSH服務(22埠)。現在,基於一些不可描述的原因,B無法直接與A的22埠建立TCP連線,這時B若想通過SSH連線A,必須通過埠轉發來實現。

既然是埠轉發,那麼一定需要一個“中介”,這個中介一方面要能將B的請求傳送給A,另一方面也能將A的響應發回給B,否則通訊就不能建立起來。這個中介可以是另一臺主機,也可以是A自身。下面我們逐個討論一下:


假設有一臺主機C(172.17.0.4),C可以連線A的22埠,B也可以和C建立連線,那麼B便可以將C作為跳板。具體操作如下:


通過socat

在C上執行:socat TCP-LISTEN:2222,fork TCP:172.17.0.2:22

此時C會監聽2222埠,並且將從2222埠上接收到的資料轉發給主機A的22埠。


檢視埠轉發時C的埠使用情況:




A的埠使用情況:



可以看出C其實用了兩個埠,一個埠用於監聽和接受來自B的請求,另一個埠用來和A建立連線。


通過ssh本地埠轉發

實際上,我們最經常使用的ssh客戶端也自帶埠轉發功能,使用方法如下:

在C上執行:ssh -gfNL 2222:localhost:22 root@172.17.0.2


實際上就是從C上SSH登陸A,只是比普通登陸多了幾個選項,執行後,C的埠使用情況:


可以看出ssh客戶端做了兩件事,一是與A上的sshd建立連線,而是開啟並監聽2222埠等待連線。B連線C的2222埠後,A上多了兩條連線:


可以看出,這種模式中資料的流向是上這樣的:B與C的2222埠建立連線,將資料發給C的ssh客戶端,C將資料加密後發給A的sshd伺服器,A的sshd伺服器將資料解密後,再通過一個TCP連線將資料送往目的地。


上面命令所用的幾個引數中,需要著重介紹“-L port:host:hostport”這個引數,其中第一個port比較好理解,就是ssh客戶端這面需要監聽的埠,而“host:hostport”這個有點讓人難以理解,為什麼是“localhost:22”呢?通過檢視ssh的幫助文件,發現這個埠實際是第二次轉發的目的埠,所以填“localhost:22”就表示最終要連線的是自己的22埠,如果要填“www.baidu.com:80” 則表示最終要連線是的www.baidu.com的80埠


通過ssh遠端埠轉發

上面兩種模式都是C主動連線A,但是若C無法主動連線A,而A可以主動連線C,則必須要用ssh遠端埠轉發:

在A上執行:ssh -gfNR 2222:localhost:22 root@172.17.0.4


即A通過SSH登入C,命令執行後,檢視C上埠監聽情況:


可見雖然已經成功建立轉發渠道,但是隻能接受來自本地的連線,要想讓C監聽所有介面,需要將C的sshd的“GatewayPort”選項設為“yes”。


同樣還是B連線C的2222埠,連線後A的埠使用情況為:


可以看出,遠端轉發和本地轉發的區別在於:遠端轉發是A要求C轉發,而本地轉發則是C主動轉發。


其他工具

除了上面說的幾種方法以外,還有許多工具可以做埠轉發,如iptables,rinetd,lcx等等,但是由於原理和特徵都基本上相同,這裡就不再討論了。

總結一下上面所說的埠轉發方式,從發起連線的主體來看可以分成本地轉發和遠端轉發(類似於正向代理和反向代理),從轉發的次數來看可以分為一次轉發和兩次轉發兩種。每種方法都有各自的特徵和適用場景。



上面所說的方法全都需要跳板機才能實現,實際上,如果A對B開放了一部分埠(如2222),那麼不經過其他主機也可以達到埠轉發的目的。工具和上面所說的一樣,僅僅是引數改變了一下而已。


通過socat

在主機A上執行:socat TCP-LISTEN:2222,fork TCP:localhost:22

B連線A的2222埠後,A上埠使用情況:



通過ssh本地轉發

在主機A上執行:ssh -gfNL 2222:localhost:22 root@localhost

B連線A的2222埠後,A上埠使用情況:


通過ssh本地轉發

在主機A上執行:ssh -gfNL 2222:localhost:22 root@localhost

B連線A的2222埠後,A上埠使用情況:


通過ssh遠端轉發

在主機A上執行:ssh -gfNR 2222:localhost:22 root@localhost,如果只能監聽環回介面,則也需要和上面一樣修改sshd配置


通過rinetd轉發

編輯/etc/rinetd

新增一行:0.0.0.0 2222 127.0.0.1 22

重啟rinetd


通過lcx轉發

lcx -m 1 -p1 2222 -h2 127.0.0.1 -p2 22


通過nc轉發

mkfifo /tmp/xx; (nc -lkp 2222) </tmp/xx | (nc localhost 22) >/tmp/xx 2>&1; rm –f /tmp/xx


比較一下使用跳板機和不使用跳板機兩種方式,可以發現兩種並沒有本質區別,後者其實是前者的特例。其實只要瞭解其中的原理,那麼自己實現一個埠轉發的工具也不是難事。 這篇文章重點關注的是在做埠轉發時的命令特徵和連線特徵。對於內網防護來說,研究埠轉發一方面是能知道黑客能用埠轉發做什麼,另一方面是能夠幫助網路管理員及時發現埠轉發行為,定位到問題主機。


參考資料:

  1.  http://lisux.me/lishuai/?p=439

  2. https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html

  3. https://my.oschina.net/sbcagf/blog/782952



通過ssh本地轉發

在主機A上執行:ssh -gfNL 2222:localhost:22 root@localhost

B連線A的2222埠後,A上埠使用情況:

通過ssh遠端轉發

在主機A上執行:ssh -gfNR 2222:localhost:22 root@localhost,如果只能監聽環回介面,則也需要和上面一樣修改sshd配置


通過rinetd轉發

編輯/etc/rinetd

新增一行:0.0.0.0 2222 127.0.0.1 22

重啟rinetd


通過lcx轉發

lcx -m 1 -p1 2222 -h2 127.0.0.1 -p2 22


通過nc轉發

mkfifo /tmp/xx; (nc -lkp 2222) </tmp/xx | (nc localhost 22) >/tmp/xx 2>&1; rm –f /tmp/xx


比較一下使用跳板機和不使用跳板機兩種方式,可以發現兩種並沒有本質區別,後者其實是前者的特例。其實只要瞭解其中的原理,那麼自己實現一個埠轉發的工具也不是難事。 這篇文章重點關注的是在做埠轉發時的命令特徵和連線特徵。對於內網防護來說,研究埠轉發一方面是能知道黑客能用埠轉發做什麼,另一方面是能夠幫助網路管理員及時發現埠轉發行為,定位到問題主機。


參考資料:

  1.  http://lisux.me/lishuai/?p=439

  2. https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html

  3. https://my.oschina.net/sbcagf/blog/782952


相關文章