scp文件通过中间主机


76

我可以访问3台机器,A,B和C.唯一可能的(ssh)连接是:

A -> B
B <-> C

我需要从A到C获取文件,所以我可以将文件从A刻录到B,然后将它们从B刻录到C.但是,B没有太多的磁盘空间,所以这不是一个选项。有没有办法通过B scp文件从A到C?注意,我没有任何机器上的root访问权限,所以不要认为我可以设置任何持久性隧道,但如果我错了就纠正我!


4
我知道这不能回答这个问题,但对于那些不了解rsync,或者不知道如何使用它来跳过主机的人来说,这可能是一个有用的提示:使用'-e'选项与rsync这样:A$ rsync <options> -e 'ssh B ssh' source C:destination
Eddified

Answers:


99

ProxyJump

OpenSSH 7.3的新功能:

A$ scp -oProxyJump=B thefile C:destination

(在幕后,这只是使用ProxyCommand和ssh -W。)

ProxyCommand

更新为包含其他答案的-W:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

如果A安装了非常旧的SSH客户端(不-W支持),或者如果B配置为禁止TCP转发(但仍允许shell命令),请使用替代方法:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

管道

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

仅适用于一个文件:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

通过B“隧道”

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

当你完成后,不要忘记杀死之前启动的ssh进程(由于这已经落到了后台-f -N)。

  • -f请求ssh在命令执行之前转到后台。如果ssh要求密码或密码短语,但用户希望在后台使用密码或密码短语,这很有用。这意味着-n。
  • -N不要执行远程命令。这对于转发端口很有用。

将“隧道”反转到B到A.

虽然不总是有效:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R 指定将远程(服务器)主机上给定TCP端口或Unix套接字的连接转发到本地端的给定主机和端口或Unix套接字。

非常感谢@grawity这些例子。一个问题 - 是否可以反转`tar c thefile anotherfile | ssh B“ssh C \”cd destination && tar xv \“”'以便将下载从C复制到A(在A上)
dmeu 2015年

@dmeu:是的,这是可能的。
grawity 2015年

如果说我正在使用MacOS,如何“杀死”之前启动的ssh进程?
Aero Windwalker 2017年

注意:像往常一样,如果你想scp C,虽然 B, A,你可以做到A$ scp -oProxyJump=B C:destination thefile
jvriesem

@Pablo更好地使用-S,然后和-O退出。或者......至少是pkill -f。
grawity

23

2011年初及之后的scp版本可能有“-3”选项:

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

如果你有这个,你可以运行:

B$ scp -3 A:file C:file

在我的情况下,主机A只能从B(可以通过VPN)访问。主机C和B在同一个局域网上。我想从A到C获得一个文件,scp -3很好地解决了它。

当两个主机都请求密码时,我遇到了麻烦。它似乎同时要求两个(两个密码提示出现在同一行),然后它无法接受我的密码。我最终可以通过重复键入密码(两台主机上都有相同的密码)来实现它,但很难搞清楚。
Colin D

8

几乎所有人都已经说过了,但这是我的最后一分钱:我使用ProxyCommand变种而nc没有soc。基于OpenSSH Proxies和Jumphost Cookbook,我精心设计了以下配置:

  1. 所以我们有以下球员:

    • HOME_HOST:它是从我们将文件复制到目标主机的地方
    • HOP_HOST:我们通过这个主机复制(记录为HOP_USER)
    • TARGET_HOST:它是我们的目的地(经过TARGET_USER认证)
  2. 首先,我将本地公钥从我的主机添加.ssh/id_dsa.pub.ssh/authorized_keys了主机和目标主机。是的,从家庭主机到他们两个的相同公钥。通常你会期望它是你必须添加到TARGET的HOP公钥。

  3. 然后我.ssh/config通过添加以下条目稍微调整一下:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. 之后,复制操作就像:scp FILE TARGET_HOST:。它显示来自跃点和目标节点的双横幅,但它可以工作。

当然你可以使用上面的方法直接ssh到目标:ssh TARGET_HOST。它适用于scp和ssh。

另一个更通用的选项可能是sshuttle实用程序,它似乎是一种透明代理(vpn over ssh)。因此,在A-> B < - > C的情况下,它允许连接到C网络中的每个节点:A-> B- [CDEFG]。它不需要管理员,但它需要Python 2.7(3.5也可以),这并不总是我们拥有的。值得尝试一下。


7
ssh -L 4321:hostC:22 youruser@hostB

在另一个shell中:

scp -P 4321 localfile youruser@127.0.0.1

这是使用端口转发。这里唯一的限制是主机B需要配置为允许端口转发。否则这应该工作正常。

在解释的方式,-L-R允许您转发端口。在-L,给出的第一个端口是端口ssh将开始侦听始发机器(主机A),它将通过SSH连接将它在该端口上接收的任何内容转发给主机B,然后在端口22上路由到主机C.

编辑

我略微搞砸了语法。它在您的LOCAL机器上设置了一个前进。


@astrofrog - 如果我们的一个答案满足您的需求,您应该接受其中一个。
Brian Vandenberg

1

Grawity的ProxyCommand答案对我有用,但由于我不太熟悉SSH,所以需要进行一些实验。我想我会更详细地说明Grawity的答案,以帮助像我这样的任何其他新手。以下是更明确的表示法的定义:

机器A:您所在的机器

服务器B: userB@ip.address.for.B(跳转主机或中间服务器)

服务器C: userC@ip.address.for.C(要复制到的远程服务器)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p userB@ip.address.for.B" thefile userC@ip.address.for.C:destination

具体例子

因此,对于一个具体示例,假设您可以访问0.0.1.2具有名为bar(服务器C)的用户帐户的IP 服务器。但要实现它,您必须首先0.0.1.1使用名为foo(服务器B)的用户帐户登录到具有IP的服务器。现在,您要将baz.txt位于当前计算机(计算机A)上的文件复制到服务器0.0.1.2/home/bar/目录中。要在此示例中使用上述ProxyCommand,您将执行以下操作:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" baz.txt bar@0.0.1.2:/home/bar/

您也可以通过切换文件和目标的顺序轻松地从服务器C复制文件。因此,例如,如果baz.txt已经位于服务器上0.0.1.2/home/bar/那么您可以使用以下方法将其复制到您的计算机:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" bar@0.0.1.2:/home/bar/baz.txt /destination/path/on/A

希望这能帮助那些需要为他们拼出的东西的人比其他人更多。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.