題 通過中間計算機轉發SSH流量


SSH隧道對我來說非常困惑。我想知道我是否可以在Linux中這樣做。

我有3台機器..

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

所以我可以從A - > B和B - > C進行SSH,但不是來自A - > C.

有沒有辦法從A到B設置SSH隧道,所以當我運行其他SSH命令時,它們只能在我的本地機器A上工作?我基本上試圖克隆從工作到家的git repo(我不能在機器B上安裝git)。

此外,一旦設置..我怎麼會取消它?


102
2018-02-11 03:58


起源


我相信在某個地方有一個重複的問題,但我今天的搜索功能很弱。 - quack quixote
那將是我的: superuser.com/questions/96489/ssh-tunnel-via-multiple-hops - Mala


答案:


把它放在你的 .ssh/config hostA上的文件(參見 男人5 ssh_config 詳情):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

現在,以下命令將自動通過hostB進行隧道傳輸

hostA:~$ ssh hostC

您可能希望添加類似的選項 -oCiphers=arcfour 和 -oClearAllForwardings=yes 包裝起來,加快速度 ssh 內 ssh 計算上更昂貴,額外的工作和包裝器在隧道已經加密的流量時不需要那麼安全。


如果您使用的是早於5.3的OpenSSH,那麼 -W 選項不可用。在這種情況下,您可以使用netcat實現上述(nc):

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB

119
2018-02-11 04:11



這太棒了!謝謝。這解決了過去兩天一直困擾著我的問題:hostC位於防火牆後面並且擁有我想從hostA訪問的數據,這是一台可以在世界任何地方使用的筆記本電腦。 hostB也在與hostC相同的防火牆後面,但它有一個向世界開放的SSH端口。因此我可以從hostC - > hostB ssh。我在hostC和hostB之間設置了一個反向SSH隧道,所以我也可以從hostB - > hostC ssh(通過localhost轉發)。有了你的技巧,我可以從hostA - > hostC!它與OSX上的SCP和Fugu無縫協作!謝謝! - AndyL
該 -W 應該使用選項而不是 nc 選項。 - vy32
哪個SSH應該支持 -W,只有hostA(原點)上的那個或者hostB(中間機器)上的那個? - gioele
有關信息,如果您有多個主機,則需要通過相同的方式訪問 hostB,可以聲明多個 Host hostC 上面的線 ProxyCommand 通過中間服務器訪問多個主機非常容易。 - fduff


編輯:這是錯誤的方法。看到 ephemient的答案 代替。這個答案可行,但可能不太安全,絕對不那麼棒。

聽起來你想要一個如下的解決方案:

ssh -L localhost:22:machinec:22 machineb

這將為你提供一個shell machineb。別這個;最小化終端窗口。

現在,無論何時進行ssh連接 localhost,你將實際連接到 machinec 通過 machineb。完成隧道後,只需關閉運行上述命令的終端即可。

請注意,您需要超級用戶權限才能運行該命令。


6
2018-02-11 04:11



+1謝謝韋斯利。這是真正的ssh隧道答案。這是一篇關於它的文章: securityfocus.com/infocus/1816 - Larry K
總的來說,這是非常邪惡的...但我必須使用古老版本的OpenSSH或其他ssh客戶端來做到這一點。您可以選擇一些像8022這樣的高端口:這樣它不會干擾localhost上的任何ssh服務,也不需要以root身份運行。只需添加 -p 8022 你的ssh命令。使用git可以很容易地使用它:使用URI ssh://localhost:8022/path/to/repo.git。 - ephemient


聽起來你想在A上使用shell別名導致ssh在C上發生

  1. 我假設在A上,你可以輸入ssh me @ b“ssh me @ c hostname”並返回“C”
  2. 創建一個別名sshc,將sshc foo擴展為ssh me @ b“ssh me @ c foo”
  3. 有關創建別名的確切語法,請諮詢superuser.com

3
2018-02-11 04:04



您可能需要添加 -t 如果你想要一個交互式shell,那麼到外部ssh的選項,因為 ssh 假設 -T 如果它給了一個命令。 - ephemient


如果您的雇主提供VPN,我建議您使用它。

這樣,您就不必專門配置任何應用程序(甚至是ssh),並且您可以看到防火牆後面的任何機器。此外,您的所有流量都將由VPN軟件加密,這將為任何無意或故意未加密的流量增加安全性。


0
2018-02-11 20:14



有時它的VPN就是我們需要這些技巧的原因...... - Louis


YASS又一個簡單的解決方案

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • 第一個命令打開一個ssh連接 主機B 並告訴 主機B 從...轉發連接 本地主機:2222 至 HostC:22
  • -f 一旦建立連接,參數告訴SSH轉到後台
  • 第二個命令只打開一個客戶端連接 本地主機:2222
  • 選項 HostKeyAlias 不是必需的,但可以幫助防止連接到錯誤的主機
  • Nota:命令 sleep 10 需要保持連接,直到第二個ssh命令使用轉發端口。然後先 SSH 第二次關閉 SSH 離開轉發港口。

你現在可以運行後續的ssh會話:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

變體:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

後續的ssh會話可以通過運行來打開:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

使用-M和-S param的主要優點是只有一個連接從HostA打開到HostC,後續會話不會再次進行身份驗證並且運行得更快。


0
2017-11-10 15:35