如何scp与第二个远程主机

时间:2012-02-04 08:06:38

标签: scp

我想知道是否有办法让我通过remote1主机直接从我的本地机器发送来自remote2主机的文件。

网络仅允许从remote1主机连接到remote2主机。此外,remote1主机和remote2主机都不能scp到我的本地计算机。

是否有类似的东西:

scp user1@remote1:user2@remote2:file .

第一个窗口:ssh remote1,然后是scp remot2:file .

第二个shell:scp remote1:file .

第一个窗口:rm file; logout

我可以编写一个脚本来执行所有这些步骤,但如果有直接的方式,我宁愿使用它。

感谢。

编辑:我在想像打开SSH隧道这样的东西,但我对于放在哪里有什么价值感到困惑。

目前,要访问remote1,我的本地计算机上的$HOME/.ssh/config中有以下内容。

Host remote1
   User     user1
   Hostname localhost
   Port     45678

访问remote1后,要访问remote2,它就是标准的本地DNS和端口22.我应该将remote1和/或localhost上的内容更改为什么?< / p>

7 个答案:

答案 0 :(得分:87)

我不知道有什么方法可以直接在一个命令中复制文件,但是如果您可以承认在后台运行SSH实例只是保持端口转发隧道打开,那么您可以复制该文件一个命令。

像这样:

# First, open the tunnel
ssh -L 1234:remote2:22 -p 45678 user1@remote1
# Then, use the tunnel to copy the file directly from remote2
scp -P 1234 user2@localhost:file .

请注意,您在实际user2@localhost命令中以scp连接,因为它位于localhost上的端口1234上,第一个ssh实例正在侦听到{{1}的前向连接}。另请注意,您不需要为每个后续文件副本运行第一个命令;你可以简单地让它继续运行。

答案 1 :(得分:64)

加倍ssh

即使在复杂的情况下,您也可以使用一个命令行处理文件传输,只需使用ssh ;-)
如果remote1无法连接到localhost

,这非常有用
ssh user1@remote1 'ssh user2@remote2 "cat file"' > file

tar

但是你丢失了文件属性(所有权,权限......)。

但是,tar是您保留这些文件属性的朋友:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar c file"' | tar x

您还可以进行压缩以减少网络带宽:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj file"' | tar xj

tar还允许您通过基本ssh转移递归目录:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj ."' | tar xj

ionice

如果文件很大并且您不想打扰其他重要的网络应用程序,则可能会错过scprsync工具提供的网络吞吐量限制(例如{ {1}}使用的速度不超过1 Mbits /秒。

但是,解决方法是使用ionice来保留单个命令行:

scp -l 1024 user@remote:file

注意:旧版本可能无法使用ionice -c2 -n7 ssh u1@remote1 'ionice -c2 -n7 ssh u2@remote2 "cat file"' > file

答案 2 :(得分:29)

这样可以解决问题:

scp -o 'Host remote2' -o 'ProxyCommand ssh user@remote1 nc %h %p' user@remote2:path/to/file .

直接从主机remote2向SCP发送文件,将两个选项(HostProxyCommand)添加到〜/ .ssh / config文件中(另请参阅{{3}回答超级用户)。然后你可以运行:

scp user@remote2:path/to/file .

来自本地计算机,无需考虑remote1

答案 3 :(得分:5)

使用openssh版 7.3 以上它很容易。在配置文件中使用 ProxyJump 选项。

# Add to ~/.ssh/config 
Host bastion
    Hostname bastion.client.com
    User userForBastion
    IdentityFile ~/.ssh/bastion.pem

Host appMachine
    Hostname appMachine.internal.com
    User bastion
    ProxyJump bastion                   # openssh 7.3 version new feature ProxyJump
    IdentityFile ~/.ssh/appMachine.pem. #no need to copy pem file to bastion host  

要运行以登录或复制的命令

ssh appMachine   # no need to specify any tunnel. 
scp helloWorld.txt appMachine:.   # copy without intermediate jumphost/bastion host copy.** 

当然,如果未在配置文件中配置,您可以使用选项“-J”指定堡垒跳转主机到ssh命令。

注意 scp 似乎支持“-J”标志。 (我在手册页中找不到。但是scp以上配置文件设置)

答案 4 :(得分:1)

scp中有一个新选项,最近为完全相同的工作添加了一个非常方便的选项,-3

TL; DR 对于已在ssh配置文件中设置了身份验证的当前主机,只需执行以下操作:

scp -3 remote1:file remote2:file

您的scp必须来自最新版本。

上述所有其他技术都要求您设置从remote1到remote2的身份验证,反之亦然,这并不总是一个好主意。
参数-3表示您希望通过使用当前主机作为中介从两个远程主机移动文件,并且该主机实际上对两个远程主机都进行了身份验证,因此它们不必彼此访问。
您只需要在ssh配置文件中设置身份验证即可,这很容易且有据可查,然后只需在TL; DR

中运行命令即可。

此答案的来源是https://superuser.com/a/686527/713762

答案 5 :(得分:0)

此配置对我来说很好:

Host jump
   User username
   Hostname jumphost.yourorg.intranet
Host production
   User username
   Hostname production.yourorg.intranet
   ProxyCommand ssh -q -W %h:%p jump

然后输入命令

scp myfile production:~

myfile 复制到生产计算机。

答案 6 :(得分:0)

我在Olibre的源代码中为this的解决方案添加了少量内容。

就像您有三种使用tar从远程主机复制到本地的方法一样,以下在双ssh情况下适用于本地主机到远程主机的复制:(在中运行它们 >必须从中复制文件的目录,否则使用fullpath / filename)

不压缩即可传输单个文件:

tar c filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar x"'

以压缩方式传输单个文件:

tar cj filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

递归目录传输:

tar cj . |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

如果命令的前半部分不起作用,例如,如果目录丢失或源/目标路径名错误,则&&此处将阻止命令运行。