Ssh

通過遠端埠轉發通過 jumphost 進行 SSH 會話

  • March 27, 2018

我們在通過遠端埠轉發進行 SSH 連接時遇到問題。

該場景是一個企業網路,內部網路上的伺服器(我們稱之為“源”)必須通過 SSH 登錄到 DMZ(“目標”)中的伺服器。由於 DMZ 中的目標伺服器被內部網路的連接鎖定(甚至無法從內部網路看到),因此我們在 DMZ 中有一個跳轉主機(“jumphost”)。我們通過在 jumphost 上設置遠端埠轉發來做到這一點。

我們從內部網路上的源伺服器執行這個命令,到 jumphost:

origin> ssh -R *:1234:target:22 myusername@jumphost

這是為了在 jumphost 上建立 SSH 會話,使其開始偵聽埠 1234(只是一個範例任意埠號),並將該埠上的連接轉發到目標伺服器埠 22 (SSH)。

然後我們在埠 1234 上建立第二個 SSH 會話,仍然是從源伺服器到 jumphost,然後實際上連接到埠 22 上的目標伺服器 - 這是我們的“真實”SSH 會話,我們可以在其中完成我們的工作目標伺服器:

origin> ssh jumphost -P 1234

配置

跳轉主機已配置為允許遠端埠轉發,在 sshd_config 中有以下設置:

AllowTcpForwarding yes
GatewayPorts yes

此外,在源伺服器和跳轉主機之間有防火牆開口,用於埠 22(用於設置遠端埠轉發的初始 SSH 連接)和埠 1234(用於轉發埠上的後續 SSH 連接)。jumphost和target之間也有防火牆,已經在22埠開放。

結果

當我們建立第二個連接(通過轉發埠的連接)時,連接立即關閉(‘連接被遠端主機關閉’)。

在目標伺服器上執行 tcpdump 沒有顯示任何活動,即似乎連接被阻塞。

但是,我們能夠成功地建立從跳轉主機到目標的正常 SSH 會話。只有通過轉發埠進入時,連接才會關閉,儘管兩者都連接到埠 22 上的目標。

更重要的是,如果我們將埠轉發點指向內部網路上的伺服器(即從內部網路上的源連接到 DMZ 中的跳轉主機,然後返回到內部網路上的第三台伺服器),那麼 SSH會話建立成功。

猜測和問題

所有這一切讓我相信某些網路安全設置正在發揮作用,它阻止通過跳轉伺服器上的轉發埠連接到 DMZ 內的目標伺服器。不幸的是,我沒有足夠的知識知道:

(1) 來自源伺服器的 SSH 連接是否通過跳轉伺服器上的轉發埠“不同”,從網路安全策略的角度來看,它可以在技術上被阻止,如果是,如何?需要做些什麼來解除這種限制?

(2) 不允許通過此連接的任何其他原因 - 防火牆配置、路由器配置、源站或 jumphost 上的 SSH 設置,還有其他什麼?

(3) 它會不會因為源伺服器不知道目標伺服器而失敗,因此第一個 ssh 命令不能按預期工作?換句話說,第一個 ssh 命令(“target”)中指定的主機名是在客戶端(源)還是在我們連接到的伺服器(jumphost)上解釋的?

最讓我難過的是可以從跳轉主機到目標建立正常 SSH 會話,我認為通過轉發埠進入的 SSH 連接是相同的,但不知何故不是。

非常感謝任何輸入。

看起來您應該使用本地埠轉發而不是遠端埠轉發。您可能需要參考 Dirk Loss 的以下有用部落格文章:

它包括以下說明圖:

ssh 埠轉發:本地與遠端

為了閱讀該圖,您需要知道它描述了創建和使用 SSH 隧道所涉及的 4 個不同角色之間的關係:

  • 用於建立隧道的 ssh 客戶端(即sshOpenSSH 命令行客戶端);
  • sshd用於維護隧道另一端的ssh 伺服器(即OpenSSH 伺服器守護程序);
  • 應用伺服器(例如,另一個 ssh 伺服器或 http 伺服器);
  • 想要通過隧道訪問應用程序伺服器的應用程序客戶端(例如,另一個 ssh 客戶端或 Web 瀏覽器)。

了解兩種不同類型的轉發對應於兩種不同的案例也很重要:

  • 本地轉發:應用程序客戶端通過 ssh 客戶端連接的位置
  • 遠端轉發:應用程序客戶端通過 ssh 伺服器連接

之所以稱為遠端轉發,是因為轉發是在遠端(在 ssh 伺服器)而不是在本地(在 ssh 客戶端)執行的。我還發現“遠端轉發 = 反向轉發”是一個有用的助記詞。

如您所見,為了從主機上的ssh客戶端通過代理伺服器上的伺服器啟動到第三台主機的連接,您必須使用本地埠轉發。遠端埠轉發適用於您希望隧道的入口點位於執行伺服器的主機而不是執行客戶端的主機的情況。origin``sshd``jumphost``target``sshd``ssh

在手冊頁中,本地埠轉發語法如下所示:

ssh -L [bind_address:]port:host:hostport user@remote

這可以更直覺地寫成如下:

ssh -L [local_bind_address:]local_port:remote_host:remote_host_port user@proxy_host

或者,使用您的命名約定:

ssh -L [origin_bind_address:]origin_port:target_host:target_host_port user@jump_host

如果我們修改您的命令以使用本地埠轉發,那麼我們最終會得到以下結果:

user@origin:~$ ssh -L *:1234:target:22 myusername@jumphost

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