![通过中间件在主机之间传输 scp 文件](https://linux22.com/image/1407102/%E9%80%9A%E8%BF%87%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%9C%A8%E4%B8%BB%E6%9C%BA%E4%B9%8B%E9%97%B4%E4%BC%A0%E8%BE%93%20scp%20%E6%96%87%E4%BB%B6.png)
我可以访问 3 台机器,A、B 和 C。唯一可能的 (ssh) 连接是:
A -> B
A -> C
我需要将文件从 B 传输到 C,我只能将文件从 A scp 传输到 B(在 A 上:scp 远程本地),然后从 A scp 传输到 C(在 A 上:scp 本地远程)。但是,A 没有足够的磁盘空间来存储一些相当大的文件。B 和 C 之间有防火墙,还有从 B -> A 和 C -> A 的反向路径。我无法在 B 或 C 上放置密钥,以便从 A 连接到 B 和 C。(说来话长,这是另一个问题)
有没有办法通过将 A 和 B 之间的 scp 输出直接传输到从 A 到 C 的 scp 中来将 B 上的文件 scp 到 C?这样实际文件就不会存储在本地?
查看详细输出,-3 选项似乎向远程主机 B 发送一个远程 scp 命令,由于中间防火墙阻止连接而失败。
答案1
您可以为此使用反向 SSH 隧道:
在主机 A 上,运行:
ssh -R 3000:ip.of.host.c:22 ip.of.host.b
在主机 B 上,运行
scp -P 3000 /source/file username@localhost:/destination_file
这将创建一个隧道,监听主机 B,并通过主机 A 转发到主机 C。因此,您可以在主机 B 上使用 localhost:3000 来连接到 hostc:22。
答案2
您可以使用以下版本tar-ssh-tar 技术执行此操作。从服务器 A 运行以下命令:
ssh B 'cd /src && tar cf - file1 file2...' | ssh C 'cd /target && tar xvf -'
这会在 B 上创建一个包含文件的 tar 格式数据流,然后通过 SSH 将其传输回 A,再通过 SSH 传输到 C,最后传输到 C 上的 tar 程序,该程序会解压文件。A 上无需存储任何文件。
您应该为 B 和 C 设置 SSH 密钥,这样就不会提示您输入密码。两次ssh
同时提示输入密码会造成混淆。
如果这是长距离传输,您可以尝试压缩 tar 流以加快速度:
ssh B 'cd /src && tar zcf - file1 file2...' | ssh C 'cd /target && tar zxvf -'
答案3
我认为最简单的解决办法是命名管道在 PC A 上,命名管道是一个行为类似于标准管道的文件,IE它会在内容可用时立即传递内容,而不存储任何内容本身. 它是在 *Nix 系统上实现 IPC(进程间通信)的标准方式。
mkfifo my-pipe
创建名为我的管道唯一的问题是你不能SCP命名管道(操作系统会抱怨 my-pipe 不是常规文件)。因此,操作方式如下:在 pcA 上的一个终端中,发出以下命令:
cat my-pipe | ssh me@pcC 'cat > /path/to/destination/file'
此命令将命名管道的内容传输到 pcC,然后重定向到目标文件。
在另一个终端中,再次在 pcA 上发出:
ssh me@pcB 'cat /path/of/source/file' > my-pipe
此命令将位于远程 pcB 上的源文件放到标准输出,并将其重定向到命名管道。
一旦材料进来,命名管道就会被清空。来自 pcB 的文件结束符会关闭到 B 的两个连接和到 C。A 上没有存储任何内容。此时,您可以移除管道,
rm my-pipe.
我觉得这很简单。
答案4
如果您经常这样做,我建议在服务器 A 上的 ssh 配置文件中添加一个代理命令,如下所示~/.ssh/config
:
host serverB
User <user on B>
HostName <hostname of B>
host serverC
User <user on C>
ProxyCommand ssh -q serverB nc -q0 <C hostname> 22
-q 代表安静模式,即较少的输出。
现在,当您想要将文件从机器 A 复制到机器 C 时,您只需输入scp file1 file2 .. serverC:/some/path
You can do this on server C as well if you want to do it back to. 如果您在不同的机器上有不同的用户名,这将特别有用,当然,如果您不想每次都输入密码,它也可以与 ssh-copy-id 结合使用。