当文件位于第三台服务器而非 SSH 服务器上时,通过 SSH 进行 FTP(不是 SFTP?)

当文件位于第三台服务器而非 SSH 服务器上时,通过 SSH 进行 FTP(不是 SFTP?)

我有一台机器 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 标准库以及第三方SSH 隧道库。这是一个相当复杂和不稳定的解决方案,导致我为每个新文件打开一个新端口,但从不关闭它。此外,最近对一个库的升级破坏了一些依赖关系,因此现在脚本无法与这些库的最新版本一起使用。我很想用底层重写解决方案波拉米科图书馆。但我担心那是一个很深的兔子洞。这东西真的很麻烦。(如果你需要看我的尝试,请告诉我。我试图省略它以避免X/Y 问题

有没有更简单的方法来实现这种隧道传输?

我更喜欢使用 Python 的解决方案,但目前我已经迫切希望使用任何工具。

答案1

对此的“常规”解决方案是使用具有袜子 5支持,而不是通过 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

答案2

您可以使用 SSH 作为 SOCKS 代理。A 上的 SSH 客户端将充当 SOCKS5 服务器,将所有连接请求通过隧道传输到 B。您需要在 A 上安装一个 SOCKSified FTP 客户端。

如何激活 SOCKS 代理功能取决于 A 上使用的 SSH 客户端。在文档中查找“动态端口转发”。对于标准 OpenSSH 客户端,请指定选项-D 1080以使其在标准 SOCKS5 端口上侦听。对于 PuTTY,请转到配置对话框中的连接 - SSH - 隧道并添加一个带有目标“动态”的转发端口。

相关内容