我有一台机器 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 - 隧道并添加一个带有目标“动态”的转发端口。