Ssh-Tunneling

通過跳轉主機、ssh_config 文件和僅“ssh targethost”進行 SSH 埠轉發

  • March 31, 2018

注意:我使用的 OpenSSH 客戶端都是7.2 版本,所以不可RemoteCommand用。

假設以下設置:

  1. machine是一個跳轉主機,並通過其foo提供對主機的訪問bar``localhost:10022
  2. bar位於網路內部,我們可以在其中訪問主機rdp並訪問其 RDP 埠(3389)。我實際上給出了我的命令行和配置內部的 IP rdp,但我認為只要名稱查找有效,使用它的名稱是合法的。為簡潔起見,我在rdp這裡使用。

rdp:3389現在的目標是通過連接到bar通過跳轉主機獲得訪問權限,foo並將其轉發到localhost:33389我正在呼叫的本地機器上ssh bar

[local:33389] --> {foo} --> {bar} --> [rdp:3389]

插曲

我以前用 PuTTY 解決了這個問題,如下所示:

  1. 創建連接foo並配置本地轉發-L 33389:localhost:33389,從而將本地機器綁定localhost:33389localhost:33389on foo
  2. 使用以下遠端命令將埠轉發傳送到其所在的網路barssh -L 33389:rdp:3389 -A bar
  3. Host bar foo內部配置.ssh/config為連接到localhost:10022並最終bar通過跳轉主機。

PuTTY 配置就像一個魅力,但它依賴於遠端命令來執行。雖然 shell 別名是解決此問題的一種方法,但我想知道是否有辦法將所有內容保存在ssh_config(5)我的客戶使用的內部,使用ProxyCommand?


上述 PuTTY 配置的大致等價物是:

ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 -p 10022 localhost

或者,只要Host bar配置為foo通過:localhost:10022``foo

ssh -L 33389:localhost:33389 foo ssh -t -L 33389:rdp:3389 bar

這似乎完成了工作。

但是當然,這很容易輸入,如果能夠將所有這些放入配置文件並ssh bar在本地機器上簡單地輸入,那就更簡潔了。

正如 OpenSSH 7.6 中介紹的那樣, RemoteCommand這似乎相當簡單:

Host bar
   HostName foo
   RemoteCommand ssh -L 33389:rdp:3389 -A -p 10022 localhost
   LocalForward 33389 localhost:33389

…這應該大致轉換為ssh上面顯示的呼叫。但如前所述,我使用的是 OpenSSH 的舊(打包)版本,不支持該RemoteCommand節。

這是似乎最接近我想要實現的嘗試。

Host bar
   HostName localhost
   Port 10022
   ProxyCommand ssh -L 33389:localhost:33389 -W %h:%p foo
   LocalForward 33389 rdp:3389

這個想法是在本地機器上我將簡單地呼叫ssh bar. 事實上,它的工作原理是我最終出現在 的 shell 提示符下bar,但埠轉髮根本不起作用。雖然sudo lsof -i|grep 3389在本地機器上給了我:

ssh       15271        accden    6u  IPv6 7933201      0t0  TCP localhost:33389 (LISTEN)
ssh       15271        accden    7u  IPv4 7933202      0t0  TCP localhost:33389 (LISTEN)

在跳轉主機上,我看不到任何包含3389.

由於ProxyCommand建立了與 的連接,foo並且我提供了LocalForward與 的連接bar,因此我希望這可以正常工作。

我究竟做錯了什麼?


目標是用於ssh bar連接bar並同時rdp:3389在本地機器上作為localhost:33389. 調整ssh_config(5)本地機器上的文件並被foo允許。但是,傳遞遠端命令不是一個有效的答案。

首先,根據您的設置,什麼起作用,無論如何都需要兩個 ssh:

Host foo
   LocalForward 10022:bar:22

Host bar
   Hostname localhost
   Port 10022
   LocalForward 33389 rdp:3389

term1$ ssh foo # or use ssh -f -N -o ExitOnForwardFailure=yes foo for background task
term2$ ssh bar

您真正需要的不是 RemoteCommand,而是 ProxyJump,真正簡化了您的配置,只有通過以下方式才能達到目標:

ssh -L 33389:rdp:3389 -J foo bar

或等效(僅)配置:

Host bar
   ProxyJump foo
   LocalForward 33389 rdp:3389

需要零中間埠。

不幸的是,ProxyJump 僅從 openssh 7.3 開始可用

但它很容易被ProxyCommand``-W您之前使用的/組合替換。

ssh -L 33389:rdp:3389 -o 'ProxyCommand=ssh foo -W %h:%p' bar 

或作為配置文件:

Host bar
   ProxyCommand ssh -W %h:%p foo
   LocalForward 33389 rdp:3389

仍然有兩個 ssh 正在執行:隱藏的一個是ProxyCommand仍在本地主機上執行的 as 參數,它使用一對帶有主 ssh 的管道進行連結,而不是額外的 tcp 埠。試圖讓中間主機參與埠轉發是不安全的或可能發生衝突(foo 的其他使用者可以訪問隧道或使用相同的埠),並且容易出錯。如果可能,隧道末端應始終保留在客戶端主機上,在那裡可以完全控制。中間隧道不應該存在或指向下一個 ssh 入口點(這就是-W’s 在這裡的用法)。

引用自:https://unix.stackexchange.com/questions/433923