Ssh

當文件在第三台伺服器而不是 SSH 伺服器上時,通過 SSH 進行 FTP(不是 SFTP?)

  • May 13, 2022

我有一台機器 A。從它,我可以通過 SSH 連接到機器 B。機器 B 可以通過 FTP 連接到機器 C。我想從 C 下載文件到 A。我無法直接從 A 訪問到 C。

                Port 20 and 21
┌───┐     ┌───┐  FTP Control    ┌─────────────────┐
│   │ SSH │   ├────────────────►│                 │
│ A ├────►│ B │                 │ C - with files  │
│   │     │   ├────────────────►│     I want      │
└───┘     └───┘  FTP data       │                 │
                Random ports   └─────────────────┘

我知道這個網站上有一百萬個關於 SFTP 的問題。據我所知,這與 SFTP 不同。使用 SFTP,SSH 伺服器似乎必須與要下載文件的伺服器相同,這不是問題所在。它是否正確?或者有什麼方法可以用一個簡單的 SFTP 命令和一些額外的參數來做到這一點?

有沒有簡單的方法可以做到這一點?文件很大,B 上的磁碟和記憶體很小,所以如果可能的話,我想直接流式傳輸數據。(與在 B 的磁碟上進行兩步 FTP 下載相比。)

一般來說,SSH 可以隧道任何東西。但顯然 FTP 使用的不僅僅是埠 20 和 21。它使用一大堆隨機且不可預測的埠,每個文件操作都有新的埠。此類 FTP 埠的可能範圍是如此之大,以至於我嘗試使用一個客戶端時,無法使用 SSH 埠轉發整個範圍。(請注意,我正在嘗試被動FTP,其中所有網路連接都是從客戶端啟動伺服器。與主動FTP 不同,其中 C 會啟動與 B 的連接,由於它們之間的 NAT,這是不可能的。)

我試圖用 python 編寫一個腳本,將FTP 標準庫和 3rd-party SSH 隧道庫結合在一起。這是一個非常複雜和笨拙的解決方案,導致我為每個新文件打開一個新埠,但從不關閉它。最近對一個庫的升級也破壞了一些依賴關係,因此現在該腳本不適用於這些庫的最新版本。我很想用底層的Paramiko庫重新編寫解決方案。但我擔心那是一個很深的兔子洞。這東西真的很花哨。(如果您需要查看我的嘗試,請告訴我。我試圖省略它以避免X/Y 問題。)

有沒有更簡單的方法來做這個隧道?

我更喜歡使用 Python 的解決方案,但在這一點上,我迫切需要使用任何工具。

“正常”解決方案是使用支持SOCKS 5的 FTP 客戶端,而不是通過 ssh 轉發特定埠,而是配置動態埠轉發(ssh 客戶端將充當 SOCKS 5 伺服器)

然後在主機 A 上:

ssh -D localhost:10108 user@host-B 

並將您的 FTP 客戶端配置為在該埠上使用 SOCKS5 代理,例如在 WinSCP https://winscp.net/eng/docs/ui_login_proxy或編輯ncftp配置文件 $HOME/.ncftp/firewall 或使用

curl --socks5-hostname localhost:10108 ftp://host-c/path/to/file

引用自:https://serverfault.com/questions/1100553